mirror of
				https://github.com/JakubMelka/PDF4QT.git
				synced 2025-06-05 21:59:17 +02:00 
			
		
		
		
	XFA: checkbox and image edit drawing
This commit is contained in:
		| @@ -9715,6 +9715,7 @@ private: | ||||
|         PDFInteger hintTextMaxChars = 0; | ||||
|         PDFInteger hintFloatFracDigits = 2; | ||||
|         PDFInteger hintFloatLeadDigits = -1; | ||||
|         xfa::XFA_BaseNode::ASPECT hintImageAspect = xfa::XFA_BaseNode::ASPECT::Fit; | ||||
|         bool hintTextHtml = false; | ||||
|     }; | ||||
|  | ||||
| @@ -9791,6 +9792,18 @@ private: | ||||
|                         size_t paragraphSettingsIndex, | ||||
|                         QPainter* painter); | ||||
|  | ||||
|     void drawUiCheckButton(const xfa::XFA_checkButton* checkButton, | ||||
|                            const NodeValue& value, | ||||
|                            QRectF nominalExtentArea, | ||||
|                            QPainter* painter); | ||||
|  | ||||
|     void drawUiImageEdit(const xfa::XFA_imageEdit* imageEdit, | ||||
|                          const NodeValue& value, | ||||
|                          QList<PDFRenderError>& errors, | ||||
|                          QRectF nominalExtentArea, | ||||
|                          size_t paragraphSettingsIndex, | ||||
|                          QPainter* painter); | ||||
|  | ||||
|     xfa::XFA_Node<xfa::XFA_template> m_template; | ||||
|     const PDFDocument* m_document; | ||||
|     PDFForm* m_form; | ||||
| @@ -11792,6 +11805,7 @@ void PDFXFAEngineImpl::drawItemValue(const xfa::XFA_value* value, | ||||
|             { | ||||
|                 nodeValue.emplace(); | ||||
|                 nodeValue->value = std::move(imageValue); | ||||
|                 nodeValue->hintImageAspect = image->getAspect(); | ||||
|             } | ||||
|             else | ||||
|             { | ||||
| @@ -11967,17 +11981,17 @@ void PDFXFAEngineImpl::drawUi(const xfa::XFA_ui* ui, | ||||
|  | ||||
|     if (ui) | ||||
|     { | ||||
|         barcode = ui->getBarcode(); | ||||
|         button = ui->getButton(); | ||||
|         barcode = ui->getBarcode(); // TODO: implement | ||||
|         button = ui->getButton(); // TODO: implement | ||||
|         checkButton = ui->getCheckButton(); | ||||
|         choiceList = ui->getChoiceList(); | ||||
|         dateTimeEdit = ui->getDateTimeEdit(); | ||||
|         choiceList = ui->getChoiceList(); // TODO: implement | ||||
|         dateTimeEdit = ui->getDateTimeEdit(); // TODO: implement | ||||
|         defaultUi = ui->getDefaultUi(); | ||||
|         imageEdit = ui->getImageEdit(); | ||||
|         numericEdit = ui->getNumericEdit(); | ||||
|         passwordEdit = ui->getPasswordEdit(); | ||||
|         signature = ui->getSignature(); | ||||
|         textEdit = ui->getTextEdit(); | ||||
|         numericEdit = ui->getNumericEdit(); // TODO: implement | ||||
|         passwordEdit = ui->getPasswordEdit(); // TODO: implement | ||||
|         signature = ui->getSignature(); // TODO: implement | ||||
|         textEdit = ui->getTextEdit(); // TODO: implement | ||||
|     } | ||||
|  | ||||
|     const bool isNonDefaultUi = barcode || button || checkButton || choiceList || | ||||
| @@ -11989,6 +12003,14 @@ void PDFXFAEngineImpl::drawUi(const xfa::XFA_ui* ui, | ||||
|     { | ||||
|         drawUiTextEdit(textEdit, value, errors, nominalExtentArea, paragraphSettingsIndex, painter); | ||||
|     } | ||||
|     else if (checkButton || (isDefaultUi && value.value.type() == QVariant::Bool)) | ||||
|     { | ||||
|         drawUiCheckButton(checkButton, value, nominalExtentArea, painter); | ||||
|     } | ||||
|     else if (imageEdit || (isDefaultUi && value.value.type() == QVariant::Image)) | ||||
|     { | ||||
|         drawUiImageEdit(imageEdit, value, errors, nominalExtentArea, paragraphSettingsIndex, painter); | ||||
|     } | ||||
|  | ||||
|     // TODO: implement all ui | ||||
| } | ||||
| @@ -12135,6 +12157,202 @@ void PDFXFAEngineImpl::drawUiTextEdit(const xfa::XFA_textEdit* textEdit, | ||||
|     } | ||||
| } | ||||
|  | ||||
| void PDFXFAEngineImpl::drawUiCheckButton(const xfa::XFA_checkButton* checkButton, | ||||
|                                          const NodeValue& value, | ||||
|                                          QRectF nominalExtentArea, | ||||
|                                          QPainter* painter) | ||||
| { | ||||
|     QRectF nominalExtent = nominalExtentArea; | ||||
|     QRectF nominalContentArea = nominalExtent; | ||||
|     QMarginsF contentMargins = checkButton ? createMargin(checkButton->getMargin()) : QMarginsF(); | ||||
|     nominalContentArea = nominalExtent.marginsRemoved(contentMargins); | ||||
|  | ||||
|     PDFReal markSize = xfa::XFA_Measurement(10.0, xfa::XFA_Measurement::Type::pt).getValuePt(nullptr); | ||||
|     xfa::XFA_BaseNode::SHAPE shape = xfa::XFA_BaseNode::SHAPE::Square; | ||||
|     xfa::XFA_BaseNode::MARK mark = xfa::XFA_BaseNode::MARK::Default; | ||||
|  | ||||
|     if (checkButton) | ||||
|     { | ||||
|         // We ignore border for check buttons | ||||
|         markSize = checkButton->getSize().getValuePt(nullptr); | ||||
|         shape = checkButton->getShape(); | ||||
|         mark = checkButton->getMark(); | ||||
|     } | ||||
|  | ||||
|     QRectF checkBoxRect = nominalContentArea; | ||||
|     checkBoxRect.setSize(QSizeF(markSize, markSize)); | ||||
|     checkBoxRect.moveCenter(nominalContentArea.center()); | ||||
|  | ||||
|     QPen pen(Qt::black); | ||||
|     pen.setWidthF(1.0); | ||||
|     painter->setPen(pen); | ||||
|     painter->setBrush(Qt::NoBrush); | ||||
|  | ||||
|     switch (shape) | ||||
|     { | ||||
|         case pdf::xfa::XFA_BaseNode::SHAPE::Square: | ||||
|             painter->drawRect(checkBoxRect); | ||||
|             break; | ||||
|         case pdf::xfa::XFA_BaseNode::SHAPE::Round: | ||||
|             painter->drawEllipse(checkBoxRect); | ||||
|             break; | ||||
|     } | ||||
|  | ||||
|     if (value.value.toBool()) | ||||
|     { | ||||
|         switch (mark) | ||||
|         { | ||||
|             case pdf::xfa::XFA_BaseNode::MARK::Default: | ||||
|             { | ||||
|                 switch (shape) | ||||
|                 { | ||||
|                     case pdf::xfa::XFA_BaseNode::SHAPE::Square: | ||||
|                         painter->fillRect(checkBoxRect, Qt::black); | ||||
|                         break; | ||||
|                     case pdf::xfa::XFA_BaseNode::SHAPE::Round: | ||||
|                     { | ||||
|                         QPainterPath path; | ||||
|                         path.addEllipse(checkBoxRect); | ||||
|                         painter->fillPath(path, Qt::black); | ||||
|                         break; | ||||
|                     } | ||||
|                 } | ||||
|                 break; | ||||
|             } | ||||
|  | ||||
|             case pdf::xfa::XFA_BaseNode::MARK::Check: | ||||
|             { | ||||
|                 PDFReal starSize = markSize * 0.9; | ||||
|  | ||||
|                 QPainterPath path; | ||||
|                 path.addText(QPointF(0, 0), QFont("Arial", starSize), "✓"); | ||||
|                 path.translate(checkBoxRect.center() - path.boundingRect().center()); | ||||
|                 painter->drawPath(path); | ||||
|                 break; | ||||
|             } | ||||
|  | ||||
|             case pdf::xfa::XFA_BaseNode::MARK::Circle: | ||||
|             { | ||||
|                 QPainterPath path; | ||||
|                 path.addEllipse(checkBoxRect); | ||||
|                 painter->fillPath(path, Qt::black); | ||||
|                 break; | ||||
|             } | ||||
|  | ||||
|             case pdf::xfa::XFA_BaseNode::MARK::Cross: | ||||
|             { | ||||
|                 painter->drawLine(checkBoxRect.topLeft(), checkBoxRect.bottomRight()); | ||||
|                 painter->drawLine(checkBoxRect.bottomLeft(), checkBoxRect.topRight()); | ||||
|                 break; | ||||
|             } | ||||
|  | ||||
|             case pdf::xfa::XFA_BaseNode::MARK::Diamond: | ||||
|             { | ||||
|                 PDFReal diamondSize = markSize * 0.4; | ||||
|  | ||||
|                 QPainterPath path; | ||||
|                 path.moveTo(0, -diamondSize); | ||||
|                 path.lineTo(diamondSize, 0); | ||||
|                 path.lineTo(0, diamondSize); | ||||
|                 path.lineTo(-diamondSize, 0); | ||||
|                 path.closeSubpath(); | ||||
|                 path.translate(checkBoxRect.center()); | ||||
|                 painter->fillPath(path, Qt::black); | ||||
|                 break; | ||||
|             } | ||||
|  | ||||
|             case pdf::xfa::XFA_BaseNode::MARK::Square: | ||||
|             { | ||||
|                 painter->fillRect(checkBoxRect, Qt::black); | ||||
|                 break; | ||||
|             } | ||||
|  | ||||
|             case pdf::xfa::XFA_BaseNode::MARK::Star: | ||||
|             { | ||||
|                 PDFReal starSize = markSize * 0.9; | ||||
|  | ||||
|                 QPainterPath path; | ||||
|                 path.addText(QPointF(0, 0), QFont("Arial", starSize), "☆"); | ||||
|                 path.translate(checkBoxRect.center() - path.boundingRect().center()); | ||||
|                 painter->drawPath(path); | ||||
|                 break; | ||||
|             } | ||||
|         } | ||||
|     } | ||||
| } | ||||
|  | ||||
| void PDFXFAEngineImpl::drawUiImageEdit(const xfa::XFA_imageEdit* imageEdit, | ||||
|                                        const NodeValue& value, | ||||
|                                        QList<PDFRenderError>& errors, | ||||
|                                        QRectF nominalExtentArea, | ||||
|                                        size_t paragraphSettingsIndex, | ||||
|                                        QPainter* painter) | ||||
| { | ||||
|     QRectF nominalExtent = nominalExtentArea; | ||||
|     QRectF nominalContentArea = nominalExtent; | ||||
|     QMarginsF contentMargins = imageEdit ? createMargin(imageEdit->getMargin()) : QMarginsF(); | ||||
|     nominalContentArea = nominalExtent.marginsRemoved(contentMargins); | ||||
|  | ||||
|     if (imageEdit && imageEdit->getBorder()) | ||||
|     { | ||||
|         drawItemBorder(imageEdit->getBorder(), errors, nominalExtentArea, painter); | ||||
|     } | ||||
|  | ||||
|     QImage image = value.value.value<QImage>(); | ||||
|     switch (value.hintImageAspect) | ||||
|     { | ||||
|         case pdf::xfa::XFA_BaseNode::ASPECT::Fit: | ||||
|         { | ||||
|             QRectF imageRect = nominalContentArea; | ||||
|             QSizeF imageSize = QSizeF(image.size()).scaled(imageRect.size(), Qt::KeepAspectRatio); | ||||
|             imageRect.setSize(imageSize); | ||||
|             imageRect.moveCenter(nominalContentArea.center()); | ||||
|             painter->drawImage(imageRect, image); | ||||
|             break; | ||||
|         } | ||||
|  | ||||
|         case pdf::xfa::XFA_BaseNode::ASPECT::Actual: | ||||
|         { | ||||
|             painter->drawImage(nominalContentArea.topLeft(), image); | ||||
|             break; | ||||
|         } | ||||
|  | ||||
|         case pdf::xfa::XFA_BaseNode::ASPECT::Height: | ||||
|         { | ||||
|             QRectF imageRect = nominalContentArea; | ||||
|             QSizeF imageSize = QSizeF(image.size()); | ||||
|  | ||||
|             if (qFuzzyIsNull(imageSize.height())) | ||||
|             { | ||||
|                 imageRect.setWidth(imageSize.width() * imageRect.height() / imageSize.height()); | ||||
|                 imageRect.moveCenter(nominalContentArea.center()); | ||||
|                 painter->drawImage(imageRect, image); | ||||
|             } | ||||
|             break; | ||||
|         } | ||||
|  | ||||
|         case pdf::xfa::XFA_BaseNode::ASPECT::None: | ||||
|         { | ||||
|             painter->drawImage(nominalContentArea, image); | ||||
|             break; | ||||
|         } | ||||
|  | ||||
|         case pdf::xfa::XFA_BaseNode::ASPECT::Width: | ||||
|         { | ||||
|             QRectF imageRect = nominalContentArea; | ||||
|             QSizeF imageSize = QSizeF(image.size()); | ||||
|  | ||||
|             if (qFuzzyIsNull(imageSize.width())) | ||||
|             { | ||||
|                 imageRect.setHeight(imageSize.height() * imageRect.width() / imageSize.width()); | ||||
|                 imageRect.moveCenter(nominalContentArea.center()); | ||||
|                 painter->drawImage(imageRect, image); | ||||
|             } | ||||
|             break; | ||||
|         } | ||||
|     } | ||||
| } | ||||
|  | ||||
| void PDFXFAEngineImpl::drawItemBorder(const xfa::XFA_border* item, | ||||
|                                       QList<PDFRenderError>& errors, | ||||
|                                       QRectF nominalContentArea, | ||||
|   | ||||
		Reference in New Issue
	
	Block a user