Uploaded image for project: 'PDFBox'
  1. PDFBox
  2. PDFBOX-732

Loading TTF font files from the classpath

    Details

    • Type: Improvement
    • Status: Closed
    • Priority: Major
    • Resolution: Fixed
    • Affects Version/s: 1.1.0
    • Fix Version/s: 1.2.0
    • Component/s: PDModel
    • Labels:

      Description

      Currently (pdfbox 1.1.0 & 1.2.0 snapshot) TTF font files can only be loaded from the file system as PDTrueTypeFont exposes two load methods:
      public static PDTrueTypeFont loadTTF(PDDocument, String)
      public static PDTrueTypeFont loadTTF(PDDocument, File)
      The first wraps the String in a java.io.File object and delegates to the second, so all TTF reading is from the file system.

      It would be useful to be able to read TTF files from the classpath - or indeed from any arbitrary stream.
      Could we have a third method?:
      public static PDTrueTypeFont loadTTF(PDDocument, InputStream)

      This would allow TTFs to be loaded like so:
      PDTrueTypeFont.load(myDoc, MyClass.class.getClassLoader().getResourceAsStream("myFont.ttf"));

      For what it's worth here's a patch of what I did (see below).
      One uncertainty I had was about the use of the COSName.LENGTH1 field which only seems to be used currently in PDTrueTypeFont. So it may be reasonable or not to push the setting of this attribute into the PDStream constructor.

      Index: pdfbox/src/main/java/org/apache/pdfbox/pdmodel/common/PDStream.java
      ===================================================================
      — pdfbox/src/main/java/org/apache/pdfbox/pdmodel/common/PDStream.java (revision 948363)
      +++ pdfbox/src/main/java/org/apache/pdfbox/pdmodel/common/PDStream.java (working copy)
      @@ -114,12 +114,17 @@

      { output = stream.createUnfilteredStream(); }

      + int bytesInInputStream = 0;
      byte[] buffer = new byte[ 1024 ];
      int amountRead = -1;
      while( (amountRead = str.read(buffer)) != -1 )

      { output.write( buffer, 0, amountRead ); + bytesInInputStream += amountRead; }

      +
      + // Set the number of bytes read from the input stream
      + this.stream.setInt( COSName.LENGTH1, bytesInInputStream );
      }
      finally

      { Index: pdfbox/src/main/java/org/apache/pdfbox/pdmodel/font/PDTrueTypeFont.java =================================================================== --- pdfbox/src/main/java/org/apache/pdfbox/pdmodel/font/PDTrueTypeFont.java (revision 948363) +++ pdfbox/src/main/java/org/apache/pdfbox/pdmodel/font/PDTrueTypeFont.java (working copy) @@ -130,7 +130,7 @@ }

      /**

      • * This will load a TTF to be embedding into a document.
        + * This will load a TTF to be embedded into a document.
        *
      • @param doc The PDF document that will hold the embedded font.
      • @param file A TTF file stream.
        @@ -139,21 +139,32 @@
        */
        public static PDTrueTypeFont loadTTF( PDDocument doc, File file ) throws IOException { + return loadTTF( doc, new FileInputStream( file ) ); + }

        +
        + /**
        + * This will load a TTF to be embedded into a document.
        + *
        + * @param doc The PDF document that will hold the embedded font.
        + * @param stream A TTF input stream.
        + * @return A PDF TTF.
        + * @throws IOException If there is an error loading the data.
        + */
        + public static PDTrueTypeFont loadTTF( PDDocument doc, InputStream stream ) throws IOException
        + {
        PDTrueTypeFont retval = new PDTrueTypeFont();
        PDFontDescriptorDictionary fd = new PDFontDescriptorDictionary();

      • PDStream fontStream = new PDStream(doc, new FileInputStream( file ), false );
      • fontStream.getStream().setInt( COSName.LENGTH1, (int)file.length() );
        + PDStream fontStream = new PDStream(doc, stream, false );
        fontStream.addCompression();
        fd.setFontFile2( fontStream );
        retval.setFontDescriptor( fd );
      • InputStream ttfData = new FileInputStream(file);
        try { - loadDescriptorDictionary(retval, fd, ttfData); + loadDescriptorDictionary(retval, fd, stream); }

        finally

        { - ttfData.close(); + stream.close(); }

        //only support winansi encoding right now, should really
        //just use Identity-H with unicode mapping

        Attachments

          Activity

            People

            • Assignee:
              lehmi Andreas Lehmkühler
              Reporter:
              neilm Neil McErlean
            • Votes:
              0 Vote for this issue
              Watchers:
              0 Start watching this issue

              Dates

              • Created:
                Updated:
                Resolved: