![JAR search and dependency download from the Maven repository](/logo.png)
com.itextpdf.forms.form.renderer.CheckBoxRenderer Maven / Gradle / Ivy
/*
This file is part of the iText (R) project.
Copyright (c) 1998-2024 Apryse Group NV
Authors: Apryse Software.
This program is offered under a commercial and under the AGPL license.
For commercial licensing, contact us at https://itextpdf.com/sales. For AGPL licensing, see below.
AGPL licensing:
This program is free software: you can redistribute it and/or modify
it under the terms of the GNU Affero General Public License as published by
the Free Software Foundation, either version 3 of the License, or
(at your option) any later version.
This program is distributed in the hope that it will be useful,
but WITHOUT ANY WARRANTY; without even the implied warranty of
MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
GNU Affero General Public License for more details.
You should have received a copy of the GNU Affero General Public License
along with this program. If not, see .
*/
package com.itextpdf.forms.form.renderer;
import com.itextpdf.forms.fields.CheckBoxFormFieldBuilder;
import com.itextpdf.forms.fields.PdfButtonFormField;
import com.itextpdf.forms.fields.PdfFormAnnotation;
import com.itextpdf.forms.fields.PdfFormCreator;
import com.itextpdf.forms.fields.properties.CheckBoxType;
import com.itextpdf.forms.form.FormProperty;
import com.itextpdf.forms.form.element.CheckBox;
import com.itextpdf.forms.form.renderer.checkboximpl.HtmlCheckBoxRenderingStrategy;
import com.itextpdf.forms.form.renderer.checkboximpl.ICheckBoxRenderingStrategy;
import com.itextpdf.forms.form.renderer.checkboximpl.PdfACheckBoxRenderingStrategy;
import com.itextpdf.forms.form.renderer.checkboximpl.PdfCheckBoxRenderingStrategy;
import com.itextpdf.forms.util.BorderStyleUtil;
import com.itextpdf.forms.util.FormFieldRendererUtil;
import com.itextpdf.kernel.geom.Rectangle;
import com.itextpdf.kernel.pdf.IConformanceLevel;
import com.itextpdf.kernel.pdf.PdfAConformanceLevel;
import com.itextpdf.kernel.pdf.PdfDocument;
import com.itextpdf.kernel.pdf.PdfPage;
import com.itextpdf.kernel.pdf.canvas.PdfCanvas;
import com.itextpdf.kernel.pdf.tagutils.TagTreePointer;
import com.itextpdf.layout.borders.Border;
import com.itextpdf.layout.element.Paragraph;
import com.itextpdf.layout.layout.LayoutContext;
import com.itextpdf.layout.properties.Background;
import com.itextpdf.layout.properties.BoxSizingPropertyValue;
import com.itextpdf.layout.properties.HorizontalAlignment;
import com.itextpdf.layout.properties.Property;
import com.itextpdf.layout.properties.RenderingMode;
import com.itextpdf.layout.properties.TextAlignment;
import com.itextpdf.layout.properties.UnitValue;
import com.itextpdf.layout.properties.VerticalAlignment;
import com.itextpdf.layout.renderer.DrawContext;
import com.itextpdf.layout.renderer.IRenderer;
import com.itextpdf.layout.renderer.ParagraphRenderer;
import java.util.Map;
/**
* The {@link AbstractFormFieldRenderer} implementation for checkboxes.
*/
public class CheckBoxRenderer extends AbstractFormFieldRenderer {
// 1px
public static final float DEFAULT_BORDER_WIDTH = 0.75F;
// 11px
private static final float DEFAULT_SIZE = 8.25F;
/**
* Creates a new {@link CheckBoxRenderer} instance.
*
* @param modelElement the model element
*/
public CheckBoxRenderer(CheckBox modelElement) {
super(modelElement);
this.setProperty(Property.VERTICAL_ALIGNMENT, VerticalAlignment.MIDDLE);
}
/**
* {@inheritDoc}
*/
@Override
public IRenderer getNextRenderer() {
return new CheckBoxRenderer((CheckBox) modelElement);
}
/**
* Gets the rendering mode of the checkbox.
*
* @return the rendering mode of the checkbox
*/
public RenderingMode getRenderingMode() {
final RenderingMode renderingMode = this.getProperty(Property.RENDERING_MODE);
if (renderingMode != null) {
return renderingMode;
}
return RenderingMode.DEFAULT_LAYOUT_MODE;
}
/**
* Returns whether or not the checkbox is in PDF/A mode.
*
* @return true if the checkbox is in PDF/A mode, false otherwise
*
* @deprecated since 8.0.4 will be removed
*/
@Deprecated
public boolean isPdfA() {
IConformanceLevel conformanceLevel = this.getProperty(FormProperty.FORM_CONFORMANCE_LEVEL);
return conformanceLevel instanceof PdfAConformanceLevel;
}
/**
* Gets the checkBoxType.
*
* @return the checkBoxType
*/
public CheckBoxType getCheckBoxType() {
if (this.hasProperty(FormProperty.FORM_CHECKBOX_TYPE)) {
return (CheckBoxType) this.getProperty(FormProperty.FORM_CHECKBOX_TYPE);
}
return CheckBoxType.CROSS;
}
/**
* creates a ICheckBoxRenderingStrategy based on the current settings.
*
* @return the ICheckBoxRenderingStrategy
*/
public ICheckBoxRenderingStrategy createCheckBoxRenderStrategy() {
// html rendering is PDFA compliant this means we don't have to check if its PDFA.
ICheckBoxRenderingStrategy renderingStrategy;
boolean isConformantPdfDocument =
this.getProperty(FormProperty.FORM_CONFORMANCE_LEVEL) != null;
if (getRenderingMode() == RenderingMode.HTML_MODE) {
renderingStrategy = new HtmlCheckBoxRenderingStrategy();
} else if (getRenderingMode() == RenderingMode.DEFAULT_LAYOUT_MODE && isConformantPdfDocument) {
renderingStrategy = new PdfACheckBoxRenderingStrategy();
} else {
renderingStrategy = new PdfCheckBoxRenderingStrategy();
}
return renderingStrategy;
}
/**
* {@inheritDoc}
*/
@Override
public void drawBackground(DrawContext drawContext) {
// Do not draw background here. It will be drawn in flat renderer.
}
/**
* {@inheritDoc}
*/
@Override
public void drawBorder(DrawContext drawContext) {
// Do not draw border here. It will be drawn in flat renderer.
}
/**
* {@inheritDoc}
*/
@Override
protected Rectangle applyBorderBox(Rectangle rect, Border[] borders, boolean reverse) {
// Do not apply borders here, they will be applied in flat renderer
return rect;
}
/**
* Defines whether the box is checked or not.
*
* @return the default value of the checkbox field
*/
public boolean isBoxChecked() {
return Boolean.TRUE.equals(this.getProperty(FormProperty.FORM_FIELD_CHECKED));
}
/**
* Adjusts the field layout.
*
* @param layoutContext layout context
*/
@Override
protected void adjustFieldLayout(LayoutContext layoutContext) {
// We don't need any layout adjustments
}
/**
* Applies given paddings to the given rectangle.
*
* Checkboxes don't support setting of paddings as they are always centered.
* So that this method returns the rectangle as is.
*
* @param rect a rectangle paddings will be applied on.
* @param paddings the paddings to be applied on the given rectangle
* @param reverse indicates whether paddings will be applied
* inside (in case of false) or outside (in case of true) the rectangle.
*
* @return The rectangle NOT modified by the paddings.
*/
@Override
protected Rectangle applyPaddings(Rectangle rect, UnitValue[] paddings, boolean reverse) {
return rect;
}
/**
* Creates a flat renderer for the checkbox.
*
* @return an IRenderer object for the flat renderer
*/
@Override
public IRenderer createFlatRenderer() {
final UnitValue heightUV = getPropertyAsUnitValue(Property.HEIGHT);
final UnitValue widthUV = getPropertyAsUnitValue(Property.WIDTH);
// if it is a percentage value, we need to calculate the actual value but we
// don't have the parent's width yet, so we will take the default value
float height = DEFAULT_SIZE;
if (heightUV != null && heightUV.isPointValue()) {
height = heightUV.getValue();
}
float width = DEFAULT_SIZE;
if (widthUV != null && widthUV.isPointValue()) {
width = widthUV.getValue();
}
final Paragraph paragraph = new Paragraph().setWidth(width).setHeight(height).setMargin(0)
.setVerticalAlignment(VerticalAlignment.MIDDLE)
.setHorizontalAlignment(HorizontalAlignment.CENTER)
.setTextAlignment(TextAlignment.CENTER);
paragraph.setProperty(Property.BOX_SIZING, this.getProperty(Property.BOX_SIZING));
modelElement.setProperty(Property.RENDERING_MODE, this.getProperty(Property.RENDERING_MODE));
paragraph.setBorder(this.getProperty(Property.BORDER));
paragraph.setProperty(Property.BACKGROUND, this.getProperty(Property.BACKGROUND));
//In html 2 pdf rendering the boxes height width ratio is always 1:1
// with chrome taking the max of the two as the size of the box
if (getRenderingMode() == RenderingMode.HTML_MODE) {
paragraph.setWidth(Math.max(width, height));
paragraph.setHeight(Math.max(width, height));
}
return new FlatParagraphRenderer(paragraph);
}
/**
* {@inheritDoc}
*/
@Override
protected void applyAcroField(DrawContext drawContext) {
final String name = getModelId();
final PdfDocument doc = drawContext.getDocument();
final Rectangle area = flatRenderer.getOccupiedArea().getBBox().clone();
final Map properties = FormFieldRendererUtil.removeProperties(this.modelElement);
final PdfPage page = doc.getPage(occupiedArea.getPageNumber());
final CheckBoxFormFieldBuilder builder = new CheckBoxFormFieldBuilder(doc, name).setWidgetRectangle(area)
.setGenericConformanceLevel(this.getProperty(FormProperty.FORM_CONFORMANCE_LEVEL));
if (this.hasProperty(FormProperty.FORM_CHECKBOX_TYPE)) {
builder.setCheckType((CheckBoxType) this.getProperty(FormProperty.FORM_CHECKBOX_TYPE));
}
final PdfButtonFormField checkBox = builder.createCheckBox();
checkBox.disableFieldRegeneration();
BorderStyleUtil.applyBorderProperty(this, checkBox.getFirstFormAnnotation());
final Background background = this.modelElement.getProperty(Property.BACKGROUND);
if (background != null) {
checkBox.getFirstFormAnnotation().setBackgroundColor(background.getColor());
}
checkBox.setValue(PdfFormAnnotation.ON_STATE_VALUE);
if (!isBoxChecked()) {
checkBox.setValue(PdfFormAnnotation.OFF_STATE_VALUE);
}
applyAccessibilityProperties(checkBox, doc);
checkBox.getFirstFormAnnotation().setFormFieldElement((CheckBox) modelElement);
checkBox.enableFieldRegeneration();
PdfFormCreator.getAcroForm(doc, true).addField(checkBox, page);
FormFieldRendererUtil.reapplyProperties(modelElement, properties);
}
/**
* {@inheritDoc}
*/
@Override
protected boolean isLayoutBasedOnFlatRenderer() {
return false;
}
/**
* A flat renderer for the checkbox.
*/
protected class FlatParagraphRenderer extends ParagraphRenderer {
/**
* Creates a new {@link FlatParagraphRenderer} instance.
*
* @param modelElement the model element
*/
public FlatParagraphRenderer(Paragraph modelElement) {
super(modelElement);
}
/**
* {@inheritDoc}
*/
@Override
public void drawChildren(DrawContext drawContext) {
final Rectangle rectangle = this.getInnerAreaBBox().clone();
PdfCanvas canvas = drawContext.getCanvas();
boolean isTaggingEnabled = drawContext.isTaggingEnabled();
if (isTaggingEnabled) {
TagTreePointer tp = drawContext.getDocument().getTagStructureContext().getAutoTaggingPointer();
canvas.openTag(tp.getTagReference());
}
createCheckBoxRenderStrategy().drawCheckBoxContent(drawContext, CheckBoxRenderer.this, rectangle);
if (isTaggingEnabled) {
canvas.closeTag();
}
}
}
}
© 2015 - 2025 Weber Informatics LLC | Privacy Policy