예제 #1
0
 /**
  * A set-OCG-state action (PDF 1.5) sets the state of one or more optional content groups.
  *
  * @param state an array consisting of any number of sequences beginning with a <CODE>PdfName
  *     </CODE> or <CODE>String</CODE> (ON, OFF, or Toggle) followed by one or more optional
  *     content group dictionaries <CODE>PdfLayer</CODE> or a <CODE>PdfIndirectReference</CODE> to
  *     a <CODE>PdfLayer</CODE>.<br>
  *     The array elements are processed from left to right; each name is applied to the subsequent
  *     groups until the next name is encountered:
  *     <ul>
  *       <li>ON sets the state of subsequent groups to ON
  *       <li>OFF sets the state of subsequent groups to OFF
  *       <li>Toggle reverses the state of subsequent groups
  *     </ul>
  *
  * @param preserveRB if <CODE>true</CODE>, indicates that radio-button state relationships between
  *     optional content groups (as specified by the RBGroups entry in the current configuration
  *     dictionary) should be preserved when the states in the <CODE>state</CODE> array are
  *     applied. That is, if a group is set to ON (either by ON or Toggle) during processing of the
  *     <CODE>state</CODE> array, any other groups belong to the same radio-button group are turned
  *     OFF. If a group is set to OFF, there is no effect on other groups.<br>
  *     If <CODE>false</CODE>, radio-button state relationships, if any, are ignored
  * @return the action
  */
 public static PdfAction setOCGstate(ArrayList state, boolean preserveRB) {
   PdfAction action = new PdfAction();
   action.put(PdfName.S, PdfName.SETOCGSTATE);
   PdfArray a = new PdfArray();
   for (int k = 0; k < state.size(); ++k) {
     Object o = state.get(k);
     if (o == null) continue;
     if (o instanceof PdfIndirectReference) a.add((PdfIndirectReference) o);
     else if (o instanceof PdfLayer) a.add(((PdfLayer) o).getRef());
     else if (o instanceof PdfName) a.add((PdfName) o);
     else if (o instanceof String) {
       PdfName name = null;
       String s = (String) o;
       if (s.equalsIgnoreCase("on")) name = PdfName.ON;
       else if (s.equalsIgnoreCase("off")) name = PdfName.OFF;
       else if (s.equalsIgnoreCase("toggle")) name = PdfName.TOGGLE;
       else
         throw new IllegalArgumentException(
             "A string '"
                 + s
                 + " was passed in state. Only 'ON', 'OFF' and 'Toggle' are allowed.");
       a.add(name);
     } else
       throw new IllegalArgumentException(
           "Invalid type was passed in state: " + o.getClass().getName());
   }
   action.put(PdfName.STATE, a);
   if (!preserveRB) action.put(PdfName.PRESERVERB, PdfBoolean.PDFFALSE);
   return action;
 }
예제 #2
0
 protected static PdfArray processOptions(String options[]) {
   PdfArray array = new PdfArray();
   for (int k = 0; k < options.length; ++k) {
     array.add(new PdfString(options[k], PdfObject.TEXT_UNICODE));
   }
   return array;
 }
예제 #3
0
  /** Translate a PRArray to a PdfArray. Also translate all of the objects contained in it */
  protected PdfArray copyArray(PdfArray in) throws IOException, BadPdfFormatException {
    PdfArray out = new PdfArray();

    for (Iterator i = in.listIterator(); i.hasNext(); ) {
      PdfObject value = (PdfObject) i.next();
      out.add(copyObject(value));
    }
    return out;
  }
예제 #4
0
 protected static PdfArray processOptions(String options[][]) {
   PdfArray array = new PdfArray();
   for (int k = 0; k < options.length; ++k) {
     String subOption[] = options[k];
     PdfArray ar2 = new PdfArray(new PdfString(subOption[0], PdfObject.TEXT_UNICODE));
     ar2.add(new PdfString(subOption[1], PdfObject.TEXT_UNICODE));
     array.add(ar2);
   }
   return array;
 }
예제 #5
0
 /**
  * Add a chained action.
  *
  * @param na the next action
  */
 public void next(PdfAction na) {
   PdfObject nextAction = get(PdfName.NEXT);
   if (nextAction == null) put(PdfName.NEXT, na);
   else if (nextAction.isDictionary()) {
     PdfArray array = new PdfArray(nextAction);
     array.add(na);
     put(PdfName.NEXT, array);
   } else {
     ((PdfArray) nextAction).add(na);
   }
 }
예제 #6
0
 static PdfArray buildArray(Object names[]) {
   PdfArray array = new PdfArray();
   for (int k = 0; k < names.length; ++k) {
     Object obj = names[k];
     if (obj instanceof String) array.add(new PdfString((String) obj));
     else if (obj instanceof PdfAnnotation)
       array.add(((PdfAnnotation) obj).getIndirectReference());
     else throw new RuntimeException("The array must contain String or PdfAnnotation.");
   }
   return array;
 }
예제 #7
0
 public void setUsed() {
   used = true;
   if (parent != null) put(PdfName.PARENT, parent.getIndirectReference());
   if (kids != null) {
     PdfArray array = new PdfArray();
     for (int k = 0; k < kids.size(); ++k) array.add(kids.get(k).getIndirectReference());
     put(PdfName.KIDS, array);
   }
   if (templates == null) return;
   PdfDictionary dic = new PdfDictionary();
   for (PdfTemplate template : templates) {
     mergeResources(dic, (PdfDictionary) template.getResources());
   }
   put(PdfName.DR, dic);
 }
예제 #8
0
  /**
   * After reading, we index all of the fields. Recursive.
   *
   * @param fieldlist An array of fields
   * @param fieldDict the last field dictionary we encountered (recursively)
   * @param title the pathname of the field, up to this point or null
   */
  protected void iterateFields(PdfArray fieldlist, PRIndirectReference fieldDict, String title) {
    for (Iterator it = fieldlist.getArrayList().iterator(); it.hasNext(); ) {
      PRIndirectReference ref = (PRIndirectReference) it.next();
      PdfDictionary dict = (PdfDictionary) PdfReader.getPdfObjectRelease(ref);

      // if we are not a field dictionary, pass our parent's values
      PRIndirectReference myFieldDict = fieldDict;
      String myTitle = title;
      PdfString tField = (PdfString) dict.get(PdfName.T);
      boolean isFieldDict = tField != null;

      if (isFieldDict) {
        myFieldDict = ref;
        if (title == null) myTitle = tField.toString();
        else myTitle = title + '.' + tField.toString();
      }

      PdfArray kids = (PdfArray) dict.get(PdfName.KIDS);
      if (kids != null) {
        pushAttrib(dict);
        iterateFields(kids, myFieldDict, myTitle);
        stack.remove(stack.size() - 1); // pop
      } else { // leaf node
        if (myFieldDict != null) {
          PdfDictionary mergedDict = (PdfDictionary) stack.get(stack.size() - 1);
          if (isFieldDict) mergedDict = mergeAttrib(mergedDict, dict);

          mergedDict.put(PdfName.T, new PdfString(myTitle));
          FieldInformation fi = new FieldInformation(myTitle, mergedDict, myFieldDict);
          fields.add(fi);
          fieldByName.put(myTitle, fi);
        }
      }
    }
  }
예제 #9
0
 public void alterContents() throws IOException {
   if (over == null && under == null) return;
   PdfArray ar = null;
   PdfObject content = PdfReader.getPdfObject(pageN.get(PdfName.CONTENTS), pageN);
   if (content == null) {
     ar = new PdfArray();
     pageN.put(PdfName.CONTENTS, ar);
   } else if (content.isArray()) {
     ar = (PdfArray) content;
   } else if (content.isStream()) {
     ar = new PdfArray();
     ar.add(pageN.get(PdfName.CONTENTS));
     pageN.put(PdfName.CONTENTS, ar);
   } else {
     ar = new PdfArray();
     pageN.put(PdfName.CONTENTS, ar);
   }
   ByteBuffer out = new ByteBuffer();
   if (under != null) {
     out.append(PdfContents.SAVESTATE);
     applyRotation(pageN, out);
     out.append(under.getInternalBuffer());
     out.append(PdfContents.RESTORESTATE);
   }
   if (over != null) out.append(PdfContents.SAVESTATE);
   PdfStream stream = new PdfStream(out.toByteArray());
   stream.flateCompress(cstp.getCompressionLevel());
   PdfIndirectReference ref1 = cstp.addToBody(stream).getIndirectReference();
   ar.addFirst(ref1);
   out.reset();
   if (over != null) {
     out.append(' ');
     out.append(PdfContents.RESTORESTATE);
     out.append(PdfContents.SAVESTATE);
     applyRotation(pageN, out);
     out.append(over.getInternalBuffer());
     out.append(PdfContents.RESTORESTATE);
     stream = new PdfStream(out.toByteArray());
     stream.flateCompress(cstp.getCompressionLevel());
     ar.add(cstp.addToBody(stream).getIndirectReference());
   }
   pageN.put(PdfName.RESOURCES, pageResources.getResources());
 }
예제 #10
0
  /** extracts attachments from PDF File */
  @SuppressWarnings("unchecked")
  protected Map extractAttachments(PdfReader reader) throws IOException {
    Map fileMap = new HashMap();
    PdfDictionary catalog = reader.getCatalog();
    PdfDictionary names = (PdfDictionary) PdfReader.getPdfObject(catalog.get(PdfName.NAMES));
    if (names != null) {
      PdfDictionary embFiles =
          (PdfDictionary) PdfReader.getPdfObject(names.get(new PdfName("EmbeddedFiles")));
      if (embFiles != null) {
        HashMap embMap = PdfNameTree.readTree(embFiles);
        for (Iterator i = embMap.values().iterator(); i.hasNext(); ) {
          PdfDictionary filespec = (PdfDictionary) PdfReader.getPdfObject((PdfObject) i.next());
          Object fileInfo[] = unpackFile(reader, filespec);
          if (fileMap.containsKey(fileInfo[0])) {
            throw new RuntimeException(DUPLICATE_FILE_NAMES);
          }
          fileMap.put(fileInfo[0], fileInfo[1]);
        }
      }
    }
    for (int k = 1; k <= reader.getNumberOfPages(); ++k) {
      PdfArray annots = (PdfArray) PdfReader.getPdfObject(reader.getPageN(k).get(PdfName.ANNOTS));
      if (annots == null) {
        continue;
      }
      for (Iterator i = annots.getArrayList().listIterator(); i.hasNext(); ) {
        PdfDictionary annot = (PdfDictionary) PdfReader.getPdfObject((PdfObject) i.next());
        PdfName subType = (PdfName) PdfReader.getPdfObject(annot.get(PdfName.SUBTYPE));
        if (!PdfName.FILEATTACHMENT.equals(subType)) {
          continue;
        }
        PdfDictionary filespec = (PdfDictionary) PdfReader.getPdfObject(annot.get(PdfName.FS));
        Object fileInfo[] = unpackFile(reader, filespec);
        if (fileMap.containsKey(fileInfo[0])) {
          throw new RuntimeException(DUPLICATE_FILE_NAMES);
        }

        fileMap.put(fileInfo[0], fileInfo[1]);
      }
    }

    return fileMap;
  }
예제 #11
0
 /**
  * Reads an array. When this is called, we have already read the ArrayStart token, and arrayDepth
  * has been incremented to reflect this.
  */
 public PdfArray readArray() throws IOException, PdfException {
   PdfArray arr = new PdfArray();
   for (; ; ) {
     PdfObject obj = null;
     try {
       obj = readObject();
       arr.add(obj);
     }
     // We detect the end of an array by a PdfException being thrown
     // when readObject encounters the close bracket.  When we get
     // the end of the array, collapse the vector before returning the object.
     catch (PdfException e) {
       Token tok = e.getToken();
       if (tok instanceof ArrayEnd) {
         collapseObjectVector(arr.getContent());
         return arr;
       } else {
         throw e; // real error
       }
     }
   }
 }
예제 #12
0
 /**
  * Generates the font dictionary for this font.
  *
  * @return the PdfDictionary containing the font dictionary
  * @param firstChar the first valid character
  * @param lastChar the last valid character
  * @param shortTag a 256 bytes long <CODE>byte</CODE> array where each unused byte is represented
  *     by 0
  * @param fontDescriptor the indirect reference to a PdfDictionary containing the font descriptor
  *     or <CODE>null</CODE>
  */
 private PdfDictionary getFontBaseType(
     PdfIndirectReference fontDescriptor, int firstChar, int lastChar, byte shortTag[]) {
   PdfDictionary dic = new PdfDictionary(PdfName.FONT);
   dic.put(PdfName.SUBTYPE, PdfName.TYPE1);
   dic.put(PdfName.BASEFONT, new PdfName(FontName));
   boolean stdEncoding = encoding.equals("Cp1252") || encoding.equals("MacRoman");
   if (!fontSpecific || specialMap != null) {
     for (int k = firstChar; k <= lastChar; ++k) {
       if (!differences[k].equals(notdef)) {
         firstChar = k;
         break;
       }
     }
     if (stdEncoding)
       dic.put(
           PdfName.ENCODING,
           encoding.equals("Cp1252") ? PdfName.WIN_ANSI_ENCODING : PdfName.MAC_ROMAN_ENCODING);
     else {
       PdfDictionary enc = new PdfDictionary(PdfName.ENCODING);
       PdfArray dif = new PdfArray();
       boolean gap = true;
       for (int k = firstChar; k <= lastChar; ++k) {
         if (shortTag[k] != 0) {
           if (gap) {
             dif.add(new PdfNumber(k));
             gap = false;
           }
           dif.add(new PdfName(differences[k]));
         } else gap = true;
       }
       enc.put(PdfName.DIFFERENCES, dif);
       dic.put(PdfName.ENCODING, enc);
     }
   }
   if (specialMap != null
       || forceWidthsOutput
       || !(builtinFont && (fontSpecific || stdEncoding))) {
     dic.put(PdfName.FIRSTCHAR, new PdfNumber(firstChar));
     dic.put(PdfName.LASTCHAR, new PdfNumber(lastChar));
     PdfArray wd = new PdfArray();
     for (int k = firstChar; k <= lastChar; ++k) {
       if (shortTag[k] == 0) wd.add(new PdfNumber(0));
       else wd.add(new PdfNumber(widths[k]));
     }
     dic.put(PdfName.WIDTHS, wd);
   }
   if (!builtinFont && fontDescriptor != null) dic.put(PdfName.FONTDESCRIPTOR, fontDescriptor);
   return dic;
 }
 static PdfArray createDestinationArray(String value, PdfWriter writer) {
   PdfArray ar = new PdfArray();
   StringTokenizer tk = new StringTokenizer(value);
   int n = Integer.parseInt(tk.nextToken());
   ar.add(writer.getPageReference(n));
   if (!tk.hasMoreTokens()) {
     ar.add(PdfName.XYZ);
     ar.add(new float[] {0, 10000, 0});
   } else {
     String fn = tk.nextToken();
     if (fn.startsWith("/")) fn = fn.substring(1);
     ar.add(new PdfName(fn));
     for (int k = 0; k < 4 && tk.hasMoreTokens(); ++k) {
       fn = tk.nextToken();
       if (fn.equals("null")) ar.add(PdfNull.PDFNULL);
       else ar.add(new PdfNumber(fn));
     }
   }
   return ar;
 }
예제 #14
0
  protected PdfObject getSpotObject(PdfWriter writer) throws IOException {
    PdfArray array = new PdfArray(PdfName.SEPARATION);
    array.add(name);
    PdfFunction func = null;
    if (altcs instanceof ExtendedColor) {
      int type = ((ExtendedColor) altcs).type;

      // ssteward
      // having trouble with unreachable bytecode in switch default (per gcj 4.4)
      // so try a clumsier workaround
      boolean handled_b = false;
      switch (type) {
        case ExtendedColor.TYPE_GRAY:
          array.add(PdfName.DEVICEGRAY);
          func =
              PdfFunction.type2(
                  writer,
                  new float[] {0, 1},
                  null,
                  new float[] {0},
                  new float[] {((GrayColor) altcs).getGray()},
                  1);
          handled_b = true;
          break;
        case ExtendedColor.TYPE_CMYK:
          array.add(PdfName.DEVICECMYK);
          CMYKColor cmyk = (CMYKColor) altcs;
          func =
              PdfFunction.type2(
                  writer,
                  new float[] {0, 1},
                  null,
                  new float[] {0, 0, 0, 0},
                  new float[] {
                    cmyk.getCyan(), cmyk.getMagenta(), cmyk.getYellow(), cmyk.getBlack()
                  },
                  1);
          handled_b = true;
          break;
          //                default:
          //                    throw new RuntimeException("Only RGB, Gray and CMYK are supported as
          // alternative color spaces.");
      }
      if (!handled_b) {
        throw new RuntimeException(
            "Only RGB, Gray and CMYK are supported as alternative color spaces.");
      }
    } else {
      array.add(PdfName.DEVICERGB);
      func =
          PdfFunction.type2(
              writer,
              new float[] {0, 1},
              null,
              new float[] {1, 1, 1},
              new float[] {
                (float) altcs.getRed() / 255,
                (float) altcs.getGreen() / 255,
                (float) altcs.getBlue() / 255
              },
              1);
    }
    array.add(func.getReference());
    return array;
  }
예제 #15
0
 public void addAnnotation(PdfAnnotation annot) {
   try {
     ArrayList allAnnots = new ArrayList();
     if (annot.isForm()) {
       PdfFormField field = (PdfFormField) annot;
       if (field.getParent() != null) return;
       expandFields(field, allAnnots);
       if (cstp.fieldTemplates == null) cstp.fieldTemplates = new HashMap();
     } else allAnnots.add(annot);
     for (int k = 0; k < allAnnots.size(); ++k) {
       annot = (PdfAnnotation) allAnnots.get(k);
       if (annot.isForm()) {
         if (!annot.isUsed()) {
           HashMap templates = annot.getTemplates();
           if (templates != null) cstp.fieldTemplates.putAll(templates);
         }
         PdfFormField field = (PdfFormField) annot;
         if (field.getParent() == null) addDocumentField(field.getIndirectReference());
       }
       if (annot.isAnnotation()) {
         PdfObject pdfobj = PdfReader.getPdfObject(pageN.get(PdfName.ANNOTS), pageN);
         PdfArray annots = null;
         if (pdfobj == null || !pdfobj.isArray()) {
           annots = new PdfArray();
           pageN.put(PdfName.ANNOTS, annots);
         } else annots = (PdfArray) pdfobj;
         annots.add(annot.getIndirectReference());
         if (!annot.isUsed()) {
           PdfRectangle rect = (PdfRectangle) annot.get(PdfName.RECT);
           if (rect != null
               && (rect.left() != 0
                   || rect.right() != 0
                   || rect.top() != 0
                   || rect.bottom() != 0)) {
             int rotation = reader.getPageRotation(pageN);
             Rectangle pageSize = reader.getPageSizeWithRotation(pageN);
             switch (rotation) {
               case 90:
                 annot.put(
                     PdfName.RECT,
                     new PdfRectangle(
                         pageSize.getTop() - rect.bottom(),
                         rect.left(),
                         pageSize.getTop() - rect.top(),
                         rect.right()));
                 break;
               case 180:
                 annot.put(
                     PdfName.RECT,
                     new PdfRectangle(
                         pageSize.getRight() - rect.left(),
                         pageSize.getTop() - rect.bottom(),
                         pageSize.getRight() - rect.right(),
                         pageSize.getTop() - rect.top()));
                 break;
               case 270:
                 annot.put(
                     PdfName.RECT,
                     new PdfRectangle(
                         rect.bottom(),
                         pageSize.getRight() - rect.left(),
                         rect.top(),
                         pageSize.getRight() - rect.right()));
                 break;
             }
           }
         }
       }
       if (!annot.isUsed()) {
         annot.setUsed();
         cstp.addToBody(annot, annot.getIndirectReference());
       }
     }
   } catch (IOException e) {
     throw new ExceptionConverter(e);
   }
 }