title: java / pdf text rendering
body: <p>I'm working on my own pdf generating lib in Java and I'm having some troubles with font/text rendering. The text displayed (font, word spacing, character spacing,...) in Java differs from the one displayed in PDF.</p>
  
  <p>In my below example, I'm using the font "Time New Roman" which is one of the PDF base font (so I have not to compute and output all the font metrics into the pdf).</p>
  
  <p>So concretely in my generated PDF, I have this:</p>
  
  <pre><code>BT
  /F5 16 Tf
  849 921 Td
  (Normal Return Distribution) Tj
  ET
  </code></pre>
  
  <p>And the font F5 is defined by the object 29 0 R, which is (only basefont, so no text metrics is specified):</p>
  
  <pre><code>29 0 obj &lt;&lt;/Type /Font /Subtype /Type1 /BaseFont /Times-Roman&gt;&gt;
  endobj
  </code></pre>
  
  <p>In Java, I'm using :</p>
  
  <pre><code>g2d.setFont(new Font("TimesRoman", Font.PLAIN, 16));
  g2d.drawString("Normal Return Distribution", 849, 921);
  </code></pre>
  
  <p>I've drawn the text into a rectangle which match the text boundaries, and in Java all it's ok (I've compute the string bounds in java), but in adobe acrobat reader, the text is bigger than the rectangle.</p>
  
  <p>Here is a screenshot (I've built it by taking a screenshot of Adobe Acrobat Reader displaying my PDF, and taking a screenshot of my program displaying the buffered image; and then copy/paste the portion of the pdf screenshot below the rectangle of my program screenshot into MSPaint. To have the same rectangles size, I have to display the pdf in Adobe in 65.5% of the original size):</p>
  
  <p><img src="https://i.stack.imgur.com/GHuNw.png" alt="Java vs PDF text output"></p>
  
  <p>So we can see that the font used in java en adobe to display the text is the same. But the text seems a little bigger into Adobe. In fact if I superimpose two words (one from java on top of one from adobe) it seems that the word spacing is the same, the letter spacing too, but some letters have 1 pixel width diff.</p>
  
  <p>Why?
  What can I do to sovle this? I'v tried to play (in pdf) with character spacing (Tc operator), word spacing (Tw operator), horizontal scaling (Tz operator); I think it can "work"; but why is not the same scaling/spacing/... in both program? Theses (default) parameters are not part of the Font file (which is a true type one)? And how to retrieve them correctly (without putting into my java code the parameter manually)?</p>
  
  <p>Thanks</p>
  
  <p><strong>EDIT</strong></p>
  
  <p>So, as you've both explained, I'm investigating to not use pdf base fonts to be sure that the same font (ttf file) is used by Java and Adobe Reader. But I'm stil have one problem (the same?).</p>
  
  <p>In PDF output, I'm generating the font like that:</p>
  
  <pre><code>31 0 obj &lt;&lt;
  /Type /Font
  /FirstChar 0
  /LastChar 255
  /Widths[1298 ... 646]
  /Name /F7
  /Encoding /WinAnsiEncoding
  /Subtype /TrueType /BaseFont /Tahoma /FontDescriptor 32 0 R
  &gt;&gt;
  endobj
  
  32 0 obj &lt;&lt;
  /Type /FontDescriptor
  /Ascent 1299
  /CapHeight 1298
  /Descent -269
  /Flags 32
  /FontBBox [0 -269 2012 1299]
  /FontName /Tahoma
  /ItalicAngle 0
  /StemV 126
  /XHeight 1298
  &gt;&gt;
  endobj
  </code></pre>
  
  <p>If I have understand the specification correctly, all number (widths, ascent, descent,...) are relative to glyph unit (1em based?), where 1em = 1000 (and 1em is the width of the M character).</p>
  
  <p>So to generate all theses parameters from java, I first try to find the correct java font size to have the width of the M character to be equal to 1000 (because Java does not give access to theses parameters in Font class or other classes; and PDF needs it even if theses informations are into the ttf file??).</p>
  
  <pre><code>float size = 1f;
  while (true) {
      font = font.deriveFont(size);
      fm = g2d.getFontMetrics(font);
      int em = fm.charWidth('M');
      if (em &gt;= 1000)
          break ;
      size += 1;
  }
  </code></pre>
  
  <p>And then I can generate all requiered parameters. By example, for the Widths array (which is the width of each character) : </p>
  
  <pre><code>String pdfWidths = "";
  for (int i = 0; i &lt;= 255; ++i) {
      int width = fm.charWidth(i);
      pdfWidths += width + " ";
  }
  </code></pre>
  
  <p>But doing this, I still have my text overlapping the rectangle in Adobe Viewer.
  So I have to set my EM limit (into my brute force loop) to 780 for Tahoma font; to 850 for Verdana font;... to have similar text displayed (not exactly the same, but it's due, perhaps, to the anti aliasing algorithm?) (see the screenshot below). So it's not a constant "limit" (to must be theorically equal to 1000), but a variable limit... is that correct? (I think no) If yes, how to find this limit? If no, what is wrong?</p>
  
  <p><img src="https://i.stack.imgur.com/jZdSP.png" alt="Java vs PDF text output - EM"></p>
  
  <p>Thanks again.</p>
  
  <p><strong>EDIT</strong></p>
  
  <p>Simply setting font size to 1000 and without bruteforcing to found the EM/Line height size, the result in pdf is really to java.</p>
  
  <pre><code>font = font.deriveFont(1000f);
  fm = g2d.getFontMetrics(font);
  //Retrieve Widths attribute
  _pdfWidths = "";
  for (int i = _firstChar; i &lt;= _lastChar; ++i) {
      int width = fm.charWidth(i);
      _pdfWidths += width + " ";
  }
  </code></pre>
  
  <p>But there is still a little difference, maybe it is due to the text drawing algorigthm (kerning maybe differ from java and adobe reader?). See image below, we can see, with Verdana, that the text is a little bit smaller (in width) in pdf than in java.</p>
  
  <p><img src="https://i.stack.imgur.com/1lN6U.png" alt="Java vs PDF text output - 1000"></p>