pdfbox-commits mailing list archives

Site index · List index
Message view « Date » · « Thread »
Top « Date » · « Thread »
From til...@apache.org
Subject svn commit: r1851572 - in /pdfbox/branches/2.0/examples/src/main/java/org/apache/pdfbox/examples/interactive/form: CreateCheckBox.java CreateRadioButtons.java
Date Thu, 17 Jan 2019 18:52:48 GMT
Author: tilman
Date: Thu Jan 17 18:52:48 2019
New Revision: 1851572

URL: http://svn.apache.org/viewvc?rev=1851572&view=rev
Log:
PDFBOX-4434: Create flexible CheckBox and RadioButtons example

Added:
    pdfbox/branches/2.0/examples/src/main/java/org/apache/pdfbox/examples/interactive/form/CreateCheckBox.java
  (with props)
    pdfbox/branches/2.0/examples/src/main/java/org/apache/pdfbox/examples/interactive/form/CreateRadioButtons.java
  (with props)

Added: pdfbox/branches/2.0/examples/src/main/java/org/apache/pdfbox/examples/interactive/form/CreateCheckBox.java
URL: http://svn.apache.org/viewvc/pdfbox/branches/2.0/examples/src/main/java/org/apache/pdfbox/examples/interactive/form/CreateCheckBox.java?rev=1851572&view=auto
==============================================================================
--- pdfbox/branches/2.0/examples/src/main/java/org/apache/pdfbox/examples/interactive/form/CreateCheckBox.java
(added)
+++ pdfbox/branches/2.0/examples/src/main/java/org/apache/pdfbox/examples/interactive/form/CreateCheckBox.java
Thu Jan 17 18:52:48 2019
@@ -0,0 +1,183 @@
+/*
+ * Licensed to the Apache Software Foundation (ASF) under one or more
+ * contributor license agreements.  See the NOTICE file distributed with
+ * this work for additional information regarding copyright ownership.
+ * The ASF licenses this file to You under the Apache License, Version 2.0
+ * (the "License"); you may not use this file except in compliance with
+ * the License.  You may obtain a copy of the License at
+ *
+ *      http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+package org.apache.pdfbox.examples.interactive.form;
+
+import java.awt.geom.Rectangle2D;
+import java.io.IOException;
+import org.apache.pdfbox.cos.COSDictionary;
+import org.apache.pdfbox.cos.COSName;
+import org.apache.pdfbox.pdmodel.PDDocument;
+import org.apache.pdfbox.pdmodel.PDPage;
+import org.apache.pdfbox.pdmodel.PDPageContentStream;
+import org.apache.pdfbox.pdmodel.PDResources;
+import org.apache.pdfbox.pdmodel.common.PDRectangle;
+import org.apache.pdfbox.pdmodel.font.PDType1Font;
+import org.apache.pdfbox.pdmodel.graphics.color.PDColor;
+import org.apache.pdfbox.pdmodel.graphics.color.PDDeviceRGB;
+import org.apache.pdfbox.pdmodel.interactive.annotation.PDAnnotationWidget;
+import org.apache.pdfbox.pdmodel.interactive.annotation.PDAppearanceCharacteristicsDictionary;
+import org.apache.pdfbox.pdmodel.interactive.annotation.PDAppearanceDictionary;
+import org.apache.pdfbox.pdmodel.interactive.annotation.PDAppearanceEntry;
+import org.apache.pdfbox.pdmodel.interactive.annotation.PDAppearanceStream;
+import org.apache.pdfbox.pdmodel.interactive.annotation.PDBorderStyleDictionary;
+import org.apache.pdfbox.pdmodel.interactive.form.PDAcroForm;
+import org.apache.pdfbox.pdmodel.interactive.form.PDCheckBox;
+
+/**
+ * Example to create a checkbox.
+ *
+ * @author Tilman Hausherr
+ */
+public class CreateCheckBox
+{
+    public static void main(String arg[]) throws IOException
+    {
+        PDDocument document = new PDDocument();
+        PDPage page = new PDPage();
+        document.addPage(page);
+
+        PDAcroForm acroForm = new PDAcroForm(document);
+        document.getDocumentCatalog().setAcroForm(acroForm);
+
+        // if you want to see what Adobe does, activate this, open with Adobe
+        // save the file, and then open it with PDFDebugger
+        //acroForm.setNeedAppearances(true)
+
+        float x = 50;
+        float y = page.getMediaBox().getHeight() - 50;
+
+        PDRectangle rect = new PDRectangle(x, y, 20, 20);
+
+        PDCheckBox checkbox = new PDCheckBox(acroForm);
+        checkbox.setPartialName("MyCheckBox");
+        PDAnnotationWidget widget = checkbox.getWidgets().get(0);
+        widget.setPage(page);
+        widget.setRectangle(rect);
+        widget.setPrinted(true);
+
+        PDAppearanceCharacteristicsDictionary appearanceCharacteristics = new PDAppearanceCharacteristicsDictionary(new
COSDictionary());
+        appearanceCharacteristics.setBorderColour(new PDColor(new float[]{1, 0, 0}, PDDeviceRGB.INSTANCE));
+        appearanceCharacteristics.setBackground(new PDColor(new float[]{1, 1, 0}, PDDeviceRGB.INSTANCE));
+        // 8 = cross; 4 = checkmark; H = star; u = diamond; n = square, l = dot
+        appearanceCharacteristics.setNormalCaption("4");
+        widget.setAppearanceCharacteristics(appearanceCharacteristics);
+
+        PDBorderStyleDictionary borderStyleDictionary = new PDBorderStyleDictionary();
+        borderStyleDictionary.setWidth(1);
+        borderStyleDictionary.setStyle(PDBorderStyleDictionary.STYLE_SOLID);
+        widget.setBorderStyle(borderStyleDictionary);
+
+        PDAppearanceDictionary ap = new PDAppearanceDictionary();
+        widget.setAppearance(ap);
+        PDAppearanceEntry normalAppearance = ap.getNormalAppearance();
+
+        COSDictionary normalAppearanceDict = (COSDictionary) normalAppearance.getCOSObject();
+        normalAppearanceDict.setItem(COSName.Off, createRadioButtonAppearanceStream(document,
widget, false));
+        normalAppearanceDict.setItem(COSName.YES, createRadioButtonAppearanceStream(document,
widget, true));
+
+        // If we ever decide to implement a /D (down) appearance, just 
+        // replace the background colors c with c * 0.75
+        page.getAnnotations().add(checkbox.getWidgets().get(0));
+        acroForm.getFields().add(checkbox);
+
+        checkbox.check();
+
+        document.save("CheckBoxSample.pdf");
+        document.close();
+    }
+
+    private static PDAppearanceStream createRadioButtonAppearanceStream(
+            final PDDocument document, PDAnnotationWidget widget, boolean on) throws IOException
+    {
+        PDRectangle rect = widget.getRectangle();
+        PDAppearanceCharacteristicsDictionary appearanceCharacteristics;
+        PDAppearanceStream yesAP = new PDAppearanceStream(document);
+        yesAP.setBBox(new PDRectangle(rect.getWidth(), rect.getHeight()));
+        yesAP.setResources(new PDResources());
+        PDPageContentStream yesAPCS = new PDPageContentStream(document, yesAP);
+        appearanceCharacteristics = widget.getAppearanceCharacteristics();
+        PDColor backgroundColor = appearanceCharacteristics.getBackground();
+        PDColor borderColor = appearanceCharacteristics.getBorderColour();
+        float lineWidth = getLineWidth(widget);
+        yesAPCS.setLineWidth(lineWidth); // border style (dash) ignored
+        yesAPCS.setNonStrokingColor(backgroundColor);
+        yesAPCS.addRect(0, 0, rect.getWidth(), rect.getHeight());
+        yesAPCS.fill();
+        yesAPCS.setStrokingColor(borderColor);
+        yesAPCS.addRect(lineWidth / 2, lineWidth / 2, rect.getWidth() - lineWidth, rect.getHeight()
- lineWidth);
+        yesAPCS.stroke();
+        if (!on)
+        {
+            yesAPCS.close();
+            return yesAP;
+        }
+
+        yesAPCS.addRect(lineWidth, lineWidth, rect.getWidth() - lineWidth * 2, rect.getHeight()
- lineWidth * 2);
+        yesAPCS.clip();
+
+        String normalCaption = appearanceCharacteristics.getNormalCaption();
+        if (normalCaption == null)
+        {
+            normalCaption = "4"; // Adobe behaviour
+        }
+        if ("8".equals(normalCaption))
+        {
+            // Adobe paints a cross instead of using the Zapf Dingbats cross symbol
+            yesAPCS.setStrokingColor(0f);
+            yesAPCS.moveTo(lineWidth * 2, rect.getHeight() - lineWidth * 2);
+            yesAPCS.lineTo(rect.getWidth() - lineWidth * 2, lineWidth * 2);
+            yesAPCS.moveTo(rect.getWidth() - lineWidth * 2, rect.getHeight() - lineWidth
* 2);
+            yesAPCS.lineTo(lineWidth * 2, lineWidth * 2);
+            yesAPCS.stroke();
+        }
+        else
+        {
+            // The caption is not unicode, but the Zapf Dingbats code in the PDF
+            // Thus convert it back to unicode
+            // Assume that only the first character is used.
+            String name = PDType1Font.ZAPF_DINGBATS.codeToName(normalCaption.codePointAt(0));
+            String unicode = PDType1Font.ZAPF_DINGBATS.getGlyphList().toUnicode(name);
+            Rectangle2D bounds = PDType1Font.ZAPF_DINGBATS.getPath(name).getBounds2D();
+            float size = (float) Math.min(bounds.getWidth(), bounds.getHeight()) / 1000;
+            // assume that checkmark has square size
+            // the calculations approximate what Adobe is doing, i.e. put the glyph in the
middle
+            float fontSize = (rect.getWidth() - lineWidth * 2) / size * 0.6666f;
+            float xOffset = (float) (rect.getWidth() - (bounds.getWidth()) / 1000 * fontSize)
/ 2;
+            xOffset -= bounds.getX() / 1000 * fontSize;
+            float yOffset = (float) (rect.getHeight() - (bounds.getHeight()) / 1000 * fontSize)
/ 2;
+            yOffset -= bounds.getY() / 1000 * fontSize;
+            yesAPCS.setNonStrokingColor(0f);
+            yesAPCS.beginText();
+            yesAPCS.setFont(PDType1Font.ZAPF_DINGBATS, fontSize);
+            yesAPCS.newLineAtOffset(xOffset, yOffset);
+            yesAPCS.showText(unicode);
+            yesAPCS.endText();
+        }
+        yesAPCS.close();
+        return yesAP;
+    }
+
+    static float getLineWidth(PDAnnotationWidget widget)
+    {
+        PDBorderStyleDictionary bs = widget.getBorderStyle();
+        if (bs != null)
+        {
+            return bs.getWidth();
+        }
+        return 1;
+    }
+}

Propchange: pdfbox/branches/2.0/examples/src/main/java/org/apache/pdfbox/examples/interactive/form/CreateCheckBox.java
------------------------------------------------------------------------------
    svn:eol-style = native

Added: pdfbox/branches/2.0/examples/src/main/java/org/apache/pdfbox/examples/interactive/form/CreateRadioButtons.java
URL: http://svn.apache.org/viewvc/pdfbox/branches/2.0/examples/src/main/java/org/apache/pdfbox/examples/interactive/form/CreateRadioButtons.java?rev=1851572&view=auto
==============================================================================
--- pdfbox/branches/2.0/examples/src/main/java/org/apache/pdfbox/examples/interactive/form/CreateRadioButtons.java
(added)
+++ pdfbox/branches/2.0/examples/src/main/java/org/apache/pdfbox/examples/interactive/form/CreateRadioButtons.java
Thu Jan 17 18:52:48 2019
@@ -0,0 +1,170 @@
+/*
+ * Licensed to the Apache Software Foundation (ASF) under one or more
+ * contributor license agreements.  See the NOTICE file distributed with
+ * this work for additional information regarding copyright ownership.
+ * The ASF licenses this file to You under the Apache License, Version 2.0
+ * (the "License"); you may not use this file except in compliance with
+ * the License.  You may obtain a copy of the License at
+ *
+ *      http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+package org.apache.pdfbox.examples.interactive.form;
+
+import java.io.IOException;
+import java.util.ArrayList;
+import java.util.Arrays;
+import java.util.List;
+import org.apache.pdfbox.cos.COSDictionary;
+import org.apache.pdfbox.cos.COSName;
+import org.apache.pdfbox.pdmodel.PDDocument;
+import org.apache.pdfbox.pdmodel.PDPage;
+import org.apache.pdfbox.pdmodel.PDPageContentStream;
+import org.apache.pdfbox.pdmodel.common.PDRectangle;
+import org.apache.pdfbox.pdmodel.font.PDType1Font;
+import org.apache.pdfbox.pdmodel.graphics.color.PDColor;
+import org.apache.pdfbox.pdmodel.graphics.color.PDDeviceRGB;
+import org.apache.pdfbox.pdmodel.interactive.annotation.PDAnnotationWidget;
+import org.apache.pdfbox.pdmodel.interactive.annotation.PDAppearanceCharacteristicsDictionary;
+import org.apache.pdfbox.pdmodel.interactive.annotation.PDAppearanceDictionary;
+import org.apache.pdfbox.pdmodel.interactive.annotation.PDAppearanceEntry;
+import org.apache.pdfbox.pdmodel.interactive.annotation.PDAppearanceStream;
+import org.apache.pdfbox.pdmodel.interactive.annotation.PDBorderStyleDictionary;
+import org.apache.pdfbox.pdmodel.interactive.form.PDAcroForm;
+import org.apache.pdfbox.pdmodel.interactive.form.PDRadioButton;
+
+/**
+ * Example to create radio buttons.
+ *
+ * @author Tilman Hausherr
+ */
+public class CreateRadioButtons
+{
+    public static void main(String[] args) throws IOException
+    {
+        PDDocument document = new PDDocument();
+        PDPage page = new PDPage(PDRectangle.A4);
+        document.addPage(page);
+        PDAcroForm acroForm = new PDAcroForm(document);
+
+        // if you want to see what Adobe does, activate this, open with Adobe
+        // save the file, and then open it with PDFDebugger
+
+        //acroForm.setNeedAppearances(true)
+
+        document.getDocumentCatalog().setAcroForm(acroForm);
+        List<String> options = Arrays.asList("a", "b", "c");
+        PDRadioButton radioButton = new PDRadioButton(acroForm);
+        radioButton.setPartialName("MyRadioButton");
+        radioButton.setExportValues(options);
+
+        PDAppearanceCharacteristicsDictionary appearanceCharacteristics = new PDAppearanceCharacteristicsDictionary(new
COSDictionary());
+        appearanceCharacteristics.setBorderColour(new PDColor(new float[] { 1, 0, 0 }, PDDeviceRGB.INSTANCE));
+        appearanceCharacteristics.setBackground(new PDColor(new float[]{0, 1, 0.3f}, PDDeviceRGB.INSTANCE));
+        // no caption => round
+        // with caption => see checkbox example
+
+        List<PDAnnotationWidget> widgets = new ArrayList<PDAnnotationWidget>();
+        for (int i = 0; i < options.size(); i++)
+        {
+            PDAnnotationWidget widget = new PDAnnotationWidget();
+            widget.setRectangle(new PDRectangle(30, PDRectangle.A4.getHeight() - 40 - i *
35, 30, 30));
+            widget.setAppearanceCharacteristics(appearanceCharacteristics);
+            PDBorderStyleDictionary borderStyleDictionary = new PDBorderStyleDictionary();
+            borderStyleDictionary.setWidth(2);
+            borderStyleDictionary.setStyle(PDBorderStyleDictionary.STYLE_SOLID);
+            widget.setBorderStyle(borderStyleDictionary);
+            widget.setPage(page);
+
+            COSDictionary apNDict = new COSDictionary();
+            apNDict.setItem(COSName.Off, createCheckBoxAppearanceStream(document, widget,
false));
+            apNDict.setItem(options.get(i), createCheckBoxAppearanceStream(document, widget,
true));
+
+            PDAppearanceDictionary appearance = new PDAppearanceDictionary();
+            PDAppearanceEntry appearanceNEntry = new PDAppearanceEntry(apNDict);
+            appearance.setNormalAppearance(appearanceNEntry);
+            widget.setAppearance(appearance);
+            widget.setAppearanceState("Off"); // don't forget this, or button will be invisible
+            widgets.add(widget);
+            page.getAnnotations().add(widget);
+        }
+        radioButton.setWidgets(widgets);
+
+        acroForm.getFields().add(radioButton);
+
+        // Set the texts
+        PDPageContentStream contents = new PDPageContentStream(document, page);
+        for (int i = 0; i < options.size(); i++)
+        {
+            contents.beginText();
+            contents.setFont(PDType1Font.HELVETICA, 15);
+            contents.newLineAtOffset(70, PDRectangle.A4.getHeight() - 30 - i * 35);
+            contents.showText(options.get(i));
+            contents.endText();
+        }
+        contents.close();
+
+        radioButton.setValue("c");
+
+        document.save("RadioButtonsSample.pdf");
+        document.close();
+    }
+
+    private static PDAppearanceStream createCheckBoxAppearanceStream(
+            final PDDocument document, PDAnnotationWidget widget, boolean on) throws IOException
+    {
+        PDRectangle rect = widget.getRectangle();
+        PDAppearanceStream onAP = new PDAppearanceStream(document);
+        onAP.setBBox(new PDRectangle(rect.getWidth(), rect.getHeight()));
+        PDPageContentStream onAPCS = new PDPageContentStream(document, onAP);
+
+        PDAppearanceCharacteristicsDictionary appearanceCharacteristics = widget.getAppearanceCharacteristics();
+        PDColor backgroundColor = appearanceCharacteristics.getBackground();
+        PDColor borderColor = appearanceCharacteristics.getBorderColour();
+        float lineWidth = getLineWidth(widget);
+        onAPCS.setLineWidth(lineWidth); // border style (dash) ignored
+        onAPCS.setNonStrokingColor(backgroundColor);
+        float radius = Math.min(rect.getWidth() / 2, rect.getHeight() / 2);
+        drawCircle(onAPCS, rect.getWidth() / 2, rect.getHeight() / 2, radius);
+        onAPCS.fill();
+        onAPCS.setStrokingColor(borderColor);
+        drawCircle(onAPCS, rect.getWidth() / 2, rect.getHeight() / 2, radius - lineWidth
/ 2);
+        onAPCS.stroke();
+        if (on)
+        {
+            onAPCS.setNonStrokingColor(0f);
+            drawCircle(onAPCS, rect.getWidth() / 2, rect.getHeight() / 2, (radius - lineWidth)
/ 2);
+            onAPCS.fill();
+        }
+
+        onAPCS.close();
+        return onAP;
+    }
+
+    static float getLineWidth(PDAnnotationWidget widget)
+    {
+        PDBorderStyleDictionary bs = widget.getBorderStyle();
+        if (bs != null)
+        {
+            return bs.getWidth();
+        }
+        return 1;
+    }
+
+    static void drawCircle(PDPageContentStream cs, float x, float y, float r) throws IOException
+    {
+        // http://stackoverflow.com/a/2007782/535646
+        float magic = r * 0.551784f;
+        cs.moveTo(x, y + r);
+        cs.curveTo(x + magic, y + r, x + r, y + magic, x + r, y);
+        cs.curveTo(x + r, y - magic, x + magic, y - r, x, y - r);
+        cs.curveTo(x - magic, y - r, x - r, y - magic, x - r, y);
+        cs.curveTo(x - r, y + magic, x - magic, y + r, x, y + r);
+        cs.closePath();
+    }
+}

Propchange: pdfbox/branches/2.0/examples/src/main/java/org/apache/pdfbox/examples/interactive/form/CreateRadioButtons.java
------------------------------------------------------------------------------
    svn:eol-style = native



Mime
View raw message