# AcroFormDefaultsProcessor.java

    /*
     * 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.pdmodel.fixup.processor;

    import org.apache.pdfbox.cos.COSDictionary;
    import org.apache.pdfbox.cos.COSName;
    import org.apache.pdfbox.pdmodel.PDDocument;
    import org.apache.pdfbox.pdmodel.PDResources;
    import org.apache.pdfbox.pdmodel.font.PDType1Font;
    import org.apache.pdfbox.pdmodel.font.Standard14Fonts.FontName;
    import org.apache.pdfbox.pdmodel.interactive.form.PDAcroForm;

    /**
     * Verify and ensure default resources for /AcroForm.
     *
     * <ul>
     *   <li>a default appearance string is defined</li>
     *   <li>default resources are defined</li>
     *   <li>Helvetica as <code>/Helv</code> and Zapf Dingbats as <code>ZaDb</code> are included.
     *       ZaDb is required for most check boxes and radio buttons</li>
     * </ul>
     *
     */
    public class AcroFormDefaultsProcessor extends AbstractProcessor
    {
        public AcroFormDefaultsProcessor(PDDocument document)
        {
            super(document);
        }

        @Override
        public void process() {
            /*
             * Get the AcroForm in it's current state.
             *
             * Also note: getAcroForm() applies a default fixup which this processor
             * is part of. So keep the null parameter otherwise this will end
             * in an endless recursive call
             */
            PDAcroForm acroForm = document.getDocumentCatalog().getAcroForm(null);
            if (acroForm != null)
            {
                verifyOrCreateDefaults(acroForm);
            }
        }

       /*
         * Verify that there are default entries for required
         * properties.
         *
         * If these are missing create default entries similar to
         * Adobe Reader / Adobe Acrobat
         *
         */
        private void verifyOrCreateDefaults(PDAcroForm acroForm)
        {
            final String adobeDefaultAppearanceString = "/Helv 0 Tf 0 g ";

            // DA entry is required
            if (acroForm.getDefaultAppearance().length() == 0)
            {
                acroForm.setDefaultAppearance(adobeDefaultAppearanceString);
                acroForm.getCOSObject().setNeedToBeUpdated(true);
            }

            // DR entry is required
            PDResources defaultResources = acroForm.getDefaultResources();
            if (defaultResources == null)
            {
                defaultResources = new PDResources();
                acroForm.setDefaultResources(defaultResources);
                acroForm.getCOSObject().setNeedToBeUpdated(true);
            }

            // PDFBOX-3732: Adobe Acrobat uses Helvetica as a default font and
            // stores that under the name '/Helv' in the resources dictionary
            // Zapf Dingbats is included per default for check boxes and
            // radio buttons as /ZaDb.
            // PDFBOX-4393: the two fonts are added by Adobe when signing
            // and this breaks a previous signature. (Might be an Adobe bug)
            COSDictionary fontDict = defaultResources.getCOSObject().getCOSDictionary(COSName.FONT);
            if (fontDict == null)
            {
                fontDict = new COSDictionary();
                defaultResources.getCOSObject().setItem(COSName.FONT, fontDict);
            }
            if (!fontDict.containsKey(COSName.HELV))
            {
                defaultResources.put(COSName.HELV, new PDType1Font(FontName.HELVETICA));
                defaultResources.getCOSObject().setNeedToBeUpdated(true);
                fontDict.setNeedToBeUpdated(true);
            }
            if (!fontDict.containsKey(COSName.ZA_DB))
            {
                defaultResources.put(COSName.ZA_DB, new PDType1Font(FontName.ZAPF_DINGBATS));
                defaultResources.getCOSObject().setNeedToBeUpdated(true);
                fontDict.setNeedToBeUpdated(true);
            }
        }
    }