Re: [iText-questions] True Type Font Portability and Division by Zero exception

2002-05-14 Thread Jeff Larsen

I found and fixed the problem. It had nothing to do with iText.

In the original code (below) the call to "ocraURL.openStream().read(bytes)"
returns the full file when the file is not jarred. When the font file
is contained in a jar, openStream() gets you an unbufffered InputStream
which requires repeated reads to get the full file.

BaseFont ocra = null;
ClassLoader cl = Thread.currentThread().getContextClassLoader();
URL ocraURL = cl.getResource("com/qec/util/fonts/OCRAN.TTF");
if (ocraURL != null) {
  byte[] bytes = new byte[ocraURL.openConnection().getContentLength()];
  ocraURL.openStream().read(bytes);
  ocra = BaseFont.createFont("OCRAN.TTF", BaseFont.WINANSI,
 BaseFont.EMBEDDED, BaseFont.CACHED, bytes, null);
}

The correct code to read the byte[] is:

  BufferedInputStream input = new BufferedInputStream(ocraURL.openStream());
  input.read(bytes, 0, bytes.length);

So the exception thrown by iText was because I fed it a font byte[] of
mostly zeros. Perhaps future versions of iText could throw an exception
in the call to BaseFont.createFont() if the byte[] is bogus. Then developers
would have a better idea of where the problem lies.

Thanks, 

Jeff

- Original Message - 
From: "Paulo Soares" <[EMAIL PROTECTED]>
To: "'Jeff Larsen'" <[EMAIL PROTECTED]>; <[EMAIL PROTECTED]>
Sent: Tuesday, May 14, 2002 5:22 AM
Subject: RE: [iText-questions] True Type Font Portability and Division by Zero 
exception


> That's really strange. The method where the exception is thrown is called
> after the embedded information is sent to the pdf, so the byte array has the
> font. It can only throw the exception if head.unitsPerEm is zero and that
> value was used before many times.
> I tested your code and it works.
> 
> Best Regards,
> Paulo Soares
> 
> > -Original Message-
> > From: Jeff Larsen [SMTP:[EMAIL PROTECTED]]
> > Sent: Monday, May 13, 2002 20:21
> > To: [EMAIL PROTECTED]
> > Subject: [iText-questions] True Type Font Portability and Division by
> > Zero exception
> > 
> > I'm using iText to generate PDF on the fly in a servlet running
> > under Tomcat 4.0.3. The PDF document requires that an image file
> > and True Type font file be packaged with the class that creates
> > the PDF. In my development environment where the image and font
> > files are read directly from the file system, everything works just
> > fine. In my production environment (UNIX), where the PDF writing class,
> > font and image files are packaged in a jar, I get a division by zero
> > error as shown in the stack trace at the end of this message.
> > 
> > Here's the java code for creating the font:
> > 
> > BaseFont ocra = null;
> > ClassLoader cl = Thread.currentThread().getContextClassLoader();
> > URL ocraURL = cl.getResource("com/qec/util/fonts/OCRAN.TTF");
> > if (ocraURL != null) {
> >   byte[] bytes = new byte[ocraURL.openConnection().getContentLength()];
> >   ocraURL.openStream().read(bytes);
> >   ocra = BaseFont.createFont("OCRAN.TTF", BaseFont.WINANSI,
> >  BaseFont.EMBEDDED, BaseFont.CACHED, bytes,
> > null);
> > }
> > 
> > Since my ultimate goal was to make this code reusable outside of
> > servlets, the class which contains the iText code and the required font
> > and image files are packaged with the servlet in a jar file which is
> > placed in the WEB-INF/lib directory of my web application.
> > 
> > I know that the ClassLoader.getResource() code works, because I load an
> > image file using the same technique. Am I incorrect in thinking that
> > embedded True Type fonts can be used in this fashion outside of the
> > Windows environment?
> > 
> > Any insight into this problem is greatly appreciated.
> > 
> > Jeff
> > 
> > Here's the previously mentioned stack trace:
> > 
> > ExceptionConverter: java.lang.ArithmeticException: / by zero
> >  at com.lowagie.text.pdf.TrueTypeFont.getFontDescriptor(Unknown Source)
> >  at com.lowagie.text.pdf.TrueTypeFont.writeFont(Unknown Source)
> >  at com.lowagie.text.pdf.FontDetails.writeFont(Unknown Source)
> >  at com.lowagie.text.pdf.PdfWriter.close(Unknown Source)
> >  at com.lowagie.text.pdf.PdfDocument.close(Unknown Source)
> >  at com.lowagie.text.Document.close(Unknown Source)
> >  at com.qec.util.InvoiceWriter.writePdf(InvoiceWriter.java:103)
> >  at
> > com.qec.offsite.servlet.InvoiceServlet.doInvoiceAsPDF(InvoiceServlet.java:
> > 106)
> >  at
> > com.qec.offsite.servlet.InvoiceServl

RE: [iText-questions] True Type Font Portability and Division by Zero exception

2002-05-14 Thread Paulo Soares

That's really strange. The method where the exception is thrown is called
after the embedded information is sent to the pdf, so the byte array has the
font. It can only throw the exception if head.unitsPerEm is zero and that
value was used before many times.
I tested your code and it works.

Best Regards,
Paulo Soares

> -Original Message-
> From: Jeff Larsen [SMTP:[EMAIL PROTECTED]]
> Sent: Monday, May 13, 2002 20:21
> To:   [EMAIL PROTECTED]
> Subject:  [iText-questions] True Type Font Portability and Division by
> Zero exception
> 
> I'm using iText to generate PDF on the fly in a servlet running
> under Tomcat 4.0.3. The PDF document requires that an image file
> and True Type font file be packaged with the class that creates
> the PDF. In my development environment where the image and font
> files are read directly from the file system, everything works just
> fine. In my production environment (UNIX), where the PDF writing class,
> font and image files are packaged in a jar, I get a division by zero
> error as shown in the stack trace at the end of this message.
> 
> Here's the java code for creating the font:
> 
> BaseFont ocra = null;
> ClassLoader cl = Thread.currentThread().getContextClassLoader();
> URL ocraURL = cl.getResource("com/qec/util/fonts/OCRAN.TTF");
> if (ocraURL != null) {
>   byte[] bytes = new byte[ocraURL.openConnection().getContentLength()];
>   ocraURL.openStream().read(bytes);
>   ocra = BaseFont.createFont("OCRAN.TTF", BaseFont.WINANSI,
>  BaseFont.EMBEDDED, BaseFont.CACHED, bytes,
> null);
> }
> 
> Since my ultimate goal was to make this code reusable outside of
> servlets, the class which contains the iText code and the required font
> and image files are packaged with the servlet in a jar file which is
> placed in the WEB-INF/lib directory of my web application.
> 
> I know that the ClassLoader.getResource() code works, because I load an
> image file using the same technique. Am I incorrect in thinking that
> embedded True Type fonts can be used in this fashion outside of the
> Windows environment?
> 
> Any insight into this problem is greatly appreciated.
> 
> Jeff
> 
> Here's the previously mentioned stack trace:
> 
> ExceptionConverter: java.lang.ArithmeticException: / by zero
>  at com.lowagie.text.pdf.TrueTypeFont.getFontDescriptor(Unknown Source)
>  at com.lowagie.text.pdf.TrueTypeFont.writeFont(Unknown Source)
>  at com.lowagie.text.pdf.FontDetails.writeFont(Unknown Source)
>  at com.lowagie.text.pdf.PdfWriter.close(Unknown Source)
>  at com.lowagie.text.pdf.PdfDocument.close(Unknown Source)
>  at com.lowagie.text.Document.close(Unknown Source)
>  at com.qec.util.InvoiceWriter.writePdf(InvoiceWriter.java:103)
>  at
> com.qec.offsite.servlet.InvoiceServlet.doInvoiceAsPDF(InvoiceServlet.java:
> 106)
>  at
> com.qec.offsite.servlet.InvoiceServlet.processRequest(InvoiceServlet.java:
> 51)
>  at com.qec.offsite.servlet.InvoiceServlet.doGet(InvoiceServlet.java:39)
>  at javax.servlet.http.HttpServlet.service(HttpServlet.java:740)
>  at
> com.qec.offsite.servlet.AbstractOffsiteServlet.service(AbstractOffsiteServ
> let.java:60)
>  at javax.servlet.http.HttpServlet.service(HttpServlet.java:853)
>  at
> org.apache.catalina.core.ApplicationFilterChain.internalDoFilter(Applicati
> onFilterChain.ja
> va:247)
>  at
> org.apache.catalina.core.ApplicationFilterChain.doFilter(ApplicationFilter
> Chain.java:193)
>  at
> org.apache.catalina.core.StandardWrapperValve.invoke(StandardWrapperValve.
> java:243)
>  at
> org.apache.catalina.core.StandardPipeline.invokeNext(StandardPipeline.java
> :566)
>  at
> org.apache.catalina.core.StandardPipeline.invoke(StandardPipeline.java:472
> )
>  at org.apache.catalina.core.ContainerBase.invoke(ContainerBase.java:943)
>  at
> org.apache.catalina.core.StandardContextValve.invoke(StandardContextValve.
> java:190)
>  at
> org.apache.catalina.core.StandardPipeline.invokeNext(StandardPipeline.java
> :566)
>  at
> org.apache.catalina.core.StandardPipeline.invoke(StandardPipeline.java:472
> )
>  at org.apache.catalina.core.ContainerBase.invoke(ContainerBase.java:943)
>  at
> org.apache.catalina.core.StandardContext.invoke(StandardContext.java:2343)
>  at
> org.apache.catalina.core.StandardHostValve.invoke(StandardHostValve.java:1
> 80)
>  at
> org.apache.catalina.core.StandardPipeline.invokeNext(StandardPipeline.java
> :566)
>  at
> org.apache.catalina.valves.ErrorDispatcherValve.invoke(ErrorDispatcherValv
> e.java:170)
>  at
> org.apache.catalina.core.StandardPipeline.invokeNext(StandardPipeline.java
> :564)
>  at
> org.apache.catalina.valves.ErrorReportValve.invoke(ErrorReportValve.java:1
> 70)
>  at
> org.apache.catalina.core.StandardPipeline.invokeNext(StandardPipeline.java
> :564)
>  at
> org.apache.catalina.core.StandardPipeline.invoke(StandardPipeline.java:472
> )
>  at org.apache.catalina.core.ContainerBase.invoke(ContainerBase.java:943)
>  at
> org.apache.catalina.core.StandardEngineValve.invoke(StandardEn