You are viewing a plain text version of this content. The canonical link for it is here.
Posted to commits@pdfbox.apache.org by ja...@apache.org on 2015/05/19 19:19:42 UTC
svn commit: r1680350 - in /pdfbox/trunk:
examples/src/main/java/org/apache/pdfbox/examples/acroforms/
pdfbox/src/main/java/org/apache/pdfbox/pdmodel/font/
pdfbox/src/main/java/org/apache/pdfbox/pdmodel/interactive/form/
Author: jahewson
Date: Tue May 19 17:19:42 2015
New Revision: 1680350
URL: http://svn.apache.org/r1680350
Log:
PDFBOX-2805: Correct CapHeight calculation, use bbox for form field text
Modified:
pdfbox/trunk/examples/src/main/java/org/apache/pdfbox/examples/acroforms/CreateFormField.java
pdfbox/trunk/examples/src/main/java/org/apache/pdfbox/examples/acroforms/FillFormField.java
pdfbox/trunk/pdfbox/src/main/java/org/apache/pdfbox/pdmodel/font/TrueTypeEmbedder.java
pdfbox/trunk/pdfbox/src/main/java/org/apache/pdfbox/pdmodel/interactive/form/AppearanceGeneratorHelper.java
Modified: pdfbox/trunk/examples/src/main/java/org/apache/pdfbox/examples/acroforms/CreateFormField.java
URL: http://svn.apache.org/viewvc/pdfbox/trunk/examples/src/main/java/org/apache/pdfbox/examples/acroforms/CreateFormField.java?rev=1680350&r1=1680349&r2=1680350&view=diff
==============================================================================
--- pdfbox/trunk/examples/src/main/java/org/apache/pdfbox/examples/acroforms/CreateFormField.java (original)
+++ pdfbox/trunk/examples/src/main/java/org/apache/pdfbox/examples/acroforms/CreateFormField.java Tue May 19 17:19:42 2015
@@ -19,7 +19,6 @@ package org.apache.pdfbox.examples.acrof
import java.io.File;
import java.io.IOException;
-
import org.apache.pdfbox.cos.COSName;
import org.apache.pdfbox.pdmodel.PDDocument;
import org.apache.pdfbox.pdmodel.PDPage;
@@ -65,14 +64,14 @@ public class CreateFormField
PDAnnotationWidget widget = textBox.getWidgets().get(0);
PDRectangle rect = new PDRectangle();
rect.setLowerLeftX((float) 50);
- rect.setLowerLeftY((float) 750);
+ rect.setLowerLeftY((float) 550);
rect.setUpperRightX((float) 250);
- rect.setUpperRightY((float) 800);
+ rect.setUpperRightY((float) 560);
widget.setRectangle(rect);
page.getAnnotations().add(widget);
// set the field value
- textBox.setValue("English ÑÑÑÑкий ÑзÑк Tiếng Viá»t");
+ textBox.setValue("English form contents");
document.save("exampleForm.pdf");
document.close();
Modified: pdfbox/trunk/examples/src/main/java/org/apache/pdfbox/examples/acroforms/FillFormField.java
URL: http://svn.apache.org/viewvc/pdfbox/trunk/examples/src/main/java/org/apache/pdfbox/examples/acroforms/FillFormField.java?rev=1680350&r1=1680349&r2=1680350&view=diff
==============================================================================
--- pdfbox/trunk/examples/src/main/java/org/apache/pdfbox/examples/acroforms/FillFormField.java (original)
+++ pdfbox/trunk/examples/src/main/java/org/apache/pdfbox/examples/acroforms/FillFormField.java Tue May 19 17:19:42 2015
@@ -33,7 +33,7 @@ public class FillFormField
public static void main(String[] args) throws IOException
{
String formTemplate = "src/main/resources/org/apache/pdfbox/examples/acroforms/FillFormField.pdf";
- String filledForm = "target/examples-output/FillFormField.pdf";
+ String filledForm = "FillFormField.pdf";
// load the document
PDDocument pdfDocument = PDDocument
Modified: pdfbox/trunk/pdfbox/src/main/java/org/apache/pdfbox/pdmodel/font/TrueTypeEmbedder.java
URL: http://svn.apache.org/viewvc/pdfbox/trunk/pdfbox/src/main/java/org/apache/pdfbox/pdmodel/font/TrueTypeEmbedder.java?rev=1680350&r1=1680349&r2=1680350&view=diff
==============================================================================
--- pdfbox/trunk/pdfbox/src/main/java/org/apache/pdfbox/pdmodel/font/TrueTypeEmbedder.java (original)
+++ pdfbox/trunk/pdfbox/src/main/java/org/apache/pdfbox/pdmodel/font/TrueTypeEmbedder.java Tue May 19 17:19:42 2015
@@ -207,16 +207,16 @@ abstract class TrueTypeEmbedder implemen
// CapHeight, XHeight
if (os2.getVersion() >= 1.2)
{
- fd.setCapHeight(os2.getCapHeight() / scaling);
- fd.setXHeight(os2.getHeight() / scaling);
+ fd.setCapHeight(os2.getCapHeight() * scaling);
+ fd.setXHeight(os2.getHeight() * scaling);
}
else
{
// estimate by summing the typographical +ve ascender and -ve descender
- fd.setCapHeight((os2.getTypoAscender() + os2.getTypoDescender()) / scaling);
+ fd.setCapHeight((os2.getTypoAscender() + os2.getTypoDescender()) * scaling);
// estimate by halving the typographical ascender
- fd.setXHeight((os2.getTypoAscender() / 2.0f) / scaling);
+ fd.setXHeight(os2.getTypoAscender() / 2.0f * scaling);
}
// StemV - there's no true TTF equivalent of this, so we estimate it
Modified: pdfbox/trunk/pdfbox/src/main/java/org/apache/pdfbox/pdmodel/interactive/form/AppearanceGeneratorHelper.java
URL: http://svn.apache.org/viewvc/pdfbox/trunk/pdfbox/src/main/java/org/apache/pdfbox/pdmodel/interactive/form/AppearanceGeneratorHelper.java?rev=1680350&r1=1680349&r2=1680350&view=diff
==============================================================================
--- pdfbox/trunk/pdfbox/src/main/java/org/apache/pdfbox/pdmodel/interactive/form/AppearanceGeneratorHelper.java (original)
+++ pdfbox/trunk/pdfbox/src/main/java/org/apache/pdfbox/pdmodel/interactive/form/AppearanceGeneratorHelper.java Tue May 19 17:19:42 2015
@@ -30,7 +30,6 @@ import org.apache.pdfbox.pdfwriter.Conte
import org.apache.pdfbox.pdmodel.PDPageContentStream;
import org.apache.pdfbox.pdmodel.common.PDRectangle;
import org.apache.pdfbox.pdmodel.font.PDFont;
-import org.apache.pdfbox.pdmodel.font.PDFontDescriptor;
import org.apache.pdfbox.pdmodel.interactive.action.PDFormFieldAdditionalActions;
import org.apache.pdfbox.pdmodel.interactive.annotation.PDAnnotationWidget;
import org.apache.pdfbox.pdmodel.interactive.annotation.PDAppearanceDictionary;
@@ -187,20 +186,23 @@ class AppearanceGeneratorHelper
// Acrobat calculates the left and right padding dependent on the offset of the border edge
// This calculation works for forms having been generated by Acrobat.
// The minimum distance is always 1f even if there is no rectangle being drawn around.
- float lineWidth = 0;
+ float borderWidth = 0;
if (widget.getBorderStyle() != null)
{
- lineWidth = widget.getBorderStyle().getWidth();
+ borderWidth = widget.getBorderStyle().getWidth();
}
- PDRectangle paddingEdge = applyPadding(bbox, Math.max(1f, lineWidth));
- PDRectangle contentEdge = applyPadding(paddingEdge, Math.max(1f, lineWidth));
+ PDRectangle clipRect = applyPadding(bbox, Math.max(1f, borderWidth));
+ PDRectangle contentRect = applyPadding(clipRect, Math.max(1f, borderWidth));
contents.saveGraphicsState();
// add a clipping path to avoid overlapping with the border
- contents.addRect(paddingEdge.getLowerLeftX(), paddingEdge.getLowerLeftY(),
- paddingEdge.getWidth(), paddingEdge.getHeight());
- contents.clip();
+ if (borderWidth > 0)
+ {
+ contents.addRect(clipRect.getLowerLeftX(), clipRect.getLowerLeftY(),
+ clipRect.getWidth(), clipRect.getHeight());
+ contents.clip();
+ }
// start the text output
contents.beginText();
@@ -212,24 +214,33 @@ class AppearanceGeneratorHelper
PDFont font = field.getDefaultAppearanceString().getFont();
// calculate the fontSize (because 0 = autosize)
- float fontSize = calculateFontSize(font, contentEdge);
+ float fontSize = calculateFontSize(font, contentRect);
- // calculation of the vertical offset from where the text will be printed
- float verticalOffset = calculateVerticalOffset(paddingEdge, contentEdge, font, fontSize);
-
- float leftOffset;
+ // calculate the y-position of the baseline
+ float y;
+ if (field instanceof PDTextField && ((PDTextField) field).isMultiline())
+ {
+ float height = font.getBoundingBox().getHeight() / 1000 * fontSize;
+ y = contentRect.getUpperRightY() - height;
+ }
+ else
+ {
+ float minY = font.getBoundingBox().getLowerLeftY() / 1000 * fontSize;
+ y = Math.max(bbox.getHeight() / 2f + minY, 0);
+ }
// show the text
+ float leftOffset;
if (!isMultiLine())
{
// calculation of the horizontal offset from where the text will be printed
- leftOffset = calculateHorizontalOffset(contentEdge, font, fontSize);
- contents.newLineAtOffset(leftOffset, verticalOffset);
+ leftOffset = calculateHorizontalOffset(contentRect, font, fontSize);
+ contents.newLineAtOffset(leftOffset, y);
contents.showText(value);
}
else
{
- leftOffset = contentEdge.getLowerLeftX();
+ leftOffset = contentRect.getLowerLeftX();
PlainText textContent = new PlainText(value);
AppearanceStyle appearanceStyle = new AppearanceStyle();
appearanceStyle.setFont(font);
@@ -237,15 +248,15 @@ class AppearanceGeneratorHelper
// Adobe Acrobat uses the font's bounding box for the leading between the lines
appearanceStyle.setLeading(font.getBoundingBox().getHeight() /
- GLYPH_TO_PDF_SCALE * fontSize);
+ GLYPH_TO_PDF_SCALE * fontSize);
PlainTextFormatter formatter = new PlainTextFormatter
.Builder(contents)
.style(appearanceStyle)
.text(textContent)
- .width(contentEdge.getWidth())
+ .width(contentRect.getWidth())
.wrapLines(true)
- .initialOffset(leftOffset, verticalOffset)
+ .initialOffset(leftOffset, y)
.textAlign(field.getQ())
.build();
formatter.format();
@@ -304,46 +315,6 @@ class AppearanceGeneratorHelper
}
/**
- * Calculate the vertical start position for the text.
- *
- * @param paddingEdge the content edge
- * @param contentEdge the content edge
- * @param pdFont the font to use for formatting
- * @param fontSize the font size to use for formating
- * @return the vertical start position of the text
- * @throws IOException If there is an error calculating the text position.
- */
- private float calculateVerticalOffset(PDRectangle paddingEdge, PDRectangle contentEdge,
- PDFont pdFont, float fontSize) throws IOException
- {
- float verticalOffset;
- float capHeight = getCapHeight(pdFont, fontSize);
- float fontHeight = pdFont.getBoundingBox().getHeight() / GLYPH_TO_PDF_SCALE * fontSize;
-
- if (field instanceof PDTextField && ((PDTextField) field).isMultiline())
- {
- verticalOffset = contentEdge.getUpperRightY() - fontHeight;
- }
- else
- {
- // Acrobat shifts the value so it aligns to the bottom if
- // the font's caps are larger than the height of the paddingEdge
- if (capHeight > paddingEdge.getHeight())
- {
- verticalOffset = paddingEdge.getLowerLeftX()
- - pdFont.getFontDescriptor().getDescent() / GLYPH_TO_PDF_SCALE * fontSize;
- }
- else
- {
- verticalOffset = (paddingEdge.getHeight() - capHeight) /
- 2f + paddingEdge.getLowerLeftX();
- }
- }
-
- return verticalOffset;
- }
-
- /**
* Calculate the horizontal start position for the text.
*
* @param contentEdge the content edge
@@ -388,28 +359,6 @@ class AppearanceGeneratorHelper
}
/**
- * Get the capHeight for a font.
- *
- * @throws IOException in case the font information can not be retrieved.
- */
- private float getCapHeight(PDFont pdFont, float fontSize) throws IOException
- {
- final PDFontDescriptor fontDescriptor = pdFont.getFontDescriptor();
-
- // as the font descriptor might be null or the cap height might be 0
- // alternate calculation for the cap height
- if (fontDescriptor == null || fontDescriptor.getCapHeight() == 0)
- {
- // TODO: refine the calculation if needed
- return pdFont.getBoundingBox().getHeight() / GLYPH_TO_PDF_SCALE * fontSize * 0.7f;
- }
- else
- {
- return pdFont.getFontDescriptor().getCapHeight() / GLYPH_TO_PDF_SCALE * fontSize;
- }
- }
-
- /**
* Resolve the bounding box.
*
* @param fieldWidget the annotation widget.