Package org.pdfclown.samples.cli

Source Code of org.pdfclown.samples.cli.IndirectObjectEditingSample

package org.pdfclown.samples.cli;

import org.pdfclown.bytes.IBuffer;
import org.pdfclown.files.File;
import org.pdfclown.objects.PdfDataObject;
import org.pdfclown.objects.PdfDictionary;
import org.pdfclown.objects.PdfIndirectObject;
import org.pdfclown.objects.PdfName;
import org.pdfclown.objects.PdfReference;
import org.pdfclown.objects.PdfStream;

/**
  This sample demonstrates <b>how to modify existing PDF indirect objects</b>.
  <p>As a practical case, we suppose to have to modify existing unicode font mappings.</p>

  @author Stefano Chizzolini (http://www.stefanochizzolini.it)
  @since 0.0.7
  @version 0.1.0
*/
public class IndirectObjectEditingSample
  extends Sample
{
  @Override
  public boolean run(
    )
  {
    // 1. Opening the PDF file...
    File file;
    {
      String filePath = promptPdfFileChoice("Please select a PDF file");

      try
      {file = new File(filePath);}
      catch(Exception e)
      {throw new RuntimeException(filePath + " file access error.",e);}
    }

    // 2. Iterating through the indirect objects to discover existing unicode mapping (ToUnicode) streams to edit...
    /*
      NOTE: For the sake of simplicity, I assume that all font objects
      tipically reside in distinct indirect objects.
    */
    for(PdfIndirectObject indirectObject : file.getIndirectObjects())
    {
      /*
        NOTE: In order to get the unicode mapping stream we have to get
        its corresponding font object, which is a dictionary.
      */
      PdfDataObject dataObject = indirectObject.getDataObject();
      if(!(dataObject instanceof PdfDictionary) // Data object is NOT a dictionary.
        || !PdfName.Font.equals(((PdfDictionary)dataObject).get(PdfName.Type))) // Dictionary is NOT a font object.
        continue;

      // Get the indirect reference to the ToUnicode stream associated to the font object!
      PdfReference toUnicodeReference = (PdfReference)((PdfDictionary)dataObject).get(PdfName.ToUnicode);
      if(toUnicodeReference == null) // No ToUnicode stream.
        continue;

      /*
        NOTE: You can either:
          1) modify the existing data object contained within the indirect object;
        or
          2) create a new data object to replace the existing data object contained within the indirect object.
        For the sake of completeness, in this sample we apply both these approaches.

        NOTE: Data objects may be any object inheriting from the PdfDataObject class
        (for example: PdfName, PdfInteger, PdfTextString, PdfArray, PdfStream, PdfDictionary and so on...).
        Unicode mapping streams are... (you guess!) PdfStream objects.
      */
      if(toUnicodeReference.getObjectNumber() % 2 == 0) // NOTE: Arbitrary condition to force the use of both the approaches.
      {
        /*
          Approach 1: Modifying the existing data object.
        */
        // Get the existing data object from the corresponding indirect object!
        PdfStream toUnicodeStream = (PdfStream)toUnicodeReference.getDataObject();

        // Editing the data object...
        IBuffer streamBody = toUnicodeStream.getBody();
        streamBody.setLength(0); // Erases the stream content to prepare it for new content insertion.
        streamBody.append("... modified ..."); // Adds arbitrary contents (NOTE: this would NOT be done in a real ToUnicode stream! We are just testing the editing functionality...).
      }
      else
      {
        /*
          Approach 2: Creating a new data object.
        */
        // Create a new data object!
        PdfStream toUnicodeStream = new PdfStream();
        // Associate the new data object to the existing indirect object, replacing the old one!
        toUnicodeReference.setDataObject(toUnicodeStream);

        // Editing the data object...
        IBuffer streamBody = toUnicodeStream.getBody();
        streamBody.append("... created ..."); // Adds arbitrary contents (NOTE: this would NOT be done in a real ToUnicode stream! We are just testing the editing functionality...).
      }

      toUnicodeReference.getIndirectObject().update(); // Ensures that the indirect object is updated.
    }

    // 3. Serialize the PDF file!
    serialize(file);
   
    return true;
  }
}
TOP

Related Classes of org.pdfclown.samples.cli.IndirectObjectEditingSample

TOP
Copyright © 2018 www.massapi.com. All rights reserved.
All source code are property of their respective owners. Java is a trademark of Sun Microsystems, Inc and owned by ORACLE Inc. Contact coftware#gmail.com.