summaryrefslogtreecommitdiff
path: root/xfa/fxfa
diff options
context:
space:
mode:
Diffstat (limited to 'xfa/fxfa')
-rw-r--r--xfa/fxfa/cxfa_ffbarcode.cpp1
-rw-r--r--xfa/fxfa/cxfa_ffcheckbutton.h2
-rw-r--r--xfa/fxfa/cxfa_ffcombobox.cpp1
-rw-r--r--xfa/fxfa/cxfa_fffield.cpp1
-rw-r--r--xfa/fxfa/cxfa_ffimage.cpp2
-rw-r--r--xfa/fxfa/cxfa_ffimageedit.cpp2
-rw-r--r--xfa/fxfa/cxfa_fflistbox.cpp1
-rw-r--r--xfa/fxfa/cxfa_ffpasswordedit.cpp1
-rw-r--r--xfa/fxfa/cxfa_ffpushbutton.cpp1
-rw-r--r--xfa/fxfa/cxfa_fftext.cpp1
-rw-r--r--xfa/fxfa/cxfa_fftextedit.cpp1
-rw-r--r--xfa/fxfa/cxfa_ffwidget.cpp1
-rw-r--r--xfa/fxfa/cxfa_fwltheme.cpp1
-rw-r--r--xfa/fxfa/cxfa_textprovider.cpp1
-rw-r--r--xfa/fxfa/cxfa_widgetacc.cpp2500
-rw-r--r--xfa/fxfa/cxfa_widgetacc.h209
-rw-r--r--xfa/fxfa/parser/cxfa_localevalue.h2
-rw-r--r--xfa/fxfa/parser/cxfa_node.cpp2443
-rw-r--r--xfa/fxfa/parser/cxfa_node.h174
-rw-r--r--xfa/fxfa/parser/xfa_document_datamerger_imp.cpp1
20 files changed, 2608 insertions, 2738 deletions
diff --git a/xfa/fxfa/cxfa_ffbarcode.cpp b/xfa/fxfa/cxfa_ffbarcode.cpp
index caef3df2fb..86b06185e4 100644
--- a/xfa/fxfa/cxfa_ffbarcode.cpp
+++ b/xfa/fxfa/cxfa_ffbarcode.cpp
@@ -17,7 +17,6 @@
#include "xfa/fxfa/cxfa_ffpageview.h"
#include "xfa/fxfa/cxfa_ffwidget.h"
#include "xfa/fxfa/cxfa_fwladapterwidgetmgr.h"
-#include "xfa/fxfa/cxfa_widgetacc.h"
#include "xfa/fxfa/parser/cxfa_border.h"
namespace {
diff --git a/xfa/fxfa/cxfa_ffcheckbutton.h b/xfa/fxfa/cxfa_ffcheckbutton.h
index 2ee2a7df44..230695f85a 100644
--- a/xfa/fxfa/cxfa_ffcheckbutton.h
+++ b/xfa/fxfa/cxfa_ffcheckbutton.h
@@ -9,7 +9,7 @@
#include "xfa/fxfa/cxfa_fffield.h"
#include "xfa/fxfa/cxfa_ffpageview.h"
-#include "xfa/fxfa/cxfa_widgetacc.h"
+#include "xfa/fxfa/parser/cxfa_node.h"
class CXFA_FFCheckButton : public CXFA_FFField {
public:
diff --git a/xfa/fxfa/cxfa_ffcombobox.cpp b/xfa/fxfa/cxfa_ffcombobox.cpp
index fcb8eb1aa5..7e9a855b16 100644
--- a/xfa/fxfa/cxfa_ffcombobox.cpp
+++ b/xfa/fxfa/cxfa_ffcombobox.cpp
@@ -14,7 +14,6 @@
#include "xfa/fwl/cfwl_notedriver.h"
#include "xfa/fxfa/cxfa_eventparam.h"
#include "xfa/fxfa/cxfa_ffdocview.h"
-#include "xfa/fxfa/cxfa_widgetacc.h"
#include "xfa/fxfa/parser/cxfa_para.h"
namespace {
diff --git a/xfa/fxfa/cxfa_fffield.cpp b/xfa/fxfa/cxfa_fffield.cpp
index 64e8e00340..8ac287641d 100644
--- a/xfa/fxfa/cxfa_fffield.cpp
+++ b/xfa/fxfa/cxfa_fffield.cpp
@@ -22,7 +22,6 @@
#include "xfa/fxfa/cxfa_ffwidget.h"
#include "xfa/fxfa/cxfa_fwltheme.h"
#include "xfa/fxfa/cxfa_textlayout.h"
-#include "xfa/fxfa/cxfa_widgetacc.h"
#include "xfa/fxfa/parser/cxfa_border.h"
#include "xfa/fxfa/parser/cxfa_calculate.h"
#include "xfa/fxfa/parser/cxfa_caption.h"
diff --git a/xfa/fxfa/cxfa_ffimage.cpp b/xfa/fxfa/cxfa_ffimage.cpp
index 608ca3cc10..a5a2ee7464 100644
--- a/xfa/fxfa/cxfa_ffimage.cpp
+++ b/xfa/fxfa/cxfa_ffimage.cpp
@@ -6,12 +6,12 @@
#include "xfa/fxfa/cxfa_ffimage.h"
+#include "core/fxge/dib/cfx_dibitmap.h"
#include "xfa/fxfa/cxfa_ffapp.h"
#include "xfa/fxfa/cxfa_ffdoc.h"
#include "xfa/fxfa/cxfa_ffdraw.h"
#include "xfa/fxfa/cxfa_ffpageview.h"
#include "xfa/fxfa/cxfa_ffwidget.h"
-#include "xfa/fxfa/cxfa_widgetacc.h"
#include "xfa/fxfa/parser/cxfa_image.h"
#include "xfa/fxfa/parser/cxfa_para.h"
#include "xfa/fxfa/parser/cxfa_value.h"
diff --git a/xfa/fxfa/cxfa_ffimageedit.cpp b/xfa/fxfa/cxfa_ffimageedit.cpp
index 3ef05e9e47..8b97c2b3be 100644
--- a/xfa/fxfa/cxfa_ffimageedit.cpp
+++ b/xfa/fxfa/cxfa_ffimageedit.cpp
@@ -8,6 +8,7 @@
#include <utility>
+#include "core/fxge/dib/cfx_dibitmap.h"
#include "third_party/base/ptr_util.h"
#include "xfa/fwl/cfwl_app.h"
#include "xfa/fwl/cfwl_messagemouse.h"
@@ -18,7 +19,6 @@
#include "xfa/fxfa/cxfa_fffield.h"
#include "xfa/fxfa/cxfa_ffpageview.h"
#include "xfa/fxfa/cxfa_ffwidget.h"
-#include "xfa/fxfa/cxfa_widgetacc.h"
#include "xfa/fxfa/parser/cxfa_border.h"
#include "xfa/fxfa/parser/cxfa_image.h"
#include "xfa/fxfa/parser/cxfa_para.h"
diff --git a/xfa/fxfa/cxfa_fflistbox.cpp b/xfa/fxfa/cxfa_fflistbox.cpp
index 12a2c8a8c9..64fb8e58a4 100644
--- a/xfa/fxfa/cxfa_fflistbox.cpp
+++ b/xfa/fxfa/cxfa_fflistbox.cpp
@@ -14,7 +14,6 @@
#include "xfa/fwl/cfwl_notedriver.h"
#include "xfa/fwl/cfwl_widget.h"
#include "xfa/fxfa/cxfa_eventparam.h"
-#include "xfa/fxfa/cxfa_widgetacc.h"
#include "xfa/fxfa/parser/cxfa_para.h"
namespace {
diff --git a/xfa/fxfa/cxfa_ffpasswordedit.cpp b/xfa/fxfa/cxfa_ffpasswordedit.cpp
index d639d1e57e..15bd5faaae 100644
--- a/xfa/fxfa/cxfa_ffpasswordedit.cpp
+++ b/xfa/fxfa/cxfa_ffpasswordedit.cpp
@@ -11,7 +11,6 @@
#include "xfa/fwl/cfwl_edit.h"
#include "xfa/fwl/cfwl_notedriver.h"
#include "xfa/fxfa/cxfa_ffdoc.h"
-#include "xfa/fxfa/cxfa_widgetacc.h"
#include "xfa/fxfa/parser/cxfa_node.h"
CXFA_FFPasswordEdit::CXFA_FFPasswordEdit(CXFA_Node* pNode)
diff --git a/xfa/fxfa/cxfa_ffpushbutton.cpp b/xfa/fxfa/cxfa_ffpushbutton.cpp
index ce05cf5d03..d4d591f87a 100644
--- a/xfa/fxfa/cxfa_ffpushbutton.cpp
+++ b/xfa/fxfa/cxfa_ffpushbutton.cpp
@@ -18,7 +18,6 @@
#include "xfa/fxfa/cxfa_ffwidget.h"
#include "xfa/fxfa/cxfa_textlayout.h"
#include "xfa/fxfa/cxfa_textprovider.h"
-#include "xfa/fxfa/cxfa_widgetacc.h"
#include "xfa/fxfa/parser/cxfa_border.h"
#include "xfa/fxfa/parser/cxfa_caption.h"
#include "xfa/fxfa/parser/cxfa_edge.h"
diff --git a/xfa/fxfa/cxfa_fftext.cpp b/xfa/fxfa/cxfa_fftext.cpp
index 05749642e8..7ae3cb6f5c 100644
--- a/xfa/fxfa/cxfa_fftext.cpp
+++ b/xfa/fxfa/cxfa_fftext.cpp
@@ -17,7 +17,6 @@
#include "xfa/fxfa/cxfa_pieceline.h"
#include "xfa/fxfa/cxfa_textlayout.h"
#include "xfa/fxfa/cxfa_textpiece.h"
-#include "xfa/fxfa/cxfa_widgetacc.h"
#include "xfa/fxfa/parser/cxfa_margin.h"
#include "xfa/fxgraphics/cxfa_graphics.h"
diff --git a/xfa/fxfa/cxfa_fftextedit.cpp b/xfa/fxfa/cxfa_fftextedit.cpp
index 8464aa97e7..89a7c90155 100644
--- a/xfa/fxfa/cxfa_fftextedit.cpp
+++ b/xfa/fxfa/cxfa_fftextedit.cpp
@@ -19,7 +19,6 @@
#include "xfa/fxfa/cxfa_eventparam.h"
#include "xfa/fxfa/cxfa_ffapp.h"
#include "xfa/fxfa/cxfa_ffdoc.h"
-#include "xfa/fxfa/cxfa_widgetacc.h"
#include "xfa/fxfa/parser/cxfa_node.h"
#include "xfa/fxfa/parser/cxfa_para.h"
diff --git a/xfa/fxfa/cxfa_ffwidget.cpp b/xfa/fxfa/cxfa_ffwidget.cpp
index fa3136ca77..c3e0d4de4d 100644
--- a/xfa/fxfa/cxfa_ffwidget.cpp
+++ b/xfa/fxfa/cxfa_ffwidget.cpp
@@ -25,7 +25,6 @@
#include "xfa/fxfa/cxfa_ffdocview.h"
#include "xfa/fxfa/cxfa_ffpageview.h"
#include "xfa/fxfa/cxfa_imagerenderer.h"
-#include "xfa/fxfa/cxfa_widgetacc.h"
#include "xfa/fxfa/parser/cxfa_border.h"
#include "xfa/fxfa/parser/cxfa_box.h"
#include "xfa/fxfa/parser/cxfa_image.h"
diff --git a/xfa/fxfa/cxfa_fwltheme.cpp b/xfa/fxfa/cxfa_fwltheme.cpp
index a3679f8127..c7c521ea66 100644
--- a/xfa/fxfa/cxfa_fwltheme.cpp
+++ b/xfa/fxfa/cxfa_fwltheme.cpp
@@ -24,7 +24,6 @@
#include "xfa/fwl/cfwl_themetext.h"
#include "xfa/fxfa/cxfa_ffapp.h"
#include "xfa/fxfa/cxfa_ffwidget.h"
-#include "xfa/fxfa/cxfa_widgetacc.h"
#include "xfa/fxfa/parser/cxfa_para.h"
#include "xfa/fxgraphics/cxfa_gecolor.h"
diff --git a/xfa/fxfa/cxfa_textprovider.cpp b/xfa/fxfa/cxfa_textprovider.cpp
index 9ea083831f..d1f9256d34 100644
--- a/xfa/fxfa/cxfa_textprovider.cpp
+++ b/xfa/fxfa/cxfa_textprovider.cpp
@@ -28,7 +28,6 @@
#include "xfa/fxfa/cxfa_ffwidget.h"
#include "xfa/fxfa/cxfa_fontmgr.h"
#include "xfa/fxfa/cxfa_fwladapterwidgetmgr.h"
-#include "xfa/fxfa/cxfa_widgetacc.h"
#include "xfa/fxfa/parser/cxfa_caption.h"
#include "xfa/fxfa/parser/cxfa_font.h"
#include "xfa/fxfa/parser/cxfa_items.h"
diff --git a/xfa/fxfa/cxfa_widgetacc.cpp b/xfa/fxfa/cxfa_widgetacc.cpp
deleted file mode 100644
index 0e73dfb4e8..0000000000
--- a/xfa/fxfa/cxfa_widgetacc.cpp
+++ /dev/null
@@ -1,2500 +0,0 @@
-// Copyright 2017 PDFium Authors. All rights reserved.
-// Use of this source code is governed by a BSD-style license that can be
-// found in the LICENSE file.
-
-// Original code copyright 2014 Foxit Software Inc. http://www.foxitsoftware.com
-
-#include "xfa/fxfa/cxfa_widgetacc.h"
-
-#include <algorithm>
-#include <tuple>
-#include <vector>
-
-#include "core/fxcrt/cfx_decimal.h"
-#include "core/fxcrt/cfx_memorystream.h"
-#include "core/fxcrt/fx_extension.h"
-#include "core/fxcrt/xml/cfx_xmlelement.h"
-#include "core/fxcrt/xml/cfx_xmlnode.h"
-#include "fxjs/cfxjse_engine.h"
-#include "fxjs/xfa/cjx_object.h"
-#include "third_party/base/stl_util.h"
-#include "xfa/fde/cfde_textout.h"
-#include "xfa/fxfa/cxfa_ffapp.h"
-#include "xfa/fxfa/cxfa_ffdoc.h"
-#include "xfa/fxfa/cxfa_ffdocview.h"
-#include "xfa/fxfa/cxfa_ffnotify.h"
-#include "xfa/fxfa/cxfa_ffwidget.h"
-#include "xfa/fxfa/cxfa_fontmgr.h"
-#include "xfa/fxfa/cxfa_textlayout.h"
-#include "xfa/fxfa/cxfa_textprovider.h"
-#include "xfa/fxfa/parser/cxfa_bind.h"
-#include "xfa/fxfa/parser/cxfa_border.h"
-#include "xfa/fxfa/parser/cxfa_calculate.h"
-#include "xfa/fxfa/parser/cxfa_caption.h"
-#include "xfa/fxfa/parser/cxfa_comb.h"
-#include "xfa/fxfa/parser/cxfa_decimal.h"
-#include "xfa/fxfa/parser/cxfa_document.h"
-#include "xfa/fxfa/parser/cxfa_event.h"
-#include "xfa/fxfa/parser/cxfa_font.h"
-#include "xfa/fxfa/parser/cxfa_format.h"
-#include "xfa/fxfa/parser/cxfa_image.h"
-#include "xfa/fxfa/parser/cxfa_items.h"
-#include "xfa/fxfa/parser/cxfa_layoutprocessor.h"
-#include "xfa/fxfa/parser/cxfa_localevalue.h"
-#include "xfa/fxfa/parser/cxfa_margin.h"
-#include "xfa/fxfa/parser/cxfa_measurement.h"
-#include "xfa/fxfa/parser/cxfa_node.h"
-#include "xfa/fxfa/parser/cxfa_para.h"
-#include "xfa/fxfa/parser/cxfa_picture.h"
-#include "xfa/fxfa/parser/cxfa_script.h"
-#include "xfa/fxfa/parser/cxfa_stroke.h"
-#include "xfa/fxfa/parser/cxfa_ui.h"
-#include "xfa/fxfa/parser/cxfa_validate.h"
-#include "xfa/fxfa/parser/cxfa_value.h"
-#include "xfa/fxfa/parser/xfa_utils.h"
-
-class CXFA_WidgetLayoutData {
- public:
- CXFA_WidgetLayoutData() : m_fWidgetHeight(-1) {}
- virtual ~CXFA_WidgetLayoutData() {}
-
- float m_fWidgetHeight;
-};
-
-namespace {
-
-constexpr uint8_t g_inv_base64[128] = {
- 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255,
- 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255,
- 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 62, 255,
- 255, 255, 63, 52, 53, 54, 55, 56, 57, 58, 59, 60, 61, 255, 255,
- 255, 255, 255, 255, 255, 0, 1, 2, 3, 4, 5, 6, 7, 8, 9,
- 10, 11, 12, 13, 14, 15, 16, 17, 18, 19, 20, 21, 22, 23, 24,
- 25, 255, 255, 255, 255, 255, 255, 26, 27, 28, 29, 30, 31, 32, 33,
- 34, 35, 36, 37, 38, 39, 40, 41, 42, 43, 44, 45, 46, 47, 48,
- 49, 50, 51, 255, 255, 255, 255, 255,
-};
-
-uint8_t* XFA_RemoveBase64Whitespace(const uint8_t* pStr, int32_t iLen) {
- uint8_t* pCP;
- int32_t i = 0, j = 0;
- if (iLen == 0) {
- iLen = strlen((char*)pStr);
- }
- pCP = FX_Alloc(uint8_t, iLen + 1);
- for (; i < iLen; i++) {
- if ((pStr[i] & 128) == 0) {
- if (g_inv_base64[pStr[i]] != 0xFF || pStr[i] == '=') {
- pCP[j++] = pStr[i];
- }
- }
- }
- pCP[j] = '\0';
- return pCP;
-}
-
-int32_t XFA_Base64Decode(const char* pStr, uint8_t* pOutBuffer) {
- if (!pStr) {
- return 0;
- }
- uint8_t* pBuffer =
- XFA_RemoveBase64Whitespace((uint8_t*)pStr, strlen((char*)pStr));
- if (!pBuffer) {
- return 0;
- }
- int32_t iLen = strlen((char*)pBuffer);
- int32_t i = 0, j = 0;
- uint32_t dwLimb = 0;
- for (; i + 3 < iLen; i += 4) {
- if (pBuffer[i] == '=' || pBuffer[i + 1] == '=' || pBuffer[i + 2] == '=' ||
- pBuffer[i + 3] == '=') {
- if (pBuffer[i] == '=' || pBuffer[i + 1] == '=') {
- break;
- }
- if (pBuffer[i + 2] == '=') {
- dwLimb = ((uint32_t)g_inv_base64[pBuffer[i]] << 6) |
- ((uint32_t)g_inv_base64[pBuffer[i + 1]]);
- pOutBuffer[j] = (uint8_t)(dwLimb >> 4) & 0xFF;
- j++;
- } else {
- dwLimb = ((uint32_t)g_inv_base64[pBuffer[i]] << 12) |
- ((uint32_t)g_inv_base64[pBuffer[i + 1]] << 6) |
- ((uint32_t)g_inv_base64[pBuffer[i + 2]]);
- pOutBuffer[j] = (uint8_t)(dwLimb >> 10) & 0xFF;
- pOutBuffer[j + 1] = (uint8_t)(dwLimb >> 2) & 0xFF;
- j += 2;
- }
- } else {
- dwLimb = ((uint32_t)g_inv_base64[pBuffer[i]] << 18) |
- ((uint32_t)g_inv_base64[pBuffer[i + 1]] << 12) |
- ((uint32_t)g_inv_base64[pBuffer[i + 2]] << 6) |
- ((uint32_t)g_inv_base64[pBuffer[i + 3]]);
- pOutBuffer[j] = (uint8_t)(dwLimb >> 16) & 0xff;
- pOutBuffer[j + 1] = (uint8_t)(dwLimb >> 8) & 0xff;
- pOutBuffer[j + 2] = (uint8_t)(dwLimb)&0xff;
- j += 3;
- }
- }
- FX_Free(pBuffer);
- return j;
-}
-
-FXCODEC_IMAGE_TYPE XFA_GetImageType(const WideString& wsType) {
- WideString wsContentType(wsType);
- wsContentType.MakeLower();
- if (wsContentType == L"image/jpg")
- return FXCODEC_IMAGE_JPG;
- if (wsContentType == L"image/png")
- return FXCODEC_IMAGE_PNG;
- if (wsContentType == L"image/gif")
- return FXCODEC_IMAGE_GIF;
- if (wsContentType == L"image/bmp")
- return FXCODEC_IMAGE_BMP;
- if (wsContentType == L"image/tif")
- return FXCODEC_IMAGE_TIF;
- return FXCODEC_IMAGE_UNKNOWN;
-}
-
-RetainPtr<CFX_DIBitmap> XFA_LoadImageData(CXFA_FFDoc* pDoc,
- CXFA_Image* pImage,
- bool& bNameImage,
- int32_t& iImageXDpi,
- int32_t& iImageYDpi) {
- WideString wsHref = pImage->GetHref();
- WideString wsImage = pImage->GetContent();
- if (wsHref.IsEmpty() && wsImage.IsEmpty())
- return nullptr;
-
- FXCODEC_IMAGE_TYPE type = XFA_GetImageType(pImage->GetContentType());
- ByteString bsContent;
- uint8_t* pImageBuffer = nullptr;
- RetainPtr<IFX_SeekableReadStream> pImageFileRead;
- if (wsImage.GetLength() > 0) {
- XFA_AttributeEnum iEncoding = pImage->GetTransferEncoding();
- if (iEncoding == XFA_AttributeEnum::Base64) {
- ByteString bsData = wsImage.UTF8Encode();
- int32_t iLength = bsData.GetLength();
- pImageBuffer = FX_Alloc(uint8_t, iLength);
- int32_t iRead = XFA_Base64Decode(bsData.c_str(), pImageBuffer);
- if (iRead > 0) {
- pImageFileRead =
- pdfium::MakeRetain<CFX_MemoryStream>(pImageBuffer, iRead, false);
- }
- } else {
- bsContent = ByteString::FromUnicode(wsImage);
- pImageFileRead = pdfium::MakeRetain<CFX_MemoryStream>(
- const_cast<uint8_t*>(bsContent.raw_str()), bsContent.GetLength(),
- false);
- }
- } else {
- WideString wsURL = wsHref;
- if (wsURL.Left(7) != L"http://" && wsURL.Left(6) != L"ftp://") {
- RetainPtr<CFX_DIBitmap> pBitmap =
- pDoc->GetPDFNamedImage(wsURL.AsStringView(), iImageXDpi, iImageYDpi);
- if (pBitmap) {
- bNameImage = true;
- return pBitmap;
- }
- }
- pImageFileRead = pDoc->GetDocEnvironment()->OpenLinkedFile(pDoc, wsURL);
- }
- if (!pImageFileRead) {
- FX_Free(pImageBuffer);
- return nullptr;
- }
- bNameImage = false;
- RetainPtr<CFX_DIBitmap> pBitmap =
- XFA_LoadImageFromBuffer(pImageFileRead, type, iImageXDpi, iImageYDpi);
- FX_Free(pImageBuffer);
- return pBitmap;
-}
-
-class CXFA_TextLayoutData : public CXFA_WidgetLayoutData {
- public:
- CXFA_TextLayoutData() {}
- ~CXFA_TextLayoutData() override {}
-
- CXFA_TextLayout* GetTextLayout() const { return m_pTextLayout.get(); }
- CXFA_TextProvider* GetTextProvider() const { return m_pTextProvider.get(); }
-
- void LoadText(CXFA_FFDoc* doc, CXFA_WidgetAcc* pAcc) {
- if (m_pTextLayout)
- return;
-
- m_pTextProvider = pdfium::MakeUnique<CXFA_TextProvider>(
- pAcc->GetNode(), XFA_TEXTPROVIDERTYPE_Text);
- m_pTextLayout =
- pdfium::MakeUnique<CXFA_TextLayout>(doc, m_pTextProvider.get());
- }
-
- private:
- std::unique_ptr<CXFA_TextLayout> m_pTextLayout;
- std::unique_ptr<CXFA_TextProvider> m_pTextProvider;
-};
-
-class CXFA_ImageLayoutData : public CXFA_WidgetLayoutData {
- public:
- CXFA_ImageLayoutData()
- : m_bNamedImage(false), m_iImageXDpi(0), m_iImageYDpi(0) {}
-
- ~CXFA_ImageLayoutData() override {}
-
- bool LoadImageData(CXFA_FFDoc* doc, CXFA_WidgetAcc* pAcc) {
- if (m_pDIBitmap)
- return true;
-
- CXFA_Value* value = pAcc->GetNode()->GetFormValueIfExists();
- if (!value)
- return false;
-
- CXFA_Image* image = value->GetImageIfExists();
- if (!image)
- return false;
-
- pAcc->SetImageImage(XFA_LoadImageData(doc, image, m_bNamedImage,
- m_iImageXDpi, m_iImageYDpi));
- return !!m_pDIBitmap;
- }
-
- RetainPtr<CFX_DIBitmap> m_pDIBitmap;
- bool m_bNamedImage;
- int32_t m_iImageXDpi;
- int32_t m_iImageYDpi;
-};
-
-class CXFA_FieldLayoutData : public CXFA_WidgetLayoutData {
- public:
- CXFA_FieldLayoutData() {}
- ~CXFA_FieldLayoutData() override {}
-
- bool LoadCaption(CXFA_FFDoc* doc, CXFA_WidgetAcc* pAcc) {
- if (m_pCapTextLayout)
- return true;
- CXFA_Caption* caption = pAcc->GetNode()->GetCaptionIfExists();
- if (!caption || caption->IsHidden())
- return false;
-
- m_pCapTextProvider = pdfium::MakeUnique<CXFA_TextProvider>(
- pAcc->GetNode(), XFA_TEXTPROVIDERTYPE_Caption);
- m_pCapTextLayout =
- pdfium::MakeUnique<CXFA_TextLayout>(doc, m_pCapTextProvider.get());
- return true;
- }
-
- std::unique_ptr<CXFA_TextLayout> m_pCapTextLayout;
- std::unique_ptr<CXFA_TextProvider> m_pCapTextProvider;
- std::unique_ptr<CFDE_TextOut> m_pTextOut;
- std::vector<float> m_FieldSplitArray;
-};
-
-class CXFA_TextEditData : public CXFA_FieldLayoutData {};
-
-class CXFA_ImageEditData : public CXFA_FieldLayoutData {
- public:
- CXFA_ImageEditData()
- : m_bNamedImage(false), m_iImageXDpi(0), m_iImageYDpi(0) {}
-
- ~CXFA_ImageEditData() override {}
-
- bool LoadImageData(CXFA_FFDoc* doc, CXFA_WidgetAcc* pAcc) {
- if (m_pDIBitmap)
- return true;
-
- CXFA_Value* value = pAcc->GetNode()->GetFormValueIfExists();
- if (!value)
- return false;
-
- CXFA_Image* image = value->GetImageIfExists();
- if (!image)
- return false;
-
- pAcc->SetImageEditImage(XFA_LoadImageData(doc, image, m_bNamedImage,
- m_iImageXDpi, m_iImageYDpi));
- return !!m_pDIBitmap;
- }
-
- RetainPtr<CFX_DIBitmap> m_pDIBitmap;
- bool m_bNamedImage;
- int32_t m_iImageXDpi;
- int32_t m_iImageYDpi;
-};
-
-bool SplitDateTime(const WideString& wsDateTime,
- WideString& wsDate,
- WideString& wsTime) {
- wsDate = L"";
- wsTime = L"";
- if (wsDateTime.IsEmpty())
- return false;
-
- auto nSplitIndex = wsDateTime.Find('T');
- if (!nSplitIndex.has_value())
- nSplitIndex = wsDateTime.Find(' ');
- if (!nSplitIndex.has_value())
- return false;
-
- wsDate = wsDateTime.Left(nSplitIndex.value());
- if (!wsDate.IsEmpty()) {
- if (!std::any_of(wsDate.begin(), wsDate.end(), std::iswdigit))
- return false;
- }
- wsTime = wsDateTime.Right(wsDateTime.GetLength() - nSplitIndex.value() - 1);
- if (!wsTime.IsEmpty()) {
- if (!std::any_of(wsTime.begin(), wsTime.end(), std::iswdigit))
- return false;
- }
- return true;
-}
-
-} // namespace
-
-CXFA_WidgetAcc::CXFA_WidgetAcc(CXFA_Node* pNode) : m_pNode(pNode) {
- ASSERT(m_pNode);
-}
-
-CXFA_WidgetAcc::~CXFA_WidgetAcc() = default;
-
-void CXFA_WidgetAcc::ResetData() {
- WideString wsValue;
- switch (m_pNode->GetUIType()) {
- case XFA_Element::ImageEdit: {
- CXFA_Value* imageValue = m_pNode->GetDefaultValueIfExists();
- CXFA_Image* image = imageValue ? imageValue->GetImageIfExists() : nullptr;
- WideString wsContentType, wsHref;
- if (image) {
- wsValue = image->GetContent();
- wsContentType = image->GetContentType();
- wsHref = image->GetHref();
- }
- SetImageEdit(wsContentType, wsHref, wsValue);
- break;
- }
- case XFA_Element::ExclGroup: {
- CXFA_Node* pNextChild = m_pNode->GetFirstContainerChild();
- while (pNextChild) {
- CXFA_Node* pChild = pNextChild;
- if (!pChild->IsWidgetReady())
- continue;
-
- CXFA_WidgetAcc* pAcc = pChild->GetWidgetAcc();
- bool done = false;
- if (wsValue.IsEmpty()) {
- CXFA_Value* defValue = pAcc->GetNode()->GetDefaultValueIfExists();
- if (defValue) {
- wsValue = defValue->GetChildValueContent();
- SetValue(XFA_VALUEPICTURE_Raw, wsValue);
- pAcc->SetValue(XFA_VALUEPICTURE_Raw, wsValue);
- done = true;
- }
- }
- if (!done) {
- CXFA_Items* pItems =
- pChild->GetChild<CXFA_Items>(0, XFA_Element::Items, false);
- if (!pItems)
- continue;
-
- WideString itemText;
- if (pItems->CountChildren(XFA_Element::Unknown, false) > 1) {
- itemText =
- pItems->GetChild<CXFA_Node>(1, XFA_Element::Unknown, false)
- ->JSObject()
- ->GetContent(false);
- }
- pAcc->SetValue(XFA_VALUEPICTURE_Raw, itemText);
- }
- pNextChild = pChild->GetNextContainerSibling();
- }
- break;
- }
- case XFA_Element::ChoiceList:
- ClearAllSelections();
- default: {
- CXFA_Value* defValue = m_pNode->GetDefaultValueIfExists();
- if (defValue)
- wsValue = defValue->GetChildValueContent();
-
- SetValue(XFA_VALUEPICTURE_Raw, wsValue);
- break;
- }
- }
-}
-
-void CXFA_WidgetAcc::SetImageEdit(const WideString& wsContentType,
- const WideString& wsHref,
- const WideString& wsData) {
- CXFA_Value* formValue = m_pNode->GetFormValueIfExists();
- CXFA_Image* image = formValue ? formValue->GetImageIfExists() : nullptr;
- if (image) {
- image->SetContentType(WideString(wsContentType));
- image->SetHref(wsHref);
- }
-
- m_pNode->JSObject()->SetContent(wsData, GetFormatDataValue(wsData), true,
- false, true);
-
- CXFA_Node* pBind = m_pNode->GetBindData();
- if (!pBind) {
- if (image)
- image->SetTransferEncoding(XFA_AttributeEnum::Base64);
- return;
- }
- pBind->JSObject()->SetCData(XFA_Attribute::ContentType, wsContentType, false,
- false);
- CXFA_Node* pHrefNode = pBind->GetFirstChild();
- if (pHrefNode) {
- pHrefNode->JSObject()->SetCData(XFA_Attribute::Value, wsHref, false, false);
- } else {
- CFX_XMLNode* pXMLNode = pBind->GetXMLMappingNode();
- ASSERT(pXMLNode && pXMLNode->GetType() == FX_XMLNODE_Element);
- static_cast<CFX_XMLElement*>(pXMLNode)->SetString(L"href", wsHref);
- }
-}
-
-CXFA_FFWidget* CXFA_WidgetAcc::GetNextWidget(CXFA_FFWidget* pWidget) {
- return static_cast<CXFA_FFWidget*>(pWidget->GetNext());
-}
-
-void CXFA_WidgetAcc::UpdateUIDisplay(CXFA_FFDocView* docView,
- CXFA_FFWidget* pExcept) {
- CXFA_FFWidget* pWidget = docView->GetWidgetForNode(m_pNode);
- for (; pWidget; pWidget = GetNextWidget(pWidget)) {
- if (pWidget == pExcept || !pWidget->IsLoaded() ||
- (m_pNode->GetUIType() != XFA_Element::CheckButton &&
- pWidget->IsFocused())) {
- continue;
- }
- pWidget->UpdateFWLData();
- pWidget->AddInvalidateRect();
- }
-}
-
-void CXFA_WidgetAcc::CalcCaptionSize(CXFA_FFDoc* doc, CFX_SizeF& szCap) {
- CXFA_Caption* caption = m_pNode->GetCaptionIfExists();
- if (!caption || !caption->IsVisible())
- return;
-
- LoadCaption(doc);
-
- XFA_Element eUIType = m_pNode->GetUIType();
- XFA_AttributeEnum iCapPlacement = caption->GetPlacementType();
- float fCapReserve = caption->GetReserve();
- const bool bVert = iCapPlacement == XFA_AttributeEnum::Top ||
- iCapPlacement == XFA_AttributeEnum::Bottom;
- const bool bReserveExit = fCapReserve > 0.01;
- CXFA_TextLayout* pCapTextLayout =
- static_cast<CXFA_FieldLayoutData*>(m_pLayoutData.get())
- ->m_pCapTextLayout.get();
- if (pCapTextLayout) {
- if (!bVert && eUIType != XFA_Element::Button)
- szCap.width = fCapReserve;
-
- CFX_SizeF minSize;
- szCap = pCapTextLayout->CalcSize(minSize, szCap);
- if (bReserveExit)
- bVert ? szCap.height = fCapReserve : szCap.width = fCapReserve;
- } else {
- float fFontSize = 10.0f;
- CXFA_Font* font = caption->GetFontIfExists();
- if (font) {
- fFontSize = font->GetFontSize();
- } else {
- CXFA_Font* widgetfont = m_pNode->GetFontIfExists();
- if (widgetfont)
- fFontSize = widgetfont->GetFontSize();
- }
-
- if (bVert) {
- szCap.height = fCapReserve > 0 ? fCapReserve : fFontSize;
- } else {
- szCap.width = fCapReserve > 0 ? fCapReserve : 0;
- szCap.height = fFontSize;
- }
- }
-
- CXFA_Margin* captionMargin = caption->GetMarginIfExists();
- if (!captionMargin)
- return;
-
- float fLeftInset = captionMargin->GetLeftInset();
- float fTopInset = captionMargin->GetTopInset();
- float fRightInset = captionMargin->GetRightInset();
- float fBottomInset = captionMargin->GetBottomInset();
- if (bReserveExit) {
- bVert ? (szCap.width += fLeftInset + fRightInset)
- : (szCap.height += fTopInset + fBottomInset);
- } else {
- szCap.width += fLeftInset + fRightInset;
- szCap.height += fTopInset + fBottomInset;
- }
-}
-
-bool CXFA_WidgetAcc::CalculateFieldAutoSize(CXFA_FFDoc* doc, CFX_SizeF& size) {
- CFX_SizeF szCap;
- CalcCaptionSize(doc, szCap);
-
- CFX_RectF rtUIMargin = m_pNode->GetUIMargin();
- size.width += rtUIMargin.left + rtUIMargin.width;
- size.height += rtUIMargin.top + rtUIMargin.height;
- if (szCap.width > 0 && szCap.height > 0) {
- CXFA_Caption* caption = m_pNode->GetCaptionIfExists();
- XFA_AttributeEnum placement = caption ? caption->GetPlacementType()
- : CXFA_Caption::kDefaultPlacementType;
- switch (placement) {
- case XFA_AttributeEnum::Left:
- case XFA_AttributeEnum::Right:
- case XFA_AttributeEnum::Inline: {
- size.width += szCap.width;
- size.height = std::max(size.height, szCap.height);
- } break;
- case XFA_AttributeEnum::Top:
- case XFA_AttributeEnum::Bottom: {
- size.height += szCap.height;
- size.width = std::max(size.width, szCap.width);
- }
- default:
- break;
- }
- }
- return CalculateWidgetAutoSize(size);
-}
-
-bool CXFA_WidgetAcc::CalculateWidgetAutoSize(CFX_SizeF& size) {
- CXFA_Margin* margin = m_pNode->GetMarginIfExists();
- if (margin) {
- size.width += margin->GetLeftInset() + margin->GetRightInset();
- size.height += margin->GetTopInset() + margin->GetBottomInset();
- }
-
- CXFA_Para* para = m_pNode->GetParaIfExists();
- if (para)
- size.width += para->GetMarginLeft() + para->GetTextIndent();
-
- Optional<float> width = m_pNode->TryWidth();
- if (width) {
- size.width = *width;
- } else {
- Optional<float> min = m_pNode->TryMinWidth();
- if (min)
- size.width = std::max(size.width, *min);
-
- Optional<float> max = m_pNode->TryMaxWidth();
- if (max && *max > 0)
- size.width = std::min(size.width, *max);
- }
-
- Optional<float> height = m_pNode->TryHeight();
- if (height) {
- size.height = *height;
- } else {
- Optional<float> min = m_pNode->TryMinHeight();
- if (min)
- size.height = std::max(size.height, *min);
-
- Optional<float> max = m_pNode->TryMaxHeight();
- if (max && *max > 0)
- size.height = std::min(size.height, *max);
- }
- return true;
-}
-
-void CXFA_WidgetAcc::CalculateTextContentSize(CXFA_FFDoc* doc,
- CFX_SizeF& size) {
- float fFontSize = m_pNode->GetFontSize();
- WideString wsText = GetValue(XFA_VALUEPICTURE_Display);
- if (wsText.IsEmpty()) {
- size.height += fFontSize;
- return;
- }
-
- wchar_t wcEnter = '\n';
- wchar_t wsLast = wsText[wsText.GetLength() - 1];
- if (wsLast == wcEnter)
- wsText = wsText + wcEnter;
-
- CXFA_FieldLayoutData* layoutData =
- static_cast<CXFA_FieldLayoutData*>(m_pLayoutData.get());
- if (!layoutData->m_pTextOut) {
- layoutData->m_pTextOut = pdfium::MakeUnique<CFDE_TextOut>();
- CFDE_TextOut* pTextOut = layoutData->m_pTextOut.get();
- pTextOut->SetFont(GetFDEFont(doc));
- pTextOut->SetFontSize(fFontSize);
- pTextOut->SetLineBreakTolerance(fFontSize * 0.2f);
- pTextOut->SetLineSpace(m_pNode->GetLineHeight());
-
- FDE_TextStyle dwStyles;
- dwStyles.last_line_height_ = true;
- if (m_pNode->GetUIType() == XFA_Element::TextEdit && IsMultiLine())
- dwStyles.line_wrap_ = true;
-
- pTextOut->SetStyles(dwStyles);
- }
- layoutData->m_pTextOut->CalcLogicSize(wsText, size);
-}
-
-bool CXFA_WidgetAcc::CalculateTextEditAutoSize(CXFA_FFDoc* doc,
- CFX_SizeF& size) {
- if (size.width > 0) {
- CFX_SizeF szOrz = size;
- CFX_SizeF szCap;
- CalcCaptionSize(doc, szCap);
- bool bCapExit = szCap.width > 0.01 && szCap.height > 0.01;
- XFA_AttributeEnum iCapPlacement = XFA_AttributeEnum::Unknown;
- if (bCapExit) {
- CXFA_Caption* caption = m_pNode->GetCaptionIfExists();
- iCapPlacement = caption ? caption->GetPlacementType()
- : CXFA_Caption::kDefaultPlacementType;
- switch (iCapPlacement) {
- case XFA_AttributeEnum::Left:
- case XFA_AttributeEnum::Right:
- case XFA_AttributeEnum::Inline: {
- size.width -= szCap.width;
- }
- default:
- break;
- }
- }
- CFX_RectF rtUIMargin = m_pNode->GetUIMargin();
- size.width -= rtUIMargin.left + rtUIMargin.width;
- CXFA_Margin* margin = m_pNode->GetMarginIfExists();
- if (margin)
- size.width -= margin->GetLeftInset() + margin->GetRightInset();
-
- CalculateTextContentSize(doc, size);
- size.height += rtUIMargin.top + rtUIMargin.height;
- if (bCapExit) {
- switch (iCapPlacement) {
- case XFA_AttributeEnum::Left:
- case XFA_AttributeEnum::Right:
- case XFA_AttributeEnum::Inline: {
- size.height = std::max(size.height, szCap.height);
- } break;
- case XFA_AttributeEnum::Top:
- case XFA_AttributeEnum::Bottom: {
- size.height += szCap.height;
- }
- default:
- break;
- }
- }
- size.width = szOrz.width;
- return CalculateWidgetAutoSize(size);
- }
- CalculateTextContentSize(doc, size);
- return CalculateFieldAutoSize(doc, size);
-}
-
-bool CXFA_WidgetAcc::CalculateCheckButtonAutoSize(CXFA_FFDoc* doc,
- CFX_SizeF& size) {
- float fCheckSize = GetCheckButtonSize();
- size = CFX_SizeF(fCheckSize, fCheckSize);
- return CalculateFieldAutoSize(doc, size);
-}
-
-bool CXFA_WidgetAcc::CalculatePushButtonAutoSize(CXFA_FFDoc* doc,
- CFX_SizeF& size) {
- CalcCaptionSize(doc, size);
- return CalculateWidgetAutoSize(size);
-}
-
-CFX_SizeF CXFA_WidgetAcc::CalculateImageSize(float img_width,
- float img_height,
- float dpi_x,
- float dpi_y) {
- CFX_RectF rtImage(0, 0, XFA_UnitPx2Pt(img_width, dpi_x),
- XFA_UnitPx2Pt(img_height, dpi_y));
-
- CFX_RectF rtFit;
- Optional<float> width = m_pNode->TryWidth();
- if (width) {
- rtFit.width = *width;
- GetWidthWithoutMargin(rtFit.width);
- } else {
- rtFit.width = rtImage.width;
- }
-
- Optional<float> height = m_pNode->TryHeight();
- if (height) {
- rtFit.height = *height;
- GetHeightWithoutMargin(rtFit.height);
- } else {
- rtFit.height = rtImage.height;
- }
-
- return rtFit.Size();
-}
-
-bool CXFA_WidgetAcc::CalculateImageAutoSize(CXFA_FFDoc* doc, CFX_SizeF& size) {
- if (!GetImageImage())
- LoadImageImage(doc);
-
- size.clear();
- RetainPtr<CFX_DIBitmap> pBitmap = GetImageImage();
- if (!pBitmap)
- return CalculateWidgetAutoSize(size);
-
- int32_t iImageXDpi = 0;
- int32_t iImageYDpi = 0;
- GetImageDpi(iImageXDpi, iImageYDpi);
-
- size = CalculateImageSize(pBitmap->GetWidth(), pBitmap->GetHeight(),
- iImageXDpi, iImageYDpi);
- return CalculateWidgetAutoSize(size);
-}
-
-bool CXFA_WidgetAcc::CalculateImageEditAutoSize(CXFA_FFDoc* doc,
- CFX_SizeF& size) {
- if (!GetImageEditImage())
- LoadImageEditImage(doc);
-
- size.clear();
- RetainPtr<CFX_DIBitmap> pBitmap = GetImageEditImage();
- if (!pBitmap)
- return CalculateFieldAutoSize(doc, size);
-
- int32_t iImageXDpi = 0;
- int32_t iImageYDpi = 0;
- GetImageEditDpi(iImageXDpi, iImageYDpi);
-
- size = CalculateImageSize(pBitmap->GetWidth(), pBitmap->GetHeight(),
- iImageXDpi, iImageYDpi);
- return CalculateFieldAutoSize(doc, size);
-}
-
-bool CXFA_WidgetAcc::LoadImageImage(CXFA_FFDoc* doc) {
- InitLayoutData();
- return static_cast<CXFA_ImageLayoutData*>(m_pLayoutData.get())
- ->LoadImageData(doc, this);
-}
-
-bool CXFA_WidgetAcc::LoadImageEditImage(CXFA_FFDoc* doc) {
- InitLayoutData();
- return static_cast<CXFA_ImageEditData*>(m_pLayoutData.get())
- ->LoadImageData(doc, this);
-}
-
-void CXFA_WidgetAcc::GetImageDpi(int32_t& iImageXDpi, int32_t& iImageYDpi) {
- CXFA_ImageLayoutData* pData =
- static_cast<CXFA_ImageLayoutData*>(m_pLayoutData.get());
- iImageXDpi = pData->m_iImageXDpi;
- iImageYDpi = pData->m_iImageYDpi;
-}
-
-void CXFA_WidgetAcc::GetImageEditDpi(int32_t& iImageXDpi, int32_t& iImageYDpi) {
- CXFA_ImageEditData* pData =
- static_cast<CXFA_ImageEditData*>(m_pLayoutData.get());
- iImageXDpi = pData->m_iImageXDpi;
- iImageYDpi = pData->m_iImageYDpi;
-}
-
-void CXFA_WidgetAcc::LoadText(CXFA_FFDoc* doc) {
- InitLayoutData();
- static_cast<CXFA_TextLayoutData*>(m_pLayoutData.get())->LoadText(doc, this);
-}
-
-float CXFA_WidgetAcc::CalculateWidgetAutoWidth(float fWidthCalc) {
- CXFA_Margin* margin = m_pNode->GetMarginIfExists();
- if (margin)
- fWidthCalc += margin->GetLeftInset() + margin->GetRightInset();
-
- Optional<float> min = m_pNode->TryMinWidth();
- if (min)
- fWidthCalc = std::max(fWidthCalc, *min);
-
- Optional<float> max = m_pNode->TryMaxWidth();
- if (max && *max > 0)
- fWidthCalc = std::min(fWidthCalc, *max);
-
- return fWidthCalc;
-}
-
-float CXFA_WidgetAcc::GetWidthWithoutMargin(float fWidthCalc) {
- CXFA_Margin* margin = m_pNode->GetMarginIfExists();
- if (margin)
- fWidthCalc -= margin->GetLeftInset() + margin->GetRightInset();
- return fWidthCalc;
-}
-
-float CXFA_WidgetAcc::CalculateWidgetAutoHeight(float fHeightCalc) {
- CXFA_Margin* margin = m_pNode->GetMarginIfExists();
- if (margin)
- fHeightCalc += margin->GetTopInset() + margin->GetBottomInset();
-
- Optional<float> min = m_pNode->TryMinHeight();
- if (min)
- fHeightCalc = std::max(fHeightCalc, *min);
-
- Optional<float> max = m_pNode->TryMaxHeight();
- if (max && *max > 0)
- fHeightCalc = std::min(fHeightCalc, *max);
-
- return fHeightCalc;
-}
-
-float CXFA_WidgetAcc::GetHeightWithoutMargin(float fHeightCalc) {
- CXFA_Margin* margin = m_pNode->GetMarginIfExists();
- if (margin)
- fHeightCalc -= margin->GetTopInset() + margin->GetBottomInset();
- return fHeightCalc;
-}
-
-void CXFA_WidgetAcc::StartWidgetLayout(CXFA_FFDoc* doc,
- float& fCalcWidth,
- float& fCalcHeight) {
- InitLayoutData();
-
- XFA_Element eUIType = m_pNode->GetUIType();
- if (eUIType == XFA_Element::Text) {
- m_pLayoutData->m_fWidgetHeight = m_pNode->TryHeight().value_or(-1);
- StartTextLayout(doc, fCalcWidth, fCalcHeight);
- return;
- }
- if (fCalcWidth > 0 && fCalcHeight > 0)
- return;
-
- m_pLayoutData->m_fWidgetHeight = -1;
- float fWidth = 0;
- if (fCalcWidth > 0 && fCalcHeight < 0) {
- Optional<float> height = m_pNode->TryHeight();
- if (height)
- fCalcHeight = *height;
- else
- CalculateAccWidthAndHeight(doc, eUIType, fCalcWidth, fCalcHeight);
-
- m_pLayoutData->m_fWidgetHeight = fCalcHeight;
- return;
- }
- if (fCalcWidth < 0 && fCalcHeight < 0) {
- Optional<float> height;
- Optional<float> width = m_pNode->TryWidth();
- if (width) {
- fWidth = *width;
-
- height = m_pNode->TryHeight();
- if (height)
- fCalcHeight = *height;
- }
- if (!width || !height)
- CalculateAccWidthAndHeight(doc, eUIType, fWidth, fCalcHeight);
-
- fCalcWidth = fWidth;
- }
- m_pLayoutData->m_fWidgetHeight = fCalcHeight;
-}
-
-void CXFA_WidgetAcc::CalculateAccWidthAndHeight(CXFA_FFDoc* doc,
- XFA_Element eUIType,
- float& fWidth,
- float& fCalcHeight) {
- CFX_SizeF sz(fWidth, m_pLayoutData->m_fWidgetHeight);
- switch (eUIType) {
- case XFA_Element::Barcode:
- case XFA_Element::ChoiceList:
- case XFA_Element::Signature:
- CalculateFieldAutoSize(doc, sz);
- break;
- case XFA_Element::ImageEdit:
- CalculateImageEditAutoSize(doc, sz);
- break;
- case XFA_Element::Button:
- CalculatePushButtonAutoSize(doc, sz);
- break;
- case XFA_Element::CheckButton:
- CalculateCheckButtonAutoSize(doc, sz);
- break;
- case XFA_Element::DateTimeEdit:
- case XFA_Element::NumericEdit:
- case XFA_Element::PasswordEdit:
- case XFA_Element::TextEdit:
- CalculateTextEditAutoSize(doc, sz);
- break;
- case XFA_Element::Image:
- CalculateImageAutoSize(doc, sz);
- break;
- case XFA_Element::Arc:
- case XFA_Element::Line:
- case XFA_Element::Rectangle:
- case XFA_Element::Subform:
- case XFA_Element::ExclGroup:
- CalculateWidgetAutoSize(sz);
- break;
- default:
- break;
- }
- fWidth = sz.width;
- m_pLayoutData->m_fWidgetHeight = sz.height;
- fCalcHeight = sz.height;
-}
-
-bool CXFA_WidgetAcc::FindSplitPos(CXFA_FFDocView* docView,
- int32_t iBlockIndex,
- float& fCalcHeight) {
- XFA_Element eUIType = m_pNode->GetUIType();
- if (eUIType == XFA_Element::Subform)
- return false;
-
- if (eUIType != XFA_Element::Text && eUIType != XFA_Element::TextEdit &&
- eUIType != XFA_Element::NumericEdit &&
- eUIType != XFA_Element::PasswordEdit) {
- fCalcHeight = 0;
- return true;
- }
-
- float fTopInset = 0;
- float fBottomInset = 0;
- if (iBlockIndex == 0) {
- CXFA_Margin* margin = m_pNode->GetMarginIfExists();
- if (margin) {
- fTopInset = margin->GetTopInset();
- fBottomInset = margin->GetBottomInset();
- }
-
- CFX_RectF rtUIMargin = m_pNode->GetUIMargin();
- fTopInset += rtUIMargin.top;
- fBottomInset += rtUIMargin.width;
- }
- if (eUIType == XFA_Element::Text) {
- float fHeight = fCalcHeight;
- if (iBlockIndex == 0) {
- fCalcHeight = fCalcHeight - fTopInset;
- if (fCalcHeight < 0)
- fCalcHeight = 0;
- }
-
- CXFA_TextLayout* pTextLayout =
- static_cast<CXFA_TextLayoutData*>(m_pLayoutData.get())->GetTextLayout();
- fCalcHeight =
- pTextLayout->DoLayout(iBlockIndex, fCalcHeight, fCalcHeight,
- m_pLayoutData->m_fWidgetHeight - fTopInset);
- if (fCalcHeight != 0) {
- if (iBlockIndex == 0)
- fCalcHeight = fCalcHeight + fTopInset;
- if (fabs(fHeight - fCalcHeight) < XFA_FLOAT_PERCISION)
- return false;
- }
- return true;
- }
- XFA_AttributeEnum iCapPlacement = XFA_AttributeEnum::Unknown;
- float fCapReserve = 0;
- if (iBlockIndex == 0) {
- CXFA_Caption* caption = m_pNode->GetCaptionIfExists();
- if (caption && !caption->IsHidden()) {
- iCapPlacement = caption->GetPlacementType();
- fCapReserve = caption->GetReserve();
- }
- if (iCapPlacement == XFA_AttributeEnum::Top &&
- fCalcHeight < fCapReserve + fTopInset) {
- fCalcHeight = 0;
- return true;
- }
- if (iCapPlacement == XFA_AttributeEnum::Bottom &&
- m_pLayoutData->m_fWidgetHeight - fCapReserve - fBottomInset) {
- fCalcHeight = 0;
- return true;
- }
- if (iCapPlacement != XFA_AttributeEnum::Top)
- fCapReserve = 0;
- }
- CXFA_FieldLayoutData* pFieldData =
- static_cast<CXFA_FieldLayoutData*>(m_pLayoutData.get());
- int32_t iLinesCount = 0;
- float fHeight = m_pLayoutData->m_fWidgetHeight;
- if (GetValue(XFA_VALUEPICTURE_Display).IsEmpty()) {
- iLinesCount = 1;
- } else {
- if (!pFieldData->m_pTextOut) {
- // TODO(dsinclair): Inline fWidth when the 2nd param of
- // CalculateAccWidthAndHeight isn't a ref-param.
- float fWidth = m_pNode->TryWidth().value_or(0);
- CalculateAccWidthAndHeight(docView->GetDoc(), eUIType, fWidth, fHeight);
- }
- iLinesCount = pFieldData->m_pTextOut->GetTotalLines();
- }
- std::vector<float>* pFieldArray = &pFieldData->m_FieldSplitArray;
- int32_t iFieldSplitCount = pdfium::CollectionSize<int32_t>(*pFieldArray);
- for (int32_t i = 0; i < iBlockIndex * 3; i += 3) {
- iLinesCount -= (int32_t)(*pFieldArray)[i + 1];
- fHeight -= (*pFieldArray)[i + 2];
- }
- if (iLinesCount == 0)
- return false;
-
- float fLineHeight = m_pNode->GetLineHeight();
- float fFontSize = m_pNode->GetFontSize();
- float fTextHeight = iLinesCount * fLineHeight - fLineHeight + fFontSize;
- float fSpaceAbove = 0;
- float fStartOffset = 0;
- if (fHeight > 0.1f && iBlockIndex == 0) {
- fStartOffset = fTopInset;
- fHeight -= (fTopInset + fBottomInset);
- CXFA_Para* para = m_pNode->GetParaIfExists();
- if (para) {
- fSpaceAbove = para->GetSpaceAbove();
- float fSpaceBelow = para->GetSpaceBelow();
- fHeight -= (fSpaceAbove + fSpaceBelow);
- switch (para->GetVerticalAlign()) {
- case XFA_AttributeEnum::Top:
- fStartOffset += fSpaceAbove;
- break;
- case XFA_AttributeEnum::Middle:
- fStartOffset += ((fHeight - fTextHeight) / 2 + fSpaceAbove);
- break;
- case XFA_AttributeEnum::Bottom:
- fStartOffset += (fHeight - fTextHeight + fSpaceAbove);
- break;
- default:
- NOTREACHED();
- break;
- }
- }
- if (fStartOffset < 0.1f)
- fStartOffset = 0;
- }
- for (int32_t i = iBlockIndex - 1; iBlockIndex > 0 && i < iBlockIndex; i++) {
- fStartOffset = (*pFieldArray)[i * 3] - (*pFieldArray)[i * 3 + 2];
- if (fStartOffset < 0.1f)
- fStartOffset = 0;
- }
- if (iFieldSplitCount / 3 == (iBlockIndex + 1))
- (*pFieldArray)[0] = fStartOffset;
- else
- pFieldArray->push_back(fStartOffset);
-
- XFA_VERSION version = docView->GetDoc()->GetXFADoc()->GetCurVersionMode();
- bool bCanSplitNoContent = false;
- XFA_AttributeEnum eLayoutMode = GetNode()
- ->GetParent()
- ->JSObject()
- ->TryEnum(XFA_Attribute::Layout, true)
- .value_or(XFA_AttributeEnum::Position);
- if ((eLayoutMode == XFA_AttributeEnum::Position ||
- eLayoutMode == XFA_AttributeEnum::Tb ||
- eLayoutMode == XFA_AttributeEnum::Row ||
- eLayoutMode == XFA_AttributeEnum::Table) &&
- version > XFA_VERSION_208) {
- bCanSplitNoContent = true;
- }
- if ((eLayoutMode == XFA_AttributeEnum::Tb ||
- eLayoutMode == XFA_AttributeEnum::Row ||
- eLayoutMode == XFA_AttributeEnum::Table) &&
- version <= XFA_VERSION_208) {
- if (fStartOffset < fCalcHeight) {
- bCanSplitNoContent = true;
- } else {
- fCalcHeight = 0;
- return true;
- }
- }
- if (bCanSplitNoContent) {
- if ((fCalcHeight - fTopInset - fSpaceAbove < fLineHeight)) {
- fCalcHeight = 0;
- return true;
- }
- if (fStartOffset + XFA_FLOAT_PERCISION >= fCalcHeight) {
- if (iFieldSplitCount / 3 == (iBlockIndex + 1)) {
- (*pFieldArray)[iBlockIndex * 3 + 1] = 0;
- (*pFieldArray)[iBlockIndex * 3 + 2] = fCalcHeight;
- } else {
- pFieldArray->push_back(0);
- pFieldArray->push_back(fCalcHeight);
- }
- return false;
- }
- if (fCalcHeight - fStartOffset < fLineHeight) {
- fCalcHeight = fStartOffset;
- if (iFieldSplitCount / 3 == (iBlockIndex + 1)) {
- (*pFieldArray)[iBlockIndex * 3 + 1] = 0;
- (*pFieldArray)[iBlockIndex * 3 + 2] = fCalcHeight;
- } else {
- pFieldArray->push_back(0);
- pFieldArray->push_back(fCalcHeight);
- }
- return true;
- }
- float fTextNum =
- fCalcHeight + XFA_FLOAT_PERCISION - fCapReserve - fStartOffset;
- int32_t iLineNum =
- (int32_t)((fTextNum + (fLineHeight - fFontSize)) / fLineHeight);
- if (iLineNum >= iLinesCount) {
- if (fCalcHeight - fStartOffset - fTextHeight >= fFontSize) {
- if (iFieldSplitCount / 3 == (iBlockIndex + 1)) {
- (*pFieldArray)[iBlockIndex * 3 + 1] = (float)iLinesCount;
- (*pFieldArray)[iBlockIndex * 3 + 2] = fCalcHeight;
- } else {
- pFieldArray->push_back((float)iLinesCount);
- pFieldArray->push_back(fCalcHeight);
- }
- return false;
- }
- if (fHeight - fStartOffset - fTextHeight < fFontSize) {
- iLineNum -= 1;
- if (iLineNum == 0) {
- fCalcHeight = 0;
- return true;
- }
- } else {
- iLineNum = (int32_t)(fTextNum / fLineHeight);
- }
- }
- if (iLineNum > 0) {
- float fSplitHeight = iLineNum * fLineHeight + fCapReserve + fStartOffset;
- if (iFieldSplitCount / 3 == (iBlockIndex + 1)) {
- (*pFieldArray)[iBlockIndex * 3 + 1] = (float)iLineNum;
- (*pFieldArray)[iBlockIndex * 3 + 2] = fSplitHeight;
- } else {
- pFieldArray->push_back((float)iLineNum);
- pFieldArray->push_back(fSplitHeight);
- }
- if (fabs(fSplitHeight - fCalcHeight) < XFA_FLOAT_PERCISION)
- return false;
-
- fCalcHeight = fSplitHeight;
- return true;
- }
- }
- fCalcHeight = 0;
- return true;
-}
-
-void CXFA_WidgetAcc::InitLayoutData() {
- if (m_pLayoutData)
- return;
-
- switch (m_pNode->GetUIType()) {
- case XFA_Element::Text:
- m_pLayoutData = pdfium::MakeUnique<CXFA_TextLayoutData>();
- return;
- case XFA_Element::TextEdit:
- m_pLayoutData = pdfium::MakeUnique<CXFA_TextEditData>();
- return;
- case XFA_Element::Image:
- m_pLayoutData = pdfium::MakeUnique<CXFA_ImageLayoutData>();
- return;
- case XFA_Element::ImageEdit:
- m_pLayoutData = pdfium::MakeUnique<CXFA_ImageEditData>();
- return;
- default:
- break;
- }
- if (m_pNode && m_pNode->GetElementType() == XFA_Element::Field) {
- m_pLayoutData = pdfium::MakeUnique<CXFA_FieldLayoutData>();
- return;
- }
- m_pLayoutData = pdfium::MakeUnique<CXFA_WidgetLayoutData>();
-}
-
-void CXFA_WidgetAcc::StartTextLayout(CXFA_FFDoc* doc,
- float& fCalcWidth,
- float& fCalcHeight) {
- LoadText(doc);
-
- CXFA_TextLayout* pTextLayout =
- static_cast<CXFA_TextLayoutData*>(m_pLayoutData.get())->GetTextLayout();
- float fTextHeight = 0;
- if (fCalcWidth > 0 && fCalcHeight > 0) {
- float fWidth = GetWidthWithoutMargin(fCalcWidth);
- pTextLayout->StartLayout(fWidth);
- fTextHeight = fCalcHeight;
- fTextHeight = GetHeightWithoutMargin(fTextHeight);
- pTextLayout->DoLayout(0, fTextHeight, -1, fTextHeight);
- return;
- }
- if (fCalcWidth > 0 && fCalcHeight < 0) {
- float fWidth = GetWidthWithoutMargin(fCalcWidth);
- pTextLayout->StartLayout(fWidth);
- }
-
- if (fCalcWidth < 0 && fCalcHeight < 0) {
- Optional<float> width = m_pNode->TryWidth();
- if (width) {
- pTextLayout->StartLayout(GetWidthWithoutMargin(*width));
- fCalcWidth = *width;
- } else {
- float fMaxWidth = CalculateWidgetAutoWidth(pTextLayout->StartLayout(-1));
- pTextLayout->StartLayout(GetWidthWithoutMargin(fMaxWidth));
- fCalcWidth = fMaxWidth;
- }
- }
-
- if (m_pLayoutData->m_fWidgetHeight < 0) {
- m_pLayoutData->m_fWidgetHeight = pTextLayout->GetLayoutHeight();
- m_pLayoutData->m_fWidgetHeight =
- CalculateWidgetAutoHeight(m_pLayoutData->m_fWidgetHeight);
- }
- fTextHeight = m_pLayoutData->m_fWidgetHeight;
- fTextHeight = GetHeightWithoutMargin(fTextHeight);
- pTextLayout->DoLayout(0, fTextHeight, -1, fTextHeight);
- fCalcHeight = m_pLayoutData->m_fWidgetHeight;
-}
-
-bool CXFA_WidgetAcc::LoadCaption(CXFA_FFDoc* doc) {
- InitLayoutData();
- return static_cast<CXFA_FieldLayoutData*>(m_pLayoutData.get())
- ->LoadCaption(doc, this);
-}
-
-CXFA_TextLayout* CXFA_WidgetAcc::GetCaptionTextLayout() {
- return m_pLayoutData
- ? static_cast<CXFA_FieldLayoutData*>(m_pLayoutData.get())
- ->m_pCapTextLayout.get()
- : nullptr;
-}
-
-CXFA_TextLayout* CXFA_WidgetAcc::GetTextLayout() {
- return m_pLayoutData
- ? static_cast<CXFA_TextLayoutData*>(m_pLayoutData.get())
- ->GetTextLayout()
- : nullptr;
-}
-
-RetainPtr<CFX_DIBitmap> CXFA_WidgetAcc::GetImageImage() {
- return m_pLayoutData
- ? static_cast<CXFA_ImageLayoutData*>(m_pLayoutData.get())
- ->m_pDIBitmap
- : nullptr;
-}
-
-RetainPtr<CFX_DIBitmap> CXFA_WidgetAcc::GetImageEditImage() {
- return m_pLayoutData
- ? static_cast<CXFA_ImageEditData*>(m_pLayoutData.get())
- ->m_pDIBitmap
- : nullptr;
-}
-
-void CXFA_WidgetAcc::SetImageImage(const RetainPtr<CFX_DIBitmap>& newImage) {
- CXFA_ImageLayoutData* pData =
- static_cast<CXFA_ImageLayoutData*>(m_pLayoutData.get());
- if (pData->m_pDIBitmap != newImage)
- pData->m_pDIBitmap = newImage;
-}
-
-void CXFA_WidgetAcc::SetImageEditImage(
- const RetainPtr<CFX_DIBitmap>& newImage) {
- CXFA_ImageEditData* pData =
- static_cast<CXFA_ImageEditData*>(m_pLayoutData.get());
- if (pData->m_pDIBitmap != newImage)
- pData->m_pDIBitmap = newImage;
-}
-
-RetainPtr<CFGAS_GEFont> CXFA_WidgetAcc::GetFDEFont(CXFA_FFDoc* doc) {
- WideString wsFontName = L"Courier";
- uint32_t dwFontStyle = 0;
- CXFA_Font* font = m_pNode->GetFontIfExists();
- if (font) {
- if (font->IsBold())
- dwFontStyle |= FXFONT_BOLD;
- if (font->IsItalic())
- dwFontStyle |= FXFONT_ITALIC;
-
- wsFontName = font->GetTypeface();
- }
- return doc->GetApp()->GetXFAFontMgr()->GetFont(doc, wsFontName.AsStringView(),
- dwFontStyle);
-}
-
-bool CXFA_WidgetAcc::IsOpenAccess() const {
- return m_pNode && m_pNode->IsOpenAccess();
-}
-
-XFA_AttributeEnum CXFA_WidgetAcc::GetButtonHighlight() {
- CXFA_Node* pUIChild = m_pNode->GetUIChild();
- if (pUIChild)
- return pUIChild->JSObject()->GetEnum(XFA_Attribute::Highlight);
- return XFA_AttributeEnum::Inverted;
-}
-
-bool CXFA_WidgetAcc::HasButtonRollover() const {
- CXFA_Items* pItems =
- m_pNode->GetChild<CXFA_Items>(0, XFA_Element::Items, false);
- if (!pItems)
- return false;
-
- for (CXFA_Node* pText = pItems->GetFirstChild(); pText;
- pText = pText->GetNextSibling()) {
- if (pText->JSObject()->GetCData(XFA_Attribute::Name) == L"rollover")
- return !pText->JSObject()->GetContent(false).IsEmpty();
- }
- return false;
-}
-
-bool CXFA_WidgetAcc::HasButtonDown() const {
- CXFA_Items* pItems =
- m_pNode->GetChild<CXFA_Items>(0, XFA_Element::Items, false);
- if (!pItems)
- return false;
-
- for (CXFA_Node* pText = pItems->GetFirstChild(); pText;
- pText = pText->GetNextSibling()) {
- if (pText->JSObject()->GetCData(XFA_Attribute::Name) == L"down")
- return !pText->JSObject()->GetContent(false).IsEmpty();
- }
- return false;
-}
-
-bool CXFA_WidgetAcc::IsCheckButtonRound() {
- CXFA_Node* pUIChild = m_pNode->GetUIChild();
- if (pUIChild)
- return pUIChild->JSObject()->GetEnum(XFA_Attribute::Shape) ==
- XFA_AttributeEnum::Round;
- return false;
-}
-
-XFA_AttributeEnum CXFA_WidgetAcc::GetCheckButtonMark() {
- CXFA_Node* pUIChild = m_pNode->GetUIChild();
- if (pUIChild)
- return pUIChild->JSObject()->GetEnum(XFA_Attribute::Mark);
- return XFA_AttributeEnum::Default;
-}
-
-bool CXFA_WidgetAcc::IsRadioButton() {
- CXFA_Node* pParent = m_pNode->GetParent();
- return pParent && pParent->GetElementType() == XFA_Element::ExclGroup;
-}
-
-float CXFA_WidgetAcc::GetCheckButtonSize() {
- CXFA_Node* pUIChild = m_pNode->GetUIChild();
- if (pUIChild) {
- return pUIChild->JSObject()
- ->GetMeasure(XFA_Attribute::Size)
- .ToUnit(XFA_Unit::Pt);
- }
- return CXFA_Measurement(10, XFA_Unit::Pt).ToUnit(XFA_Unit::Pt);
-}
-
-bool CXFA_WidgetAcc::IsAllowNeutral() {
- CXFA_Node* pUIChild = m_pNode->GetUIChild();
- return pUIChild &&
- pUIChild->JSObject()->GetBoolean(XFA_Attribute::AllowNeutral);
-}
-
-XFA_CHECKSTATE CXFA_WidgetAcc::GetCheckState() {
- WideString wsValue = m_pNode->GetRawValue();
- if (wsValue.IsEmpty())
- return XFA_CHECKSTATE_Off;
-
- auto* pItems = m_pNode->GetChild<CXFA_Items>(0, XFA_Element::Items, false);
- if (!pItems)
- return XFA_CHECKSTATE_Off;
-
- CXFA_Node* pText = pItems->GetFirstChild();
- int32_t i = 0;
- while (pText) {
- Optional<WideString> wsContent = pText->JSObject()->TryContent(false, true);
- if (wsContent && *wsContent == wsValue)
- return static_cast<XFA_CHECKSTATE>(i);
-
- i++;
- pText = pText->GetNextSibling();
- }
- return XFA_CHECKSTATE_Off;
-}
-
-void CXFA_WidgetAcc::SetCheckState(XFA_CHECKSTATE eCheckState, bool bNotify) {
- CXFA_Node* node = m_pNode->GetExclGroupIfExists();
- if (!node) {
- CXFA_Items* pItems =
- m_pNode->GetChild<CXFA_Items>(0, XFA_Element::Items, false);
- if (!pItems)
- return;
-
- int32_t i = -1;
- CXFA_Node* pText = pItems->GetFirstChild();
- WideString wsContent;
- while (pText) {
- i++;
- if (i == eCheckState) {
- wsContent = pText->JSObject()->GetContent(false);
- break;
- }
- pText = pText->GetNextSibling();
- }
- m_pNode->SyncValue(wsContent, bNotify);
-
- return;
- }
-
- WideString wsValue;
- if (eCheckState != XFA_CHECKSTATE_Off) {
- if (CXFA_Items* pItems =
- m_pNode->GetChild<CXFA_Items>(0, XFA_Element::Items, false)) {
- CXFA_Node* pText = pItems->GetFirstChild();
- if (pText)
- wsValue = pText->JSObject()->GetContent(false);
- }
- }
- CXFA_Node* pChild = node->GetFirstChild();
- for (; pChild; pChild = pChild->GetNextSibling()) {
- if (pChild->GetElementType() != XFA_Element::Field)
- continue;
-
- CXFA_Items* pItem =
- pChild->GetChild<CXFA_Items>(0, XFA_Element::Items, false);
- if (!pItem)
- continue;
-
- CXFA_Node* pItemchild = pItem->GetFirstChild();
- if (!pItemchild)
- continue;
-
- WideString text = pItemchild->JSObject()->GetContent(false);
- WideString wsChildValue = text;
- if (wsValue != text) {
- pItemchild = pItemchild->GetNextSibling();
- if (pItemchild)
- wsChildValue = pItemchild->JSObject()->GetContent(false);
- else
- wsChildValue.clear();
- }
- pChild->SyncValue(wsChildValue, bNotify);
- }
- node->SyncValue(wsValue, bNotify);
-}
-
-CXFA_Node* CXFA_WidgetAcc::GetSelectedMember() {
- CXFA_Node* pSelectedMember = nullptr;
- WideString wsState = m_pNode->GetRawValue();
- if (wsState.IsEmpty())
- return pSelectedMember;
-
- for (CXFA_Node* pNode = ToNode(m_pNode->GetFirstChild()); pNode;
- pNode = pNode->GetNextSibling()) {
- CXFA_WidgetAcc widgetData(pNode);
- if (widgetData.GetCheckState() == XFA_CHECKSTATE_On) {
- pSelectedMember = pNode;
- break;
- }
- }
- return pSelectedMember;
-}
-
-CXFA_Node* CXFA_WidgetAcc::SetSelectedMember(const WideStringView& wsName,
- bool bNotify) {
- uint32_t nameHash = FX_HashCode_GetW(wsName, false);
- for (CXFA_Node* pNode = ToNode(m_pNode->GetFirstChild()); pNode;
- pNode = pNode->GetNextSibling()) {
- if (pNode->GetNameHash() == nameHash) {
- CXFA_WidgetAcc widgetData(pNode);
- widgetData.SetCheckState(XFA_CHECKSTATE_On, bNotify);
- return pNode;
- }
- }
- return nullptr;
-}
-
-void CXFA_WidgetAcc::SetSelectedMemberByValue(const WideStringView& wsValue,
- bool bNotify,
- bool bScriptModify,
- bool bSyncData) {
- WideString wsExclGroup;
- for (CXFA_Node* pNode = m_pNode->GetFirstChild(); pNode;
- pNode = pNode->GetNextSibling()) {
- if (pNode->GetElementType() != XFA_Element::Field)
- continue;
-
- CXFA_Items* pItem =
- pNode->GetChild<CXFA_Items>(0, XFA_Element::Items, false);
- if (!pItem)
- continue;
-
- CXFA_Node* pItemchild = pItem->GetFirstChild();
- if (!pItemchild)
- continue;
-
- WideString wsChildValue = pItemchild->JSObject()->GetContent(false);
- if (wsValue != wsChildValue) {
- pItemchild = pItemchild->GetNextSibling();
- if (pItemchild)
- wsChildValue = pItemchild->JSObject()->GetContent(false);
- else
- wsChildValue.clear();
- } else {
- wsExclGroup = wsValue;
- }
- pNode->JSObject()->SetContent(wsChildValue, wsChildValue, bNotify,
- bScriptModify, false);
- }
- m_pNode->JSObject()->SetContent(wsExclGroup, wsExclGroup, bNotify,
- bScriptModify, bSyncData);
-}
-
-CXFA_Node* CXFA_WidgetAcc::GetExclGroupFirstMember() {
- CXFA_Node* pExcl = GetNode();
- if (!pExcl)
- return nullptr;
-
- CXFA_Node* pNode = pExcl->GetFirstChild();
- while (pNode) {
- if (pNode->GetElementType() == XFA_Element::Field)
- return pNode;
-
- pNode = pNode->GetNextSibling();
- }
- return nullptr;
-}
-CXFA_Node* CXFA_WidgetAcc::GetExclGroupNextMember(CXFA_Node* pNode) {
- if (!pNode)
- return nullptr;
-
- CXFA_Node* pNodeField = pNode->GetNextSibling();
- while (pNodeField) {
- if (pNodeField->GetElementType() == XFA_Element::Field)
- return pNodeField;
-
- pNodeField = pNodeField->GetNextSibling();
- }
- return nullptr;
-}
-
-bool CXFA_WidgetAcc::IsChoiceListCommitOnSelect() {
- CXFA_Node* pUIChild = m_pNode->GetUIChild();
- if (pUIChild) {
- return pUIChild->JSObject()->GetEnum(XFA_Attribute::CommitOn) ==
- XFA_AttributeEnum::Select;
- }
- return true;
-}
-
-bool CXFA_WidgetAcc::IsChoiceListAllowTextEntry() {
- CXFA_Node* pUIChild = m_pNode->GetUIChild();
- return pUIChild && pUIChild->JSObject()->GetBoolean(XFA_Attribute::TextEntry);
-}
-
-bool CXFA_WidgetAcc::IsChoiceListMultiSelect() {
- CXFA_Node* pUIChild = m_pNode->GetUIChild();
- if (pUIChild) {
- return pUIChild->JSObject()->GetEnum(XFA_Attribute::Open) ==
- XFA_AttributeEnum::MultiSelect;
- }
- return false;
-}
-
-bool CXFA_WidgetAcc::IsListBox() {
- CXFA_Node* pUIChild = m_pNode->GetUIChild();
- if (!pUIChild)
- return false;
-
- XFA_AttributeEnum attr = pUIChild->JSObject()->GetEnum(XFA_Attribute::Open);
- return attr == XFA_AttributeEnum::Always ||
- attr == XFA_AttributeEnum::MultiSelect;
-}
-
-int32_t CXFA_WidgetAcc::CountChoiceListItems(bool bSaveValue) {
- std::vector<CXFA_Node*> pItems;
- int32_t iCount = 0;
- for (CXFA_Node* pNode = m_pNode->GetFirstChild(); pNode;
- pNode = pNode->GetNextSibling()) {
- if (pNode->GetElementType() != XFA_Element::Items)
- continue;
- iCount++;
- pItems.push_back(pNode);
- if (iCount == 2)
- break;
- }
- if (iCount == 0)
- return 0;
-
- CXFA_Node* pItem = pItems[0];
- if (iCount > 1) {
- bool bItemOneHasSave =
- pItems[0]->JSObject()->GetBoolean(XFA_Attribute::Save);
- bool bItemTwoHasSave =
- pItems[1]->JSObject()->GetBoolean(XFA_Attribute::Save);
- if (bItemOneHasSave != bItemTwoHasSave && bSaveValue == bItemTwoHasSave)
- pItem = pItems[1];
- }
- return pItem->CountChildren(XFA_Element::Unknown, false);
-}
-
-Optional<WideString> CXFA_WidgetAcc::GetChoiceListItem(int32_t nIndex,
- bool bSaveValue) {
- std::vector<CXFA_Node*> pItemsArray;
- int32_t iCount = 0;
- for (CXFA_Node* pNode = m_pNode->GetFirstChild(); pNode;
- pNode = pNode->GetNextSibling()) {
- if (pNode->GetElementType() != XFA_Element::Items)
- continue;
-
- ++iCount;
- pItemsArray.push_back(pNode);
- if (iCount == 2)
- break;
- }
- if (iCount == 0)
- return {};
-
- CXFA_Node* pItems = pItemsArray[0];
- if (iCount > 1) {
- bool bItemOneHasSave =
- pItemsArray[0]->JSObject()->GetBoolean(XFA_Attribute::Save);
- bool bItemTwoHasSave =
- pItemsArray[1]->JSObject()->GetBoolean(XFA_Attribute::Save);
- if (bItemOneHasSave != bItemTwoHasSave && bSaveValue == bItemTwoHasSave)
- pItems = pItemsArray[1];
- }
- if (!pItems)
- return {};
-
- CXFA_Node* pItem =
- pItems->GetChild<CXFA_Node>(nIndex, XFA_Element::Unknown, false);
- if (pItem)
- return {pItem->JSObject()->GetContent(false)};
- return {};
-}
-
-std::vector<WideString> CXFA_WidgetAcc::GetChoiceListItems(bool bSaveValue) {
- std::vector<CXFA_Node*> items;
- for (CXFA_Node* pNode = m_pNode->GetFirstChild(); pNode && items.size() < 2;
- pNode = pNode->GetNextSibling()) {
- if (pNode->GetElementType() == XFA_Element::Items)
- items.push_back(pNode);
- }
- if (items.empty())
- return std::vector<WideString>();
-
- CXFA_Node* pItem = items.front();
- if (items.size() > 1) {
- bool bItemOneHasSave =
- items[0]->JSObject()->GetBoolean(XFA_Attribute::Save);
- bool bItemTwoHasSave =
- items[1]->JSObject()->GetBoolean(XFA_Attribute::Save);
- if (bItemOneHasSave != bItemTwoHasSave && bSaveValue == bItemTwoHasSave)
- pItem = items[1];
- }
-
- std::vector<WideString> wsTextArray;
- for (CXFA_Node* pNode = pItem->GetFirstChild(); pNode;
- pNode = pNode->GetNextSibling()) {
- wsTextArray.emplace_back(pNode->JSObject()->GetContent(false));
- }
- return wsTextArray;
-}
-
-int32_t CXFA_WidgetAcc::CountSelectedItems() {
- std::vector<WideString> wsValueArray = GetSelectedItemsValue();
- if (IsListBox() || !IsChoiceListAllowTextEntry())
- return pdfium::CollectionSize<int32_t>(wsValueArray);
-
- int32_t iSelected = 0;
- std::vector<WideString> wsSaveTextArray = GetChoiceListItems(true);
- for (const auto& value : wsValueArray) {
- if (pdfium::ContainsValue(wsSaveTextArray, value))
- iSelected++;
- }
- return iSelected;
-}
-
-int32_t CXFA_WidgetAcc::GetSelectedItem(int32_t nIndex) {
- std::vector<WideString> wsValueArray = GetSelectedItemsValue();
- if (!pdfium::IndexInBounds(wsValueArray, nIndex))
- return -1;
-
- std::vector<WideString> wsSaveTextArray = GetChoiceListItems(true);
- auto it = std::find(wsSaveTextArray.begin(), wsSaveTextArray.end(),
- wsValueArray[nIndex]);
- return it != wsSaveTextArray.end() ? it - wsSaveTextArray.begin() : -1;
-}
-
-std::vector<int32_t> CXFA_WidgetAcc::GetSelectedItems() {
- std::vector<int32_t> iSelArray;
- std::vector<WideString> wsValueArray = GetSelectedItemsValue();
- std::vector<WideString> wsSaveTextArray = GetChoiceListItems(true);
- for (const auto& value : wsValueArray) {
- auto it = std::find(wsSaveTextArray.begin(), wsSaveTextArray.end(), value);
- if (it != wsSaveTextArray.end())
- iSelArray.push_back(it - wsSaveTextArray.begin());
- }
- return iSelArray;
-}
-
-std::vector<WideString> CXFA_WidgetAcc::GetSelectedItemsValue() {
- std::vector<WideString> wsSelTextArray;
- WideString wsValue = m_pNode->GetRawValue();
- if (IsChoiceListMultiSelect()) {
- if (!wsValue.IsEmpty()) {
- size_t iStart = 0;
- size_t iLength = wsValue.GetLength();
- auto iEnd = wsValue.Find(L'\n', iStart);
- iEnd = (!iEnd.has_value()) ? iLength : iEnd;
- while (iEnd >= iStart) {
- wsSelTextArray.push_back(wsValue.Mid(iStart, iEnd.value() - iStart));
- iStart = iEnd.value() + 1;
- if (iStart >= iLength)
- break;
- iEnd = wsValue.Find(L'\n', iStart);
- if (!iEnd.has_value())
- wsSelTextArray.push_back(wsValue.Mid(iStart, iLength - iStart));
- }
- }
- } else {
- wsSelTextArray.push_back(wsValue);
- }
- return wsSelTextArray;
-}
-
-bool CXFA_WidgetAcc::GetItemState(int32_t nIndex) {
- std::vector<WideString> wsSaveTextArray = GetChoiceListItems(true);
- return pdfium::IndexInBounds(wsSaveTextArray, nIndex) &&
- pdfium::ContainsValue(GetSelectedItemsValue(),
- wsSaveTextArray[nIndex]);
-}
-
-void CXFA_WidgetAcc::SetItemState(int32_t nIndex,
- bool bSelected,
- bool bNotify,
- bool bScriptModify,
- bool bSyncData) {
- std::vector<WideString> wsSaveTextArray = GetChoiceListItems(true);
- if (!pdfium::IndexInBounds(wsSaveTextArray, nIndex))
- return;
-
- int32_t iSel = -1;
- std::vector<WideString> wsValueArray = GetSelectedItemsValue();
- auto it = std::find(wsValueArray.begin(), wsValueArray.end(),
- wsSaveTextArray[nIndex]);
- if (it != wsValueArray.end())
- iSel = it - wsValueArray.begin();
-
- if (IsChoiceListMultiSelect()) {
- if (bSelected) {
- if (iSel < 0) {
- WideString wsValue = m_pNode->GetRawValue();
- if (!wsValue.IsEmpty()) {
- wsValue += L"\n";
- }
- wsValue += wsSaveTextArray[nIndex];
- m_pNode->JSObject()->SetContent(wsValue, wsValue, bNotify,
- bScriptModify, bSyncData);
- }
- } else if (iSel >= 0) {
- std::vector<int32_t> iSelArray = GetSelectedItems();
- auto it = std::find(iSelArray.begin(), iSelArray.end(), nIndex);
- if (it != iSelArray.end())
- iSelArray.erase(it);
- SetSelectedItems(iSelArray, bNotify, bScriptModify, bSyncData);
- }
- } else {
- if (bSelected) {
- if (iSel < 0) {
- WideString wsSaveText = wsSaveTextArray[nIndex];
- m_pNode->JSObject()->SetContent(wsSaveText,
- GetFormatDataValue(wsSaveText), bNotify,
- bScriptModify, bSyncData);
- }
- } else if (iSel >= 0) {
- m_pNode->JSObject()->SetContent(WideString(), WideString(), bNotify,
- bScriptModify, bSyncData);
- }
- }
-}
-
-void CXFA_WidgetAcc::SetSelectedItems(const std::vector<int32_t>& iSelArray,
- bool bNotify,
- bool bScriptModify,
- bool bSyncData) {
- WideString wsValue;
- int32_t iSize = pdfium::CollectionSize<int32_t>(iSelArray);
- if (iSize >= 1) {
- std::vector<WideString> wsSaveTextArray = GetChoiceListItems(true);
- WideString wsItemValue;
- for (int32_t i = 0; i < iSize; i++) {
- wsItemValue = (iSize == 1) ? wsSaveTextArray[iSelArray[i]]
- : wsSaveTextArray[iSelArray[i]] + L"\n";
- wsValue += wsItemValue;
- }
- }
- WideString wsFormat(wsValue);
- if (!IsChoiceListMultiSelect())
- wsFormat = GetFormatDataValue(wsValue);
-
- m_pNode->JSObject()->SetContent(wsValue, wsFormat, bNotify, bScriptModify,
- bSyncData);
-}
-
-void CXFA_WidgetAcc::ClearAllSelections() {
- CXFA_Node* pBind = m_pNode->GetBindData();
- if (!pBind || !IsChoiceListMultiSelect()) {
- m_pNode->SyncValue(WideString(), false);
- return;
- }
-
- while (CXFA_Node* pChildNode = pBind->GetFirstChild())
- pBind->RemoveChild(pChildNode, true);
-}
-
-void CXFA_WidgetAcc::InsertItem(const WideString& wsLabel,
- const WideString& wsValue,
- bool bNotify) {
- int32_t nIndex = -1;
- WideString wsNewValue(wsValue);
- if (wsNewValue.IsEmpty())
- wsNewValue = wsLabel;
-
- std::vector<CXFA_Node*> listitems;
- for (CXFA_Node* pItem = m_pNode->GetFirstChild(); pItem;
- pItem = pItem->GetNextSibling()) {
- if (pItem->GetElementType() == XFA_Element::Items)
- listitems.push_back(pItem);
- }
- if (listitems.empty()) {
- CXFA_Node* pItems = m_pNode->CreateSamePacketNode(XFA_Element::Items);
- m_pNode->InsertChild(-1, pItems);
- InsertListTextItem(pItems, wsLabel, nIndex);
- CXFA_Node* pSaveItems = m_pNode->CreateSamePacketNode(XFA_Element::Items);
- m_pNode->InsertChild(-1, pSaveItems);
- pSaveItems->JSObject()->SetBoolean(XFA_Attribute::Save, true, false);
- InsertListTextItem(pSaveItems, wsNewValue, nIndex);
- } else if (listitems.size() > 1) {
- for (int32_t i = 0; i < 2; i++) {
- CXFA_Node* pNode = listitems[i];
- bool bHasSave = pNode->JSObject()->GetBoolean(XFA_Attribute::Save);
- if (bHasSave)
- InsertListTextItem(pNode, wsNewValue, nIndex);
- else
- InsertListTextItem(pNode, wsLabel, nIndex);
- }
- } else {
- CXFA_Node* pNode = listitems[0];
- pNode->JSObject()->SetBoolean(XFA_Attribute::Save, false, false);
- pNode->JSObject()->SetEnum(XFA_Attribute::Presence,
- XFA_AttributeEnum::Visible, false);
- CXFA_Node* pSaveItems = m_pNode->CreateSamePacketNode(XFA_Element::Items);
- m_pNode->InsertChild(-1, pSaveItems);
- pSaveItems->JSObject()->SetBoolean(XFA_Attribute::Save, true, false);
- pSaveItems->JSObject()->SetEnum(XFA_Attribute::Presence,
- XFA_AttributeEnum::Hidden, false);
- CXFA_Node* pListNode = pNode->GetFirstChild();
- int32_t i = 0;
- while (pListNode) {
- InsertListTextItem(pSaveItems, pListNode->JSObject()->GetContent(false),
- i);
- ++i;
-
- pListNode = pListNode->GetNextSibling();
- }
- InsertListTextItem(pNode, wsLabel, nIndex);
- InsertListTextItem(pSaveItems, wsNewValue, nIndex);
- }
- if (!bNotify)
- return;
-
- m_pNode->GetDocument()->GetNotify()->OnWidgetListItemAdded(
- m_pNode, wsLabel.c_str(), wsValue.c_str(), nIndex);
-}
-
-void CXFA_WidgetAcc::GetItemLabel(const WideStringView& wsValue,
- WideString& wsLabel) {
- int32_t iCount = 0;
- std::vector<CXFA_Node*> listitems;
- CXFA_Node* pItems = m_pNode->GetFirstChild();
- for (; pItems; pItems = pItems->GetNextSibling()) {
- if (pItems->GetElementType() != XFA_Element::Items)
- continue;
- iCount++;
- listitems.push_back(pItems);
- }
-
- if (iCount <= 1) {
- wsLabel = wsValue;
- return;
- }
-
- CXFA_Node* pLabelItems = listitems[0];
- bool bSave = pLabelItems->JSObject()->GetBoolean(XFA_Attribute::Save);
- CXFA_Node* pSaveItems = nullptr;
- if (bSave) {
- pSaveItems = pLabelItems;
- pLabelItems = listitems[1];
- } else {
- pSaveItems = listitems[1];
- }
- iCount = 0;
-
- int32_t iSearch = -1;
- for (CXFA_Node* pChildItem = pSaveItems->GetFirstChild(); pChildItem;
- pChildItem = pChildItem->GetNextSibling()) {
- if (pChildItem->JSObject()->GetContent(false) == wsValue) {
- iSearch = iCount;
- break;
- }
- iCount++;
- }
- if (iSearch < 0)
- return;
-
- CXFA_Node* pText =
- pLabelItems->GetChild<CXFA_Node>(iSearch, XFA_Element::Unknown, false);
- if (pText)
- wsLabel = pText->JSObject()->GetContent(false);
-}
-
-WideString CXFA_WidgetAcc::GetItemValue(const WideStringView& wsLabel) {
- int32_t iCount = 0;
- std::vector<CXFA_Node*> listitems;
- for (CXFA_Node* pItems = m_pNode->GetFirstChild(); pItems;
- pItems = pItems->GetNextSibling()) {
- if (pItems->GetElementType() != XFA_Element::Items)
- continue;
- iCount++;
- listitems.push_back(pItems);
- }
- if (iCount <= 1)
- return WideString(wsLabel);
-
- CXFA_Node* pLabelItems = listitems[0];
- bool bSave = pLabelItems->JSObject()->GetBoolean(XFA_Attribute::Save);
- CXFA_Node* pSaveItems = nullptr;
- if (bSave) {
- pSaveItems = pLabelItems;
- pLabelItems = listitems[1];
- } else {
- pSaveItems = listitems[1];
- }
- iCount = 0;
-
- int32_t iSearch = -1;
- WideString wsContent;
- CXFA_Node* pChildItem = pLabelItems->GetFirstChild();
- for (; pChildItem; pChildItem = pChildItem->GetNextSibling()) {
- if (pChildItem->JSObject()->GetContent(false) == wsLabel) {
- iSearch = iCount;
- break;
- }
- iCount++;
- }
- if (iSearch < 0)
- return L"";
-
- CXFA_Node* pText =
- pSaveItems->GetChild<CXFA_Node>(iSearch, XFA_Element::Unknown, false);
- return pText ? pText->JSObject()->GetContent(false) : L"";
-}
-
-bool CXFA_WidgetAcc::DeleteItem(int32_t nIndex,
- bool bNotify,
- bool bScriptModify) {
- bool bSetValue = false;
- CXFA_Node* pItems = m_pNode->GetFirstChild();
- for (; pItems; pItems = pItems->GetNextSibling()) {
- if (pItems->GetElementType() != XFA_Element::Items)
- continue;
-
- if (nIndex < 0) {
- while (CXFA_Node* pNode = pItems->GetFirstChild()) {
- pItems->RemoveChild(pNode, true);
- }
- } else {
- if (!bSetValue && pItems->JSObject()->GetBoolean(XFA_Attribute::Save)) {
- SetItemState(nIndex, false, true, bScriptModify, true);
- bSetValue = true;
- }
- int32_t i = 0;
- CXFA_Node* pNode = pItems->GetFirstChild();
- while (pNode) {
- if (i == nIndex) {
- pItems->RemoveChild(pNode, true);
- break;
- }
- i++;
- pNode = pNode->GetNextSibling();
- }
- }
- }
- if (bNotify)
- m_pNode->GetDocument()->GetNotify()->OnWidgetListItemRemoved(m_pNode,
- nIndex);
- return true;
-}
-
-bool CXFA_WidgetAcc::IsHorizontalScrollPolicyOff() {
- CXFA_Node* pUIChild = m_pNode->GetUIChild();
- if (pUIChild) {
- return pUIChild->JSObject()->GetEnum(XFA_Attribute::HScrollPolicy) ==
- XFA_AttributeEnum::Off;
- }
- return false;
-}
-
-bool CXFA_WidgetAcc::IsVerticalScrollPolicyOff() {
- CXFA_Node* pUIChild = m_pNode->GetUIChild();
- if (pUIChild) {
- return pUIChild->JSObject()->GetEnum(XFA_Attribute::VScrollPolicy) ==
- XFA_AttributeEnum::Off;
- }
- return false;
-}
-
-Optional<int32_t> CXFA_WidgetAcc::GetNumberOfCells() {
- CXFA_Node* pUIChild = m_pNode->GetUIChild();
- if (!pUIChild)
- return {};
- if (CXFA_Comb* pNode =
- pUIChild->GetChild<CXFA_Comb>(0, XFA_Element::Comb, false))
- return {pNode->JSObject()->GetInteger(XFA_Attribute::NumberOfCells)};
- return {};
-}
-
-WideString CXFA_WidgetAcc::GetPasswordChar() {
- CXFA_Node* pUIChild = m_pNode->GetUIChild();
- return pUIChild ? pUIChild->JSObject()->GetCData(XFA_Attribute::PasswordChar)
- : L"*";
-}
-
-bool CXFA_WidgetAcc::IsMultiLine() {
- CXFA_Node* pUIChild = m_pNode->GetUIChild();
- return pUIChild && pUIChild->JSObject()->GetBoolean(XFA_Attribute::MultiLine);
-}
-
-std::pair<XFA_Element, int32_t> CXFA_WidgetAcc::GetMaxChars() {
- if (CXFA_Value* pNode =
- m_pNode->GetChild<CXFA_Value>(0, XFA_Element::Value, false)) {
- if (CXFA_Node* pChild = pNode->GetFirstChild()) {
- switch (pChild->GetElementType()) {
- case XFA_Element::Text:
- return {XFA_Element::Text,
- pChild->JSObject()->GetInteger(XFA_Attribute::MaxChars)};
- case XFA_Element::ExData: {
- int32_t iMax =
- pChild->JSObject()->GetInteger(XFA_Attribute::MaxLength);
- return {XFA_Element::ExData, iMax < 0 ? 0 : iMax};
- }
- default:
- break;
- }
- }
- }
- return {XFA_Element::Unknown, 0};
-}
-
-int32_t CXFA_WidgetAcc::GetFracDigits() {
- CXFA_Value* pNode =
- m_pNode->GetChild<CXFA_Value>(0, XFA_Element::Value, false);
- if (!pNode)
- return -1;
-
- CXFA_Decimal* pChild =
- pNode->GetChild<CXFA_Decimal>(0, XFA_Element::Decimal, false);
- if (!pChild)
- return -1;
-
- return pChild->JSObject()
- ->TryInteger(XFA_Attribute::FracDigits, true)
- .value_or(-1);
-}
-
-int32_t CXFA_WidgetAcc::GetLeadDigits() {
- CXFA_Value* pNode =
- m_pNode->GetChild<CXFA_Value>(0, XFA_Element::Value, false);
- if (!pNode)
- return -1;
-
- CXFA_Decimal* pChild =
- pNode->GetChild<CXFA_Decimal>(0, XFA_Element::Decimal, false);
- if (!pChild)
- return -1;
-
- return pChild->JSObject()
- ->TryInteger(XFA_Attribute::LeadDigits, true)
- .value_or(-1);
-}
-
-bool CXFA_WidgetAcc::SetValue(XFA_VALUEPICTURE eValueType,
- const WideString& wsValue) {
- if (wsValue.IsEmpty()) {
- m_pNode->SyncValue(wsValue, true);
- return true;
- }
-
- m_pNode->SetPreNull(m_pNode->IsNull());
- m_pNode->SetIsNull(false);
-
- WideString wsNewText(wsValue);
- WideString wsPicture = GetPictureContent(eValueType);
- bool bValidate = true;
- bool bSyncData = false;
- CXFA_Node* pNode = m_pNode->GetUIChild();
- if (!pNode)
- return true;
-
- XFA_Element eType = pNode->GetElementType();
- if (!wsPicture.IsEmpty()) {
- CXFA_LocaleMgr* pLocalMgr = m_pNode->GetDocument()->GetLocalMgr();
- IFX_Locale* pLocale = m_pNode->GetLocale();
- CXFA_LocaleValue widgetValue = XFA_GetLocaleValue(GetNode());
- bValidate =
- widgetValue.ValidateValue(wsValue, wsPicture, pLocale, &wsPicture);
- if (bValidate) {
- widgetValue = CXFA_LocaleValue(widgetValue.GetType(), wsNewText,
- wsPicture, pLocale, pLocalMgr);
- wsNewText = widgetValue.GetValue();
- if (eType == XFA_Element::NumericEdit)
- wsNewText = NumericLimit(wsNewText, GetLeadDigits(), GetFracDigits());
-
- bSyncData = true;
- }
- } else {
- if (eType == XFA_Element::NumericEdit) {
- if (wsNewText != L"0")
- wsNewText = NumericLimit(wsNewText, GetLeadDigits(), GetFracDigits());
-
- bSyncData = true;
- }
- }
- if (eType != XFA_Element::NumericEdit || bSyncData)
- m_pNode->SyncValue(wsNewText, true);
-
- return bValidate;
-}
-
-WideString CXFA_WidgetAcc::GetPictureContent(XFA_VALUEPICTURE ePicture) {
- if (ePicture == XFA_VALUEPICTURE_Raw)
- return L"";
-
- CXFA_LocaleValue widgetValue = XFA_GetLocaleValue(GetNode());
- switch (ePicture) {
- case XFA_VALUEPICTURE_Display: {
- if (CXFA_Format* pFormat =
- m_pNode->GetChild<CXFA_Format>(0, XFA_Element::Format, false)) {
- if (CXFA_Picture* pPicture = pFormat->GetChild<CXFA_Picture>(
- 0, XFA_Element::Picture, false)) {
- Optional<WideString> picture =
- pPicture->JSObject()->TryContent(false, true);
- if (picture)
- return *picture;
- }
- }
-
- IFX_Locale* pLocale = m_pNode->GetLocale();
- if (!pLocale)
- return L"";
-
- uint32_t dwType = widgetValue.GetType();
- switch (dwType) {
- case XFA_VT_DATE:
- return pLocale->GetDatePattern(FX_LOCALEDATETIMESUBCATEGORY_Medium);
- case XFA_VT_TIME:
- return pLocale->GetTimePattern(FX_LOCALEDATETIMESUBCATEGORY_Medium);
- case XFA_VT_DATETIME:
- return pLocale->GetDatePattern(FX_LOCALEDATETIMESUBCATEGORY_Medium) +
- L"T" +
- pLocale->GetTimePattern(FX_LOCALEDATETIMESUBCATEGORY_Medium);
- case XFA_VT_DECIMAL:
- case XFA_VT_FLOAT:
- default:
- return L"";
- }
- }
- case XFA_VALUEPICTURE_Edit: {
- CXFA_Ui* pUI = m_pNode->GetChild<CXFA_Ui>(0, XFA_Element::Ui, false);
- if (pUI) {
- if (CXFA_Picture* pPicture =
- pUI->GetChild<CXFA_Picture>(0, XFA_Element::Picture, false)) {
- Optional<WideString> picture =
- pPicture->JSObject()->TryContent(false, true);
- if (picture)
- return *picture;
- }
- }
-
- IFX_Locale* pLocale = m_pNode->GetLocale();
- if (!pLocale)
- return L"";
-
- uint32_t dwType = widgetValue.GetType();
- switch (dwType) {
- case XFA_VT_DATE:
- return pLocale->GetDatePattern(FX_LOCALEDATETIMESUBCATEGORY_Short);
- case XFA_VT_TIME:
- return pLocale->GetTimePattern(FX_LOCALEDATETIMESUBCATEGORY_Short);
- case XFA_VT_DATETIME:
- return pLocale->GetDatePattern(FX_LOCALEDATETIMESUBCATEGORY_Short) +
- L"T" +
- pLocale->GetTimePattern(FX_LOCALEDATETIMESUBCATEGORY_Short);
- default:
- return L"";
- }
- }
- case XFA_VALUEPICTURE_DataBind: {
- CXFA_Bind* bind = m_pNode->GetBindIfExists();
- if (bind)
- return bind->GetPicture();
- break;
- }
- default:
- break;
- }
- return L"";
-}
-
-WideString CXFA_WidgetAcc::GetValue(XFA_VALUEPICTURE eValueType) {
- WideString wsValue = m_pNode->JSObject()->GetContent(false);
-
- if (eValueType == XFA_VALUEPICTURE_Display)
- GetItemLabel(wsValue.AsStringView(), wsValue);
-
- WideString wsPicture = GetPictureContent(eValueType);
- CXFA_Node* pNode = m_pNode->GetUIChild();
- if (!pNode)
- return wsValue;
-
- switch (m_pNode->GetUIChild()->GetElementType()) {
- case XFA_Element::ChoiceList: {
- if (eValueType == XFA_VALUEPICTURE_Display) {
- int32_t iSelItemIndex = GetSelectedItem(0);
- if (iSelItemIndex >= 0) {
- wsValue = GetChoiceListItem(iSelItemIndex, false).value_or(L"");
- wsPicture.clear();
- }
- }
- } break;
- case XFA_Element::NumericEdit:
- if (eValueType != XFA_VALUEPICTURE_Raw && wsPicture.IsEmpty()) {
- IFX_Locale* pLocale = m_pNode->GetLocale();
- if (eValueType == XFA_VALUEPICTURE_Display && pLocale)
- wsValue = FormatNumStr(NormalizeNumStr(wsValue), pLocale);
- }
- break;
- default:
- break;
- }
- if (wsPicture.IsEmpty())
- return wsValue;
-
- if (IFX_Locale* pLocale = m_pNode->GetLocale()) {
- CXFA_LocaleValue widgetValue = XFA_GetLocaleValue(GetNode());
- CXFA_LocaleMgr* pLocalMgr = m_pNode->GetDocument()->GetLocalMgr();
- switch (widgetValue.GetType()) {
- case XFA_VT_DATE: {
- WideString wsDate, wsTime;
- if (SplitDateTime(wsValue, wsDate, wsTime)) {
- CXFA_LocaleValue date(XFA_VT_DATE, wsDate, pLocalMgr);
- if (date.FormatPatterns(wsValue, wsPicture, pLocale, eValueType))
- return wsValue;
- }
- break;
- }
- case XFA_VT_TIME: {
- WideString wsDate, wsTime;
- if (SplitDateTime(wsValue, wsDate, wsTime)) {
- CXFA_LocaleValue time(XFA_VT_TIME, wsTime, pLocalMgr);
- if (time.FormatPatterns(wsValue, wsPicture, pLocale, eValueType))
- return wsValue;
- }
- break;
- }
- default:
- break;
- }
- widgetValue.FormatPatterns(wsValue, wsPicture, pLocale, eValueType);
- }
- return wsValue;
-}
-
-WideString CXFA_WidgetAcc::GetNormalizeDataValue(const WideString& wsValue) {
- if (wsValue.IsEmpty())
- return L"";
-
- WideString wsPicture = GetPictureContent(XFA_VALUEPICTURE_DataBind);
- if (wsPicture.IsEmpty())
- return wsValue;
-
- ASSERT(GetNode());
- CXFA_LocaleMgr* pLocalMgr = GetNode()->GetDocument()->GetLocalMgr();
- IFX_Locale* pLocale = m_pNode->GetLocale();
- CXFA_LocaleValue widgetValue = XFA_GetLocaleValue(GetNode());
- if (widgetValue.ValidateValue(wsValue, wsPicture, pLocale, &wsPicture)) {
- widgetValue = CXFA_LocaleValue(widgetValue.GetType(), wsValue, wsPicture,
- pLocale, pLocalMgr);
- return widgetValue.GetValue();
- }
- return wsValue;
-}
-
-WideString CXFA_WidgetAcc::GetFormatDataValue(const WideString& wsValue) {
- if (wsValue.IsEmpty())
- return L"";
-
- WideString wsPicture = GetPictureContent(XFA_VALUEPICTURE_DataBind);
- if (wsPicture.IsEmpty())
- return wsValue;
-
- WideString wsFormattedValue = wsValue;
- if (IFX_Locale* pLocale = m_pNode->GetLocale()) {
- ASSERT(GetNode());
- CXFA_Value* pNodeValue =
- GetNode()->GetChild<CXFA_Value>(0, XFA_Element::Value, false);
- if (!pNodeValue)
- return wsValue;
-
- CXFA_Node* pValueChild = pNodeValue->GetFirstChild();
- if (!pValueChild)
- return wsValue;
-
- int32_t iVTType = XFA_VT_NULL;
- switch (pValueChild->GetElementType()) {
- case XFA_Element::Decimal:
- iVTType = XFA_VT_DECIMAL;
- break;
- case XFA_Element::Float:
- iVTType = XFA_VT_FLOAT;
- break;
- case XFA_Element::Date:
- iVTType = XFA_VT_DATE;
- break;
- case XFA_Element::Time:
- iVTType = XFA_VT_TIME;
- break;
- case XFA_Element::DateTime:
- iVTType = XFA_VT_DATETIME;
- break;
- case XFA_Element::Boolean:
- iVTType = XFA_VT_BOOLEAN;
- break;
- case XFA_Element::Integer:
- iVTType = XFA_VT_INTEGER;
- break;
- case XFA_Element::Text:
- iVTType = XFA_VT_TEXT;
- break;
- default:
- iVTType = XFA_VT_NULL;
- break;
- }
- CXFA_LocaleMgr* pLocalMgr = GetNode()->GetDocument()->GetLocalMgr();
- CXFA_LocaleValue widgetValue(iVTType, wsValue, pLocalMgr);
- switch (widgetValue.GetType()) {
- case XFA_VT_DATE: {
- WideString wsDate, wsTime;
- if (SplitDateTime(wsValue, wsDate, wsTime)) {
- CXFA_LocaleValue date(XFA_VT_DATE, wsDate, pLocalMgr);
- if (date.FormatPatterns(wsFormattedValue, wsPicture, pLocale,
- XFA_VALUEPICTURE_DataBind)) {
- return wsFormattedValue;
- }
- }
- break;
- }
- case XFA_VT_TIME: {
- WideString wsDate, wsTime;
- if (SplitDateTime(wsValue, wsDate, wsTime)) {
- CXFA_LocaleValue time(XFA_VT_TIME, wsTime, pLocalMgr);
- if (time.FormatPatterns(wsFormattedValue, wsPicture, pLocale,
- XFA_VALUEPICTURE_DataBind)) {
- return wsFormattedValue;
- }
- }
- break;
- }
- default:
- break;
- }
- widgetValue.FormatPatterns(wsFormattedValue, wsPicture, pLocale,
- XFA_VALUEPICTURE_DataBind);
- }
- return wsFormattedValue;
-}
-
-WideString CXFA_WidgetAcc::NormalizeNumStr(const WideString& wsValue) {
- if (wsValue.IsEmpty())
- return L"";
-
- WideString wsOutput = wsValue;
- wsOutput.TrimLeft('0');
-
- if (!wsOutput.IsEmpty() && wsOutput.Contains('.') && GetFracDigits() != -1) {
- wsOutput.TrimRight(L"0");
- wsOutput.TrimRight(L".");
- }
- if (wsOutput.IsEmpty() || wsOutput[0] == '.')
- wsOutput.InsertAtFront('0');
-
- return wsOutput;
-}
-
-WideString CXFA_WidgetAcc::FormatNumStr(const WideString& wsValue,
- IFX_Locale* pLocale) {
- if (wsValue.IsEmpty())
- return L"";
-
- WideString wsSrcNum = wsValue;
- WideString wsGroupSymbol =
- pLocale->GetNumbericSymbol(FX_LOCALENUMSYMBOL_Grouping);
- bool bNeg = false;
- if (wsSrcNum[0] == '-') {
- bNeg = true;
- wsSrcNum.Delete(0, 1);
- }
-
- auto dot_index = wsSrcNum.Find('.');
- dot_index = !dot_index.has_value() ? wsSrcNum.GetLength() : dot_index;
-
- if (dot_index.value() < 1)
- return L"";
-
- size_t nPos = dot_index.value() % 3;
- WideString wsOutput;
- for (size_t i = 0; i < dot_index.value(); i++) {
- if (i % 3 == nPos && i != 0)
- wsOutput += wsGroupSymbol;
-
- wsOutput += wsSrcNum[i];
- }
- if (dot_index.value() < wsSrcNum.GetLength()) {
- wsOutput += pLocale->GetNumbericSymbol(FX_LOCALENUMSYMBOL_Decimal);
- wsOutput += wsSrcNum.Right(wsSrcNum.GetLength() - dot_index.value() - 1);
- }
- if (bNeg)
- return pLocale->GetNumbericSymbol(FX_LOCALENUMSYMBOL_Minus) + wsOutput;
-
- return wsOutput;
-}
-
-void CXFA_WidgetAcc::InsertListTextItem(CXFA_Node* pItems,
- const WideString& wsText,
- int32_t nIndex) {
- CXFA_Node* pText = pItems->CreateSamePacketNode(XFA_Element::Text);
- pItems->InsertChild(nIndex, pText);
- pText->JSObject()->SetContent(wsText, wsText, false, false, false);
-}
-
-WideString CXFA_WidgetAcc::NumericLimit(const WideString& wsValue,
- int32_t iLead,
- int32_t iTread) const {
- if ((iLead == -1) && (iTread == -1))
- return wsValue;
-
- WideString wsRet;
- int32_t iLead_ = 0, iTread_ = -1;
- int32_t iCount = wsValue.GetLength();
- if (iCount == 0)
- return wsValue;
-
- int32_t i = 0;
- if (wsValue[i] == L'-') {
- wsRet += L'-';
- i++;
- }
- for (; i < iCount; i++) {
- wchar_t wc = wsValue[i];
- if (FXSYS_isDecimalDigit(wc)) {
- if (iLead >= 0) {
- iLead_++;
- if (iLead_ > iLead)
- return L"0";
- } else if (iTread_ >= 0) {
- iTread_++;
- if (iTread_ > iTread) {
- if (iTread != -1) {
- CFX_Decimal wsDeci = CFX_Decimal(wsValue.AsStringView());
- wsDeci.SetScale(iTread);
- wsRet = wsDeci;
- }
- return wsRet;
- }
- }
- } else if (wc == L'.') {
- iTread_ = 0;
- iLead = -1;
- }
- wsRet += wc;
- }
- return wsRet;
-}
diff --git a/xfa/fxfa/cxfa_widgetacc.h b/xfa/fxfa/cxfa_widgetacc.h
deleted file mode 100644
index 8e0301865d..0000000000
--- a/xfa/fxfa/cxfa_widgetacc.h
+++ /dev/null
@@ -1,209 +0,0 @@
-// Copyright 2014 PDFium Authors. All rights reserved.
-// Use of this source code is governed by a BSD-style license that can be
-// found in the LICENSE file.
-
-// Original code copyright 2014 Foxit Software Inc. http://www.foxitsoftware.com
-
-#ifndef XFA_FXFA_CXFA_WIDGETACC_H_
-#define XFA_FXFA_CXFA_WIDGETACC_H_
-
-#include <memory>
-#include <utility>
-#include <vector>
-
-#include "core/fxcrt/fx_coordinates.h"
-#include "core/fxcrt/fx_string.h"
-#include "core/fxcrt/fx_system.h"
-#include "core/fxcrt/retain_ptr.h"
-#include "core/fxge/dib/cfx_dibitmap.h"
-#include "core/fxge/fx_dib.h"
-#include "xfa/fxfa/fxfa_basic.h"
-
-enum XFA_CHECKSTATE {
- XFA_CHECKSTATE_On = 0,
- XFA_CHECKSTATE_Off = 1,
- XFA_CHECKSTATE_Neutral = 2,
-};
-
-enum XFA_VALUEPICTURE {
- XFA_VALUEPICTURE_Raw = 0,
- XFA_VALUEPICTURE_Display,
- XFA_VALUEPICTURE_Edit,
- XFA_VALUEPICTURE_DataBind,
-};
-
-class CFGAS_GEFont;
-class CXFA_Bind;
-class CXFA_Border;
-class CXFA_Calculate;
-class CXFA_Caption;
-class CXFA_Event;
-class CXFA_EventParam;
-class CXFA_FFApp;
-class CXFA_FFDoc;
-class CXFA_FFDocView;
-class CXFA_FFWidget;
-class CXFA_Font;
-class CXFA_Margin;
-class CXFA_Node;
-class CXFA_Script;
-class CXFA_Para;
-class CXFA_TextLayout;
-class CXFA_Value;
-class CXFA_Validate;
-class CXFA_WidgetLayoutData;
-class IFX_Locale;
-
-class CXFA_WidgetAcc {
- public:
- explicit CXFA_WidgetAcc(CXFA_Node* pNode);
- ~CXFA_WidgetAcc();
-
- void ResetData();
-
- CXFA_FFWidget* GetNextWidget(CXFA_FFWidget* pWidget);
- void StartWidgetLayout(CXFA_FFDoc* doc,
- float& fCalcWidth,
- float& fCalcHeight);
- bool FindSplitPos(CXFA_FFDocView* docView,
- int32_t iBlockIndex,
- float& fCalcHeight);
-
- bool LoadCaption(CXFA_FFDoc* doc);
- CXFA_TextLayout* GetCaptionTextLayout();
-
- void LoadText(CXFA_FFDoc* doc);
- CXFA_TextLayout* GetTextLayout();
-
- bool LoadImageImage(CXFA_FFDoc* doc);
- bool LoadImageEditImage(CXFA_FFDoc* doc);
- void GetImageDpi(int32_t& iImageXDpi, int32_t& iImageYDpi);
- void GetImageEditDpi(int32_t& iImageXDpi, int32_t& iImageYDpi);
-
- RetainPtr<CFX_DIBitmap> GetImageImage();
- RetainPtr<CFX_DIBitmap> GetImageEditImage();
- void SetImageEdit(const WideString& wsContentType,
- const WideString& wsHref,
- const WideString& wsData);
- void SetImageImage(const RetainPtr<CFX_DIBitmap>& newImage);
- void SetImageEditImage(const RetainPtr<CFX_DIBitmap>& newImage);
- void UpdateUIDisplay(CXFA_FFDocView* docView, CXFA_FFWidget* pExcept);
-
- RetainPtr<CFGAS_GEFont> GetFDEFont(CXFA_FFDoc* doc);
-
- CXFA_Node* GetNode() const { return m_pNode; }
-
- bool IsOpenAccess() const;
- bool IsListBox();
- bool IsAllowNeutral();
- bool IsRadioButton();
- bool IsChoiceListAllowTextEntry();
- bool IsMultiLine();
-
- XFA_AttributeEnum GetButtonHighlight();
- bool HasButtonRollover() const;
- bool HasButtonDown() const;
-
- bool IsCheckButtonRound();
- XFA_AttributeEnum GetCheckButtonMark();
- float GetCheckButtonSize();
-
- XFA_CHECKSTATE GetCheckState();
- void SetCheckState(XFA_CHECKSTATE eCheckState, bool bNotify);
-
- CXFA_Node* GetSelectedMember();
- CXFA_Node* SetSelectedMember(const WideStringView& wsName, bool bNotify);
- void SetSelectedMemberByValue(const WideStringView& wsValue,
- bool bNotify,
- bool bScriptModify,
- bool bSyncData);
-
- CXFA_Node* GetExclGroupFirstMember();
- CXFA_Node* GetExclGroupNextMember(CXFA_Node* pNode);
-
- int32_t CountChoiceListItems(bool bSaveValue);
- Optional<WideString> GetChoiceListItem(int32_t nIndex, bool bSaveValue);
- bool IsChoiceListMultiSelect();
- bool IsChoiceListCommitOnSelect();
- std::vector<WideString> GetChoiceListItems(bool bSaveValue);
-
- int32_t CountSelectedItems();
- int32_t GetSelectedItem(int32_t nIndex);
- std::vector<int32_t> GetSelectedItems();
- std::vector<WideString> GetSelectedItemsValue();
- void SetSelectedItems(const std::vector<int32_t>& iSelArray,
- bool bNotify,
- bool bScriptModify,
- bool bSyncData);
- void InsertItem(const WideString& wsLabel,
- const WideString& wsValue,
- bool bNotify);
- bool DeleteItem(int32_t nIndex, bool bNotify, bool bScriptModify);
- void ClearAllSelections();
-
- bool GetItemState(int32_t nIndex);
- void SetItemState(int32_t nIndex,
- bool bSelected,
- bool bNotify,
- bool bScriptModify,
- bool bSyncData);
-
- WideString GetItemValue(const WideStringView& wsLabel);
-
- bool IsHorizontalScrollPolicyOff();
- bool IsVerticalScrollPolicyOff();
- Optional<int32_t> GetNumberOfCells();
-
- bool SetValue(XFA_VALUEPICTURE eValueType, const WideString& wsValue);
- WideString GetValue(XFA_VALUEPICTURE eValueType);
-
- WideString GetPictureContent(XFA_VALUEPICTURE ePicture);
- WideString GetNormalizeDataValue(const WideString& wsValue);
- WideString GetFormatDataValue(const WideString& wsValue);
- WideString NormalizeNumStr(const WideString& wsValue);
-
- WideString GetPasswordChar();
- std::pair<XFA_Element, int32_t> GetMaxChars();
- int32_t GetFracDigits();
- int32_t GetLeadDigits();
-
- WideString NumericLimit(const WideString& wsValue,
- int32_t iLead,
- int32_t iTread) const;
-
- private:
- void CalcCaptionSize(CXFA_FFDoc* doc, CFX_SizeF& szCap);
- bool CalculateFieldAutoSize(CXFA_FFDoc* doc, CFX_SizeF& size);
- bool CalculateWidgetAutoSize(CFX_SizeF& size);
- bool CalculateTextEditAutoSize(CXFA_FFDoc* doc, CFX_SizeF& size);
- bool CalculateCheckButtonAutoSize(CXFA_FFDoc* doc, CFX_SizeF& size);
- bool CalculatePushButtonAutoSize(CXFA_FFDoc* doc, CFX_SizeF& size);
- CFX_SizeF CalculateImageSize(float img_width,
- float img_height,
- float dpi_x,
- float dpi_y);
- bool CalculateImageEditAutoSize(CXFA_FFDoc* doc, CFX_SizeF& size);
- bool CalculateImageAutoSize(CXFA_FFDoc* doc, CFX_SizeF& size);
- float CalculateWidgetAutoHeight(float fHeightCalc);
- float CalculateWidgetAutoWidth(float fWidthCalc);
- float GetWidthWithoutMargin(float fWidthCalc);
- float GetHeightWithoutMargin(float fHeightCalc);
- void CalculateTextContentSize(CXFA_FFDoc* doc, CFX_SizeF& size);
- void CalculateAccWidthAndHeight(CXFA_FFDoc* doc,
- XFA_Element eUIType,
- float& fWidth,
- float& fCalcHeight);
- void InitLayoutData();
- void StartTextLayout(CXFA_FFDoc* doc, float& fCalcWidth, float& fCalcHeight);
-
- void InsertListTextItem(CXFA_Node* pItems,
- const WideString& wsText,
- int32_t nIndex);
- WideString FormatNumStr(const WideString& wsValue, IFX_Locale* pLocale);
- void GetItemLabel(const WideStringView& wsValue, WideString& wsLabel);
-
- std::unique_ptr<CXFA_WidgetLayoutData> m_pLayoutData;
- CXFA_Node* m_pNode;
-};
-
-#endif // XFA_FXFA_CXFA_WIDGETACC_H_
diff --git a/xfa/fxfa/parser/cxfa_localevalue.h b/xfa/fxfa/parser/cxfa_localevalue.h
index 60de601c02..44db7b15d9 100644
--- a/xfa/fxfa/parser/cxfa_localevalue.h
+++ b/xfa/fxfa/parser/cxfa_localevalue.h
@@ -9,7 +9,7 @@
#include "core/fxcrt/fx_string.h"
#include "core/fxcrt/fx_system.h"
-#include "xfa/fxfa/cxfa_widgetacc.h"
+#include "xfa/fxfa/parser/cxfa_node.h"
class IFX_Locale;
class CFX_DateTime;
diff --git a/xfa/fxfa/parser/cxfa_node.cpp b/xfa/fxfa/parser/cxfa_node.cpp
index ba882a2b9d..988d1e2ee5 100644
--- a/xfa/fxfa/parser/cxfa_node.cpp
+++ b/xfa/fxfa/parser/cxfa_node.cpp
@@ -6,6 +6,7 @@
#include "xfa/fxfa/parser/cxfa_node.h"
+#include <algorithm>
#include <map>
#include <memory>
#include <set>
@@ -20,26 +21,35 @@
#include "core/fxcrt/xml/cfx_xmlelement.h"
#include "core/fxcrt/xml/cfx_xmlnode.h"
#include "core/fxcrt/xml/cfx_xmltext.h"
+#include "core/fxge/dib/cfx_dibitmap.h"
#include "fxjs/cfxjse_engine.h"
#include "fxjs/cfxjse_value.h"
#include "fxjs/xfa/cjx_node.h"
#include "third_party/base/logging.h"
#include "third_party/base/ptr_util.h"
#include "third_party/base/stl_util.h"
+#include "xfa/fde/cfde_textout.h"
+#include "xfa/fgas/font/cfgas_fontmgr.h"
#include "xfa/fxfa/cxfa_eventparam.h"
#include "xfa/fxfa/cxfa_ffapp.h"
#include "xfa/fxfa/cxfa_ffdocview.h"
#include "xfa/fxfa/cxfa_ffnotify.h"
#include "xfa/fxfa/cxfa_ffwidget.h"
+#include "xfa/fxfa/cxfa_fontmgr.h"
+#include "xfa/fxfa/cxfa_textprovider.h"
#include "xfa/fxfa/parser/cxfa_arraynodelist.h"
#include "xfa/fxfa/parser/cxfa_attachnodelist.h"
#include "xfa/fxfa/parser/cxfa_bind.h"
#include "xfa/fxfa/parser/cxfa_border.h"
#include "xfa/fxfa/parser/cxfa_calculate.h"
#include "xfa/fxfa/parser/cxfa_caption.h"
+#include "xfa/fxfa/parser/cxfa_comb.h"
+#include "xfa/fxfa/parser/cxfa_decimal.h"
#include "xfa/fxfa/parser/cxfa_document.h"
#include "xfa/fxfa/parser/cxfa_event.h"
#include "xfa/fxfa/parser/cxfa_font.h"
+#include "xfa/fxfa/parser/cxfa_format.h"
+#include "xfa/fxfa/parser/cxfa_image.h"
#include "xfa/fxfa/parser/cxfa_items.h"
#include "xfa/fxfa/parser/cxfa_keep.h"
#include "xfa/fxfa/parser/cxfa_layoutprocessor.h"
@@ -49,6 +59,7 @@
#include "xfa/fxfa/parser/cxfa_nodeiteratortemplate.h"
#include "xfa/fxfa/parser/cxfa_occur.h"
#include "xfa/fxfa/parser/cxfa_para.h"
+#include "xfa/fxfa/parser/cxfa_picture.h"
#include "xfa/fxfa/parser/cxfa_simple_parser.h"
#include "xfa/fxfa/parser/cxfa_stroke.h"
#include "xfa/fxfa/parser/cxfa_subform.h"
@@ -59,10 +70,301 @@
#include "xfa/fxfa/parser/xfa_basic_data.h"
#include "xfa/fxfa/parser/xfa_utils.h"
+class CXFA_WidgetLayoutData {
+ public:
+ CXFA_WidgetLayoutData() : m_fWidgetHeight(-1) {}
+ virtual ~CXFA_WidgetLayoutData() {}
+
+ float m_fWidgetHeight;
+};
+
namespace {
constexpr uint8_t kMaxExecuteRecursion = 2;
+constexpr uint8_t g_inv_base64[128] = {
+ 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255,
+ 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255,
+ 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 62, 255,
+ 255, 255, 63, 52, 53, 54, 55, 56, 57, 58, 59, 60, 61, 255, 255,
+ 255, 255, 255, 255, 255, 0, 1, 2, 3, 4, 5, 6, 7, 8, 9,
+ 10, 11, 12, 13, 14, 15, 16, 17, 18, 19, 20, 21, 22, 23, 24,
+ 25, 255, 255, 255, 255, 255, 255, 26, 27, 28, 29, 30, 31, 32, 33,
+ 34, 35, 36, 37, 38, 39, 40, 41, 42, 43, 44, 45, 46, 47, 48,
+ 49, 50, 51, 255, 255, 255, 255, 255,
+};
+
+uint8_t* XFA_RemoveBase64Whitespace(const uint8_t* pStr, int32_t iLen) {
+ uint8_t* pCP;
+ int32_t i = 0, j = 0;
+ if (iLen == 0) {
+ iLen = strlen((char*)pStr);
+ }
+ pCP = FX_Alloc(uint8_t, iLen + 1);
+ for (; i < iLen; i++) {
+ if ((pStr[i] & 128) == 0) {
+ if (g_inv_base64[pStr[i]] != 0xFF || pStr[i] == '=') {
+ pCP[j++] = pStr[i];
+ }
+ }
+ }
+ pCP[j] = '\0';
+ return pCP;
+}
+
+int32_t XFA_Base64Decode(const char* pStr, uint8_t* pOutBuffer) {
+ if (!pStr) {
+ return 0;
+ }
+ uint8_t* pBuffer =
+ XFA_RemoveBase64Whitespace((uint8_t*)pStr, strlen((char*)pStr));
+ if (!pBuffer) {
+ return 0;
+ }
+ int32_t iLen = strlen((char*)pBuffer);
+ int32_t i = 0, j = 0;
+ uint32_t dwLimb = 0;
+ for (; i + 3 < iLen; i += 4) {
+ if (pBuffer[i] == '=' || pBuffer[i + 1] == '=' || pBuffer[i + 2] == '=' ||
+ pBuffer[i + 3] == '=') {
+ if (pBuffer[i] == '=' || pBuffer[i + 1] == '=') {
+ break;
+ }
+ if (pBuffer[i + 2] == '=') {
+ dwLimb = ((uint32_t)g_inv_base64[pBuffer[i]] << 6) |
+ ((uint32_t)g_inv_base64[pBuffer[i + 1]]);
+ pOutBuffer[j] = (uint8_t)(dwLimb >> 4) & 0xFF;
+ j++;
+ } else {
+ dwLimb = ((uint32_t)g_inv_base64[pBuffer[i]] << 12) |
+ ((uint32_t)g_inv_base64[pBuffer[i + 1]] << 6) |
+ ((uint32_t)g_inv_base64[pBuffer[i + 2]]);
+ pOutBuffer[j] = (uint8_t)(dwLimb >> 10) & 0xFF;
+ pOutBuffer[j + 1] = (uint8_t)(dwLimb >> 2) & 0xFF;
+ j += 2;
+ }
+ } else {
+ dwLimb = ((uint32_t)g_inv_base64[pBuffer[i]] << 18) |
+ ((uint32_t)g_inv_base64[pBuffer[i + 1]] << 12) |
+ ((uint32_t)g_inv_base64[pBuffer[i + 2]] << 6) |
+ ((uint32_t)g_inv_base64[pBuffer[i + 3]]);
+ pOutBuffer[j] = (uint8_t)(dwLimb >> 16) & 0xff;
+ pOutBuffer[j + 1] = (uint8_t)(dwLimb >> 8) & 0xff;
+ pOutBuffer[j + 2] = (uint8_t)(dwLimb)&0xff;
+ j += 3;
+ }
+ }
+ FX_Free(pBuffer);
+ return j;
+}
+
+FXCODEC_IMAGE_TYPE XFA_GetImageType(const WideString& wsType) {
+ WideString wsContentType(wsType);
+ wsContentType.MakeLower();
+ if (wsContentType == L"image/jpg")
+ return FXCODEC_IMAGE_JPG;
+ if (wsContentType == L"image/png")
+ return FXCODEC_IMAGE_PNG;
+ if (wsContentType == L"image/gif")
+ return FXCODEC_IMAGE_GIF;
+ if (wsContentType == L"image/bmp")
+ return FXCODEC_IMAGE_BMP;
+ if (wsContentType == L"image/tif")
+ return FXCODEC_IMAGE_TIF;
+ return FXCODEC_IMAGE_UNKNOWN;
+}
+
+RetainPtr<CFX_DIBitmap> XFA_LoadImageData(CXFA_FFDoc* pDoc,
+ CXFA_Image* pImage,
+ bool& bNameImage,
+ int32_t& iImageXDpi,
+ int32_t& iImageYDpi) {
+ WideString wsHref = pImage->GetHref();
+ WideString wsImage = pImage->GetContent();
+ if (wsHref.IsEmpty() && wsImage.IsEmpty())
+ return nullptr;
+
+ FXCODEC_IMAGE_TYPE type = XFA_GetImageType(pImage->GetContentType());
+ ByteString bsContent;
+ uint8_t* pImageBuffer = nullptr;
+ RetainPtr<IFX_SeekableReadStream> pImageFileRead;
+ if (wsImage.GetLength() > 0) {
+ XFA_AttributeEnum iEncoding = pImage->GetTransferEncoding();
+ if (iEncoding == XFA_AttributeEnum::Base64) {
+ ByteString bsData = wsImage.UTF8Encode();
+ int32_t iLength = bsData.GetLength();
+ pImageBuffer = FX_Alloc(uint8_t, iLength);
+ int32_t iRead = XFA_Base64Decode(bsData.c_str(), pImageBuffer);
+ if (iRead > 0) {
+ pImageFileRead =
+ pdfium::MakeRetain<CFX_MemoryStream>(pImageBuffer, iRead, false);
+ }
+ } else {
+ bsContent = ByteString::FromUnicode(wsImage);
+ pImageFileRead = pdfium::MakeRetain<CFX_MemoryStream>(
+ const_cast<uint8_t*>(bsContent.raw_str()), bsContent.GetLength(),
+ false);
+ }
+ } else {
+ WideString wsURL = wsHref;
+ if (wsURL.Left(7) != L"http://" && wsURL.Left(6) != L"ftp://") {
+ RetainPtr<CFX_DIBitmap> pBitmap =
+ pDoc->GetPDFNamedImage(wsURL.AsStringView(), iImageXDpi, iImageYDpi);
+ if (pBitmap) {
+ bNameImage = true;
+ return pBitmap;
+ }
+ }
+ pImageFileRead = pDoc->GetDocEnvironment()->OpenLinkedFile(pDoc, wsURL);
+ }
+ if (!pImageFileRead) {
+ FX_Free(pImageBuffer);
+ return nullptr;
+ }
+ bNameImage = false;
+ RetainPtr<CFX_DIBitmap> pBitmap =
+ XFA_LoadImageFromBuffer(pImageFileRead, type, iImageXDpi, iImageYDpi);
+ FX_Free(pImageBuffer);
+ return pBitmap;
+}
+
+class CXFA_TextLayoutData : public CXFA_WidgetLayoutData {
+ public:
+ CXFA_TextLayoutData() {}
+ ~CXFA_TextLayoutData() override {}
+
+ CXFA_TextLayout* GetTextLayout() const { return m_pTextLayout.get(); }
+ CXFA_TextProvider* GetTextProvider() const { return m_pTextProvider.get(); }
+
+ void LoadText(CXFA_FFDoc* doc, CXFA_Node* pNode) {
+ if (m_pTextLayout)
+ return;
+
+ m_pTextProvider =
+ pdfium::MakeUnique<CXFA_TextProvider>(pNode, XFA_TEXTPROVIDERTYPE_Text);
+ m_pTextLayout =
+ pdfium::MakeUnique<CXFA_TextLayout>(doc, m_pTextProvider.get());
+ }
+
+ private:
+ std::unique_ptr<CXFA_TextLayout> m_pTextLayout;
+ std::unique_ptr<CXFA_TextProvider> m_pTextProvider;
+};
+
+class CXFA_ImageLayoutData : public CXFA_WidgetLayoutData {
+ public:
+ CXFA_ImageLayoutData()
+ : m_bNamedImage(false), m_iImageXDpi(0), m_iImageYDpi(0) {}
+
+ ~CXFA_ImageLayoutData() override {}
+
+ bool LoadImageData(CXFA_FFDoc* doc, CXFA_Node* pNode) {
+ if (m_pDIBitmap)
+ return true;
+
+ CXFA_Value* value = pNode->GetFormValueIfExists();
+ if (!value)
+ return false;
+
+ CXFA_Image* image = value->GetImageIfExists();
+ if (!image)
+ return false;
+
+ pNode->SetImageImage(XFA_LoadImageData(doc, image, m_bNamedImage,
+ m_iImageXDpi, m_iImageYDpi));
+ return !!m_pDIBitmap;
+ }
+
+ RetainPtr<CFX_DIBitmap> m_pDIBitmap;
+ bool m_bNamedImage;
+ int32_t m_iImageXDpi;
+ int32_t m_iImageYDpi;
+};
+
+class CXFA_FieldLayoutData : public CXFA_WidgetLayoutData {
+ public:
+ CXFA_FieldLayoutData() {}
+ ~CXFA_FieldLayoutData() override {}
+
+ bool LoadCaption(CXFA_FFDoc* doc, CXFA_Node* pNode) {
+ if (m_pCapTextLayout)
+ return true;
+ CXFA_Caption* caption = pNode->GetCaptionIfExists();
+ if (!caption || caption->IsHidden())
+ return false;
+
+ m_pCapTextProvider = pdfium::MakeUnique<CXFA_TextProvider>(
+ pNode, XFA_TEXTPROVIDERTYPE_Caption);
+ m_pCapTextLayout =
+ pdfium::MakeUnique<CXFA_TextLayout>(doc, m_pCapTextProvider.get());
+ return true;
+ }
+
+ std::unique_ptr<CXFA_TextLayout> m_pCapTextLayout;
+ std::unique_ptr<CXFA_TextProvider> m_pCapTextProvider;
+ std::unique_ptr<CFDE_TextOut> m_pTextOut;
+ std::vector<float> m_FieldSplitArray;
+};
+
+class CXFA_TextEditData : public CXFA_FieldLayoutData {};
+
+class CXFA_ImageEditData : public CXFA_FieldLayoutData {
+ public:
+ CXFA_ImageEditData()
+ : m_bNamedImage(false), m_iImageXDpi(0), m_iImageYDpi(0) {}
+
+ ~CXFA_ImageEditData() override {}
+
+ bool LoadImageData(CXFA_FFDoc* doc, CXFA_Node* pNode) {
+ if (m_pDIBitmap)
+ return true;
+
+ CXFA_Value* value = pNode->GetFormValueIfExists();
+ if (!value)
+ return false;
+
+ CXFA_Image* image = value->GetImageIfExists();
+ if (!image)
+ return false;
+
+ pNode->SetImageEditImage(XFA_LoadImageData(doc, image, m_bNamedImage,
+ m_iImageXDpi, m_iImageYDpi));
+ return !!m_pDIBitmap;
+ }
+
+ RetainPtr<CFX_DIBitmap> m_pDIBitmap;
+ bool m_bNamedImage;
+ int32_t m_iImageXDpi;
+ int32_t m_iImageYDpi;
+};
+
+bool SplitDateTime(const WideString& wsDateTime,
+ WideString& wsDate,
+ WideString& wsTime) {
+ wsDate = L"";
+ wsTime = L"";
+ if (wsDateTime.IsEmpty())
+ return false;
+
+ auto nSplitIndex = wsDateTime.Find('T');
+ if (!nSplitIndex.has_value())
+ nSplitIndex = wsDateTime.Find(' ');
+ if (!nSplitIndex.has_value())
+ return false;
+
+ wsDate = wsDateTime.Left(nSplitIndex.value());
+ if (!wsDate.IsEmpty()) {
+ if (!std::any_of(wsDate.begin(), wsDate.end(), std::iswdigit))
+ return false;
+ }
+ wsTime = wsDateTime.Right(wsDateTime.GetLength() - nSplitIndex.value() - 1);
+ if (!wsTime.IsEmpty()) {
+ if (!std::any_of(wsTime.begin(), wsTime.end(), std::iswdigit))
+ return false;
+ }
+ return true;
+}
+
std::vector<CXFA_Node*> NodesSortedByDocumentIdx(
const std::set<CXFA_Node*>& rgNodeSet) {
if (rgNodeSet.empty())
@@ -360,7 +662,8 @@ CXFA_Node::CXFA_Node(CXFA_Document* pDoc,
m_ePacket(ePacket),
m_uNodeFlags(XFA_NodeFlag_None),
m_dwNameHash(0),
- m_pAuxNode(nullptr) {
+ m_pAuxNode(nullptr),
+ m_pNode(this) {
ASSERT(m_pDocument);
}
@@ -735,7 +1038,7 @@ CXFA_Node* CXFA_Node::GetContainerNode() {
return nullptr;
if (eType == XFA_Element::Field) {
- CXFA_WidgetAcc* pFieldWidgetAcc = GetWidgetAcc();
+ CXFA_Node* pFieldWidgetAcc = GetWidgetAcc();
if (pFieldWidgetAcc && pFieldWidgetAcc->IsChoiceListMultiSelect())
return nullptr;
@@ -1829,11 +2132,6 @@ CXFA_Node* CXFA_Node::GetExclGroupIfExists() {
return pExcl;
}
-void CXFA_Node::SetWidgetReady() {
- acc_ = pdfium::MakeUnique<CXFA_WidgetAcc>(AsNode());
- is_widget_ready_ = true;
-}
-
int32_t CXFA_Node::ProcessEvent(CXFA_FFDocView* docView,
XFA_AttributeEnum iActivity,
CXFA_EventParam* pEventParam) {
@@ -2457,3 +2755,2134 @@ std::vector<CXFA_Event*> CXFA_Node::GetEventByActivity(
}
return events;
}
+
+void CXFA_Node::ResetData() {
+ WideString wsValue;
+ switch (m_pNode->GetUIType()) {
+ case XFA_Element::ImageEdit: {
+ CXFA_Value* imageValue = m_pNode->GetDefaultValueIfExists();
+ CXFA_Image* image = imageValue ? imageValue->GetImageIfExists() : nullptr;
+ WideString wsContentType, wsHref;
+ if (image) {
+ wsValue = image->GetContent();
+ wsContentType = image->GetContentType();
+ wsHref = image->GetHref();
+ }
+ SetImageEdit(wsContentType, wsHref, wsValue);
+ break;
+ }
+ case XFA_Element::ExclGroup: {
+ CXFA_Node* pNextChild = m_pNode->GetFirstContainerChild();
+ while (pNextChild) {
+ CXFA_Node* pChild = pNextChild;
+ if (!pChild->IsWidgetReady())
+ continue;
+
+ CXFA_Node* pAcc = pChild->GetWidgetAcc();
+ bool done = false;
+ if (wsValue.IsEmpty()) {
+ CXFA_Value* defValue = pAcc->GetNode()->GetDefaultValueIfExists();
+ if (defValue) {
+ wsValue = defValue->GetChildValueContent();
+ SetValue(XFA_VALUEPICTURE_Raw, wsValue);
+ pAcc->SetValue(XFA_VALUEPICTURE_Raw, wsValue);
+ done = true;
+ }
+ }
+ if (!done) {
+ CXFA_Items* pItems =
+ pChild->GetChild<CXFA_Items>(0, XFA_Element::Items, false);
+ if (!pItems)
+ continue;
+
+ WideString itemText;
+ if (pItems->CountChildren(XFA_Element::Unknown, false) > 1) {
+ itemText =
+ pItems->GetChild<CXFA_Node>(1, XFA_Element::Unknown, false)
+ ->JSObject()
+ ->GetContent(false);
+ }
+ pAcc->SetValue(XFA_VALUEPICTURE_Raw, itemText);
+ }
+ pNextChild = pChild->GetNextContainerSibling();
+ }
+ break;
+ }
+ case XFA_Element::ChoiceList:
+ ClearAllSelections();
+ default: {
+ CXFA_Value* defValue = m_pNode->GetDefaultValueIfExists();
+ if (defValue)
+ wsValue = defValue->GetChildValueContent();
+
+ SetValue(XFA_VALUEPICTURE_Raw, wsValue);
+ break;
+ }
+ }
+}
+
+void CXFA_Node::SetImageEdit(const WideString& wsContentType,
+ const WideString& wsHref,
+ const WideString& wsData) {
+ CXFA_Value* formValue = m_pNode->GetFormValueIfExists();
+ CXFA_Image* image = formValue ? formValue->GetImageIfExists() : nullptr;
+ if (image) {
+ image->SetContentType(WideString(wsContentType));
+ image->SetHref(wsHref);
+ }
+
+ m_pNode->JSObject()->SetContent(wsData, GetFormatDataValue(wsData), true,
+ false, true);
+
+ CXFA_Node* pBind = m_pNode->GetBindData();
+ if (!pBind) {
+ if (image)
+ image->SetTransferEncoding(XFA_AttributeEnum::Base64);
+ return;
+ }
+ pBind->JSObject()->SetCData(XFA_Attribute::ContentType, wsContentType, false,
+ false);
+ CXFA_Node* pHrefNode = pBind->GetFirstChild();
+ if (pHrefNode) {
+ pHrefNode->JSObject()->SetCData(XFA_Attribute::Value, wsHref, false, false);
+ } else {
+ CFX_XMLNode* pXMLNode = pBind->GetXMLMappingNode();
+ ASSERT(pXMLNode && pXMLNode->GetType() == FX_XMLNODE_Element);
+ static_cast<CFX_XMLElement*>(pXMLNode)->SetString(L"href", wsHref);
+ }
+}
+
+CXFA_FFWidget* CXFA_Node::GetNextWidget(CXFA_FFWidget* pWidget) {
+ return static_cast<CXFA_FFWidget*>(pWidget->GetNext());
+}
+
+void CXFA_Node::UpdateUIDisplay(CXFA_FFDocView* docView,
+ CXFA_FFWidget* pExcept) {
+ CXFA_FFWidget* pWidget = docView->GetWidgetForNode(m_pNode);
+ for (; pWidget; pWidget = GetNextWidget(pWidget)) {
+ if (pWidget == pExcept || !pWidget->IsLoaded() ||
+ (m_pNode->GetUIType() != XFA_Element::CheckButton &&
+ pWidget->IsFocused())) {
+ continue;
+ }
+ pWidget->UpdateFWLData();
+ pWidget->AddInvalidateRect();
+ }
+}
+
+void CXFA_Node::CalcCaptionSize(CXFA_FFDoc* doc, CFX_SizeF& szCap) {
+ CXFA_Caption* caption = m_pNode->GetCaptionIfExists();
+ if (!caption || !caption->IsVisible())
+ return;
+
+ LoadCaption(doc);
+
+ XFA_Element eUIType = m_pNode->GetUIType();
+ XFA_AttributeEnum iCapPlacement = caption->GetPlacementType();
+ float fCapReserve = caption->GetReserve();
+ const bool bVert = iCapPlacement == XFA_AttributeEnum::Top ||
+ iCapPlacement == XFA_AttributeEnum::Bottom;
+ const bool bReserveExit = fCapReserve > 0.01;
+ CXFA_TextLayout* pCapTextLayout =
+ static_cast<CXFA_FieldLayoutData*>(m_pLayoutData.get())
+ ->m_pCapTextLayout.get();
+ if (pCapTextLayout) {
+ if (!bVert && eUIType != XFA_Element::Button)
+ szCap.width = fCapReserve;
+
+ CFX_SizeF minSize;
+ szCap = pCapTextLayout->CalcSize(minSize, szCap);
+ if (bReserveExit)
+ bVert ? szCap.height = fCapReserve : szCap.width = fCapReserve;
+ } else {
+ float fFontSize = 10.0f;
+ CXFA_Font* font = caption->GetFontIfExists();
+ if (font) {
+ fFontSize = font->GetFontSize();
+ } else {
+ CXFA_Font* widgetfont = m_pNode->GetFontIfExists();
+ if (widgetfont)
+ fFontSize = widgetfont->GetFontSize();
+ }
+
+ if (bVert) {
+ szCap.height = fCapReserve > 0 ? fCapReserve : fFontSize;
+ } else {
+ szCap.width = fCapReserve > 0 ? fCapReserve : 0;
+ szCap.height = fFontSize;
+ }
+ }
+
+ CXFA_Margin* captionMargin = caption->GetMarginIfExists();
+ if (!captionMargin)
+ return;
+
+ float fLeftInset = captionMargin->GetLeftInset();
+ float fTopInset = captionMargin->GetTopInset();
+ float fRightInset = captionMargin->GetRightInset();
+ float fBottomInset = captionMargin->GetBottomInset();
+ if (bReserveExit) {
+ bVert ? (szCap.width += fLeftInset + fRightInset)
+ : (szCap.height += fTopInset + fBottomInset);
+ } else {
+ szCap.width += fLeftInset + fRightInset;
+ szCap.height += fTopInset + fBottomInset;
+ }
+}
+
+bool CXFA_Node::CalculateFieldAutoSize(CXFA_FFDoc* doc, CFX_SizeF& size) {
+ CFX_SizeF szCap;
+ CalcCaptionSize(doc, szCap);
+
+ CFX_RectF rtUIMargin = m_pNode->GetUIMargin();
+ size.width += rtUIMargin.left + rtUIMargin.width;
+ size.height += rtUIMargin.top + rtUIMargin.height;
+ if (szCap.width > 0 && szCap.height > 0) {
+ CXFA_Caption* caption = m_pNode->GetCaptionIfExists();
+ XFA_AttributeEnum placement = caption ? caption->GetPlacementType()
+ : CXFA_Caption::kDefaultPlacementType;
+ switch (placement) {
+ case XFA_AttributeEnum::Left:
+ case XFA_AttributeEnum::Right:
+ case XFA_AttributeEnum::Inline: {
+ size.width += szCap.width;
+ size.height = std::max(size.height, szCap.height);
+ } break;
+ case XFA_AttributeEnum::Top:
+ case XFA_AttributeEnum::Bottom: {
+ size.height += szCap.height;
+ size.width = std::max(size.width, szCap.width);
+ }
+ default:
+ break;
+ }
+ }
+ return CalculateWidgetAutoSize(size);
+}
+
+bool CXFA_Node::CalculateWidgetAutoSize(CFX_SizeF& size) {
+ CXFA_Margin* margin = m_pNode->GetMarginIfExists();
+ if (margin) {
+ size.width += margin->GetLeftInset() + margin->GetRightInset();
+ size.height += margin->GetTopInset() + margin->GetBottomInset();
+ }
+
+ CXFA_Para* para = m_pNode->GetParaIfExists();
+ if (para)
+ size.width += para->GetMarginLeft() + para->GetTextIndent();
+
+ Optional<float> width = m_pNode->TryWidth();
+ if (width) {
+ size.width = *width;
+ } else {
+ Optional<float> min = m_pNode->TryMinWidth();
+ if (min)
+ size.width = std::max(size.width, *min);
+
+ Optional<float> max = m_pNode->TryMaxWidth();
+ if (max && *max > 0)
+ size.width = std::min(size.width, *max);
+ }
+
+ Optional<float> height = m_pNode->TryHeight();
+ if (height) {
+ size.height = *height;
+ } else {
+ Optional<float> min = m_pNode->TryMinHeight();
+ if (min)
+ size.height = std::max(size.height, *min);
+
+ Optional<float> max = m_pNode->TryMaxHeight();
+ if (max && *max > 0)
+ size.height = std::min(size.height, *max);
+ }
+ return true;
+}
+
+void CXFA_Node::CalculateTextContentSize(CXFA_FFDoc* doc, CFX_SizeF& size) {
+ float fFontSize = m_pNode->GetFontSize();
+ WideString wsText = GetValue(XFA_VALUEPICTURE_Display);
+ if (wsText.IsEmpty()) {
+ size.height += fFontSize;
+ return;
+ }
+
+ wchar_t wcEnter = '\n';
+ wchar_t wsLast = wsText[wsText.GetLength() - 1];
+ if (wsLast == wcEnter)
+ wsText = wsText + wcEnter;
+
+ CXFA_FieldLayoutData* layoutData =
+ static_cast<CXFA_FieldLayoutData*>(m_pLayoutData.get());
+ if (!layoutData->m_pTextOut) {
+ layoutData->m_pTextOut = pdfium::MakeUnique<CFDE_TextOut>();
+ CFDE_TextOut* pTextOut = layoutData->m_pTextOut.get();
+ pTextOut->SetFont(GetFDEFont(doc));
+ pTextOut->SetFontSize(fFontSize);
+ pTextOut->SetLineBreakTolerance(fFontSize * 0.2f);
+ pTextOut->SetLineSpace(m_pNode->GetLineHeight());
+
+ FDE_TextStyle dwStyles;
+ dwStyles.last_line_height_ = true;
+ if (m_pNode->GetUIType() == XFA_Element::TextEdit && IsMultiLine())
+ dwStyles.line_wrap_ = true;
+
+ pTextOut->SetStyles(dwStyles);
+ }
+ layoutData->m_pTextOut->CalcLogicSize(wsText, size);
+}
+
+bool CXFA_Node::CalculateTextEditAutoSize(CXFA_FFDoc* doc, CFX_SizeF& size) {
+ if (size.width > 0) {
+ CFX_SizeF szOrz = size;
+ CFX_SizeF szCap;
+ CalcCaptionSize(doc, szCap);
+ bool bCapExit = szCap.width > 0.01 && szCap.height > 0.01;
+ XFA_AttributeEnum iCapPlacement = XFA_AttributeEnum::Unknown;
+ if (bCapExit) {
+ CXFA_Caption* caption = m_pNode->GetCaptionIfExists();
+ iCapPlacement = caption ? caption->GetPlacementType()
+ : CXFA_Caption::kDefaultPlacementType;
+ switch (iCapPlacement) {
+ case XFA_AttributeEnum::Left:
+ case XFA_AttributeEnum::Right:
+ case XFA_AttributeEnum::Inline: {
+ size.width -= szCap.width;
+ }
+ default:
+ break;
+ }
+ }
+ CFX_RectF rtUIMargin = m_pNode->GetUIMargin();
+ size.width -= rtUIMargin.left + rtUIMargin.width;
+ CXFA_Margin* margin = m_pNode->GetMarginIfExists();
+ if (margin)
+ size.width -= margin->GetLeftInset() + margin->GetRightInset();
+
+ CalculateTextContentSize(doc, size);
+ size.height += rtUIMargin.top + rtUIMargin.height;
+ if (bCapExit) {
+ switch (iCapPlacement) {
+ case XFA_AttributeEnum::Left:
+ case XFA_AttributeEnum::Right:
+ case XFA_AttributeEnum::Inline: {
+ size.height = std::max(size.height, szCap.height);
+ } break;
+ case XFA_AttributeEnum::Top:
+ case XFA_AttributeEnum::Bottom: {
+ size.height += szCap.height;
+ }
+ default:
+ break;
+ }
+ }
+ size.width = szOrz.width;
+ return CalculateWidgetAutoSize(size);
+ }
+ CalculateTextContentSize(doc, size);
+ return CalculateFieldAutoSize(doc, size);
+}
+
+bool CXFA_Node::CalculateCheckButtonAutoSize(CXFA_FFDoc* doc, CFX_SizeF& size) {
+ float fCheckSize = GetCheckButtonSize();
+ size = CFX_SizeF(fCheckSize, fCheckSize);
+ return CalculateFieldAutoSize(doc, size);
+}
+
+bool CXFA_Node::CalculatePushButtonAutoSize(CXFA_FFDoc* doc, CFX_SizeF& size) {
+ CalcCaptionSize(doc, size);
+ return CalculateWidgetAutoSize(size);
+}
+
+CFX_SizeF CXFA_Node::CalculateImageSize(float img_width,
+ float img_height,
+ float dpi_x,
+ float dpi_y) {
+ CFX_RectF rtImage(0, 0, XFA_UnitPx2Pt(img_width, dpi_x),
+ XFA_UnitPx2Pt(img_height, dpi_y));
+
+ CFX_RectF rtFit;
+ Optional<float> width = m_pNode->TryWidth();
+ if (width) {
+ rtFit.width = *width;
+ GetWidthWithoutMargin(rtFit.width);
+ } else {
+ rtFit.width = rtImage.width;
+ }
+
+ Optional<float> height = m_pNode->TryHeight();
+ if (height) {
+ rtFit.height = *height;
+ GetHeightWithoutMargin(rtFit.height);
+ } else {
+ rtFit.height = rtImage.height;
+ }
+
+ return rtFit.Size();
+}
+
+bool CXFA_Node::CalculateImageAutoSize(CXFA_FFDoc* doc, CFX_SizeF& size) {
+ if (!GetImageImage())
+ LoadImageImage(doc);
+
+ size.clear();
+ RetainPtr<CFX_DIBitmap> pBitmap = GetImageImage();
+ if (!pBitmap)
+ return CalculateWidgetAutoSize(size);
+
+ int32_t iImageXDpi = 0;
+ int32_t iImageYDpi = 0;
+ GetImageDpi(iImageXDpi, iImageYDpi);
+
+ size = CalculateImageSize(pBitmap->GetWidth(), pBitmap->GetHeight(),
+ iImageXDpi, iImageYDpi);
+ return CalculateWidgetAutoSize(size);
+}
+
+bool CXFA_Node::CalculateImageEditAutoSize(CXFA_FFDoc* doc, CFX_SizeF& size) {
+ if (!GetImageEditImage())
+ LoadImageEditImage(doc);
+
+ size.clear();
+ RetainPtr<CFX_DIBitmap> pBitmap = GetImageEditImage();
+ if (!pBitmap)
+ return CalculateFieldAutoSize(doc, size);
+
+ int32_t iImageXDpi = 0;
+ int32_t iImageYDpi = 0;
+ GetImageEditDpi(iImageXDpi, iImageYDpi);
+
+ size = CalculateImageSize(pBitmap->GetWidth(), pBitmap->GetHeight(),
+ iImageXDpi, iImageYDpi);
+ return CalculateFieldAutoSize(doc, size);
+}
+
+bool CXFA_Node::LoadImageImage(CXFA_FFDoc* doc) {
+ InitLayoutData();
+ return static_cast<CXFA_ImageLayoutData*>(m_pLayoutData.get())
+ ->LoadImageData(doc, this);
+}
+
+bool CXFA_Node::LoadImageEditImage(CXFA_FFDoc* doc) {
+ InitLayoutData();
+ return static_cast<CXFA_ImageEditData*>(m_pLayoutData.get())
+ ->LoadImageData(doc, this);
+}
+
+void CXFA_Node::GetImageDpi(int32_t& iImageXDpi, int32_t& iImageYDpi) {
+ CXFA_ImageLayoutData* pData =
+ static_cast<CXFA_ImageLayoutData*>(m_pLayoutData.get());
+ iImageXDpi = pData->m_iImageXDpi;
+ iImageYDpi = pData->m_iImageYDpi;
+}
+
+void CXFA_Node::GetImageEditDpi(int32_t& iImageXDpi, int32_t& iImageYDpi) {
+ CXFA_ImageEditData* pData =
+ static_cast<CXFA_ImageEditData*>(m_pLayoutData.get());
+ iImageXDpi = pData->m_iImageXDpi;
+ iImageYDpi = pData->m_iImageYDpi;
+}
+
+void CXFA_Node::LoadText(CXFA_FFDoc* doc) {
+ InitLayoutData();
+ static_cast<CXFA_TextLayoutData*>(m_pLayoutData.get())->LoadText(doc, this);
+}
+
+float CXFA_Node::CalculateWidgetAutoWidth(float fWidthCalc) {
+ CXFA_Margin* margin = m_pNode->GetMarginIfExists();
+ if (margin)
+ fWidthCalc += margin->GetLeftInset() + margin->GetRightInset();
+
+ Optional<float> min = m_pNode->TryMinWidth();
+ if (min)
+ fWidthCalc = std::max(fWidthCalc, *min);
+
+ Optional<float> max = m_pNode->TryMaxWidth();
+ if (max && *max > 0)
+ fWidthCalc = std::min(fWidthCalc, *max);
+
+ return fWidthCalc;
+}
+
+float CXFA_Node::GetWidthWithoutMargin(float fWidthCalc) {
+ CXFA_Margin* margin = m_pNode->GetMarginIfExists();
+ if (margin)
+ fWidthCalc -= margin->GetLeftInset() + margin->GetRightInset();
+ return fWidthCalc;
+}
+
+float CXFA_Node::CalculateWidgetAutoHeight(float fHeightCalc) {
+ CXFA_Margin* margin = m_pNode->GetMarginIfExists();
+ if (margin)
+ fHeightCalc += margin->GetTopInset() + margin->GetBottomInset();
+
+ Optional<float> min = m_pNode->TryMinHeight();
+ if (min)
+ fHeightCalc = std::max(fHeightCalc, *min);
+
+ Optional<float> max = m_pNode->TryMaxHeight();
+ if (max && *max > 0)
+ fHeightCalc = std::min(fHeightCalc, *max);
+
+ return fHeightCalc;
+}
+
+float CXFA_Node::GetHeightWithoutMargin(float fHeightCalc) {
+ CXFA_Margin* margin = m_pNode->GetMarginIfExists();
+ if (margin)
+ fHeightCalc -= margin->GetTopInset() + margin->GetBottomInset();
+ return fHeightCalc;
+}
+
+void CXFA_Node::StartWidgetLayout(CXFA_FFDoc* doc,
+ float& fCalcWidth,
+ float& fCalcHeight) {
+ InitLayoutData();
+
+ XFA_Element eUIType = m_pNode->GetUIType();
+ if (eUIType == XFA_Element::Text) {
+ m_pLayoutData->m_fWidgetHeight = m_pNode->TryHeight().value_or(-1);
+ StartTextLayout(doc, fCalcWidth, fCalcHeight);
+ return;
+ }
+ if (fCalcWidth > 0 && fCalcHeight > 0)
+ return;
+
+ m_pLayoutData->m_fWidgetHeight = -1;
+ float fWidth = 0;
+ if (fCalcWidth > 0 && fCalcHeight < 0) {
+ Optional<float> height = m_pNode->TryHeight();
+ if (height)
+ fCalcHeight = *height;
+ else
+ CalculateAccWidthAndHeight(doc, eUIType, fCalcWidth, fCalcHeight);
+
+ m_pLayoutData->m_fWidgetHeight = fCalcHeight;
+ return;
+ }
+ if (fCalcWidth < 0 && fCalcHeight < 0) {
+ Optional<float> height;
+ Optional<float> width = m_pNode->TryWidth();
+ if (width) {
+ fWidth = *width;
+
+ height = m_pNode->TryHeight();
+ if (height)
+ fCalcHeight = *height;
+ }
+ if (!width || !height)
+ CalculateAccWidthAndHeight(doc, eUIType, fWidth, fCalcHeight);
+
+ fCalcWidth = fWidth;
+ }
+ m_pLayoutData->m_fWidgetHeight = fCalcHeight;
+}
+
+void CXFA_Node::CalculateAccWidthAndHeight(CXFA_FFDoc* doc,
+ XFA_Element eUIType,
+ float& fWidth,
+ float& fCalcHeight) {
+ CFX_SizeF sz(fWidth, m_pLayoutData->m_fWidgetHeight);
+ switch (eUIType) {
+ case XFA_Element::Barcode:
+ case XFA_Element::ChoiceList:
+ case XFA_Element::Signature:
+ CalculateFieldAutoSize(doc, sz);
+ break;
+ case XFA_Element::ImageEdit:
+ CalculateImageEditAutoSize(doc, sz);
+ break;
+ case XFA_Element::Button:
+ CalculatePushButtonAutoSize(doc, sz);
+ break;
+ case XFA_Element::CheckButton:
+ CalculateCheckButtonAutoSize(doc, sz);
+ break;
+ case XFA_Element::DateTimeEdit:
+ case XFA_Element::NumericEdit:
+ case XFA_Element::PasswordEdit:
+ case XFA_Element::TextEdit:
+ CalculateTextEditAutoSize(doc, sz);
+ break;
+ case XFA_Element::Image:
+ CalculateImageAutoSize(doc, sz);
+ break;
+ case XFA_Element::Arc:
+ case XFA_Element::Line:
+ case XFA_Element::Rectangle:
+ case XFA_Element::Subform:
+ case XFA_Element::ExclGroup:
+ CalculateWidgetAutoSize(sz);
+ break;
+ default:
+ break;
+ }
+ fWidth = sz.width;
+ m_pLayoutData->m_fWidgetHeight = sz.height;
+ fCalcHeight = sz.height;
+}
+
+bool CXFA_Node::FindSplitPos(CXFA_FFDocView* docView,
+ int32_t iBlockIndex,
+ float& fCalcHeight) {
+ XFA_Element eUIType = m_pNode->GetUIType();
+ if (eUIType == XFA_Element::Subform)
+ return false;
+
+ if (eUIType != XFA_Element::Text && eUIType != XFA_Element::TextEdit &&
+ eUIType != XFA_Element::NumericEdit &&
+ eUIType != XFA_Element::PasswordEdit) {
+ fCalcHeight = 0;
+ return true;
+ }
+
+ float fTopInset = 0;
+ float fBottomInset = 0;
+ if (iBlockIndex == 0) {
+ CXFA_Margin* margin = m_pNode->GetMarginIfExists();
+ if (margin) {
+ fTopInset = margin->GetTopInset();
+ fBottomInset = margin->GetBottomInset();
+ }
+
+ CFX_RectF rtUIMargin = m_pNode->GetUIMargin();
+ fTopInset += rtUIMargin.top;
+ fBottomInset += rtUIMargin.width;
+ }
+ if (eUIType == XFA_Element::Text) {
+ float fHeight = fCalcHeight;
+ if (iBlockIndex == 0) {
+ fCalcHeight = fCalcHeight - fTopInset;
+ if (fCalcHeight < 0)
+ fCalcHeight = 0;
+ }
+
+ CXFA_TextLayout* pTextLayout =
+ static_cast<CXFA_TextLayoutData*>(m_pLayoutData.get())->GetTextLayout();
+ fCalcHeight =
+ pTextLayout->DoLayout(iBlockIndex, fCalcHeight, fCalcHeight,
+ m_pLayoutData->m_fWidgetHeight - fTopInset);
+ if (fCalcHeight != 0) {
+ if (iBlockIndex == 0)
+ fCalcHeight = fCalcHeight + fTopInset;
+ if (fabs(fHeight - fCalcHeight) < XFA_FLOAT_PERCISION)
+ return false;
+ }
+ return true;
+ }
+ XFA_AttributeEnum iCapPlacement = XFA_AttributeEnum::Unknown;
+ float fCapReserve = 0;
+ if (iBlockIndex == 0) {
+ CXFA_Caption* caption = m_pNode->GetCaptionIfExists();
+ if (caption && !caption->IsHidden()) {
+ iCapPlacement = caption->GetPlacementType();
+ fCapReserve = caption->GetReserve();
+ }
+ if (iCapPlacement == XFA_AttributeEnum::Top &&
+ fCalcHeight < fCapReserve + fTopInset) {
+ fCalcHeight = 0;
+ return true;
+ }
+ if (iCapPlacement == XFA_AttributeEnum::Bottom &&
+ m_pLayoutData->m_fWidgetHeight - fCapReserve - fBottomInset) {
+ fCalcHeight = 0;
+ return true;
+ }
+ if (iCapPlacement != XFA_AttributeEnum::Top)
+ fCapReserve = 0;
+ }
+ CXFA_FieldLayoutData* pFieldData =
+ static_cast<CXFA_FieldLayoutData*>(m_pLayoutData.get());
+ int32_t iLinesCount = 0;
+ float fHeight = m_pLayoutData->m_fWidgetHeight;
+ if (GetValue(XFA_VALUEPICTURE_Display).IsEmpty()) {
+ iLinesCount = 1;
+ } else {
+ if (!pFieldData->m_pTextOut) {
+ // TODO(dsinclair): Inline fWidth when the 2nd param of
+ // CalculateAccWidthAndHeight isn't a ref-param.
+ float fWidth = m_pNode->TryWidth().value_or(0);
+ CalculateAccWidthAndHeight(docView->GetDoc(), eUIType, fWidth, fHeight);
+ }
+ iLinesCount = pFieldData->m_pTextOut->GetTotalLines();
+ }
+ std::vector<float>* pFieldArray = &pFieldData->m_FieldSplitArray;
+ int32_t iFieldSplitCount = pdfium::CollectionSize<int32_t>(*pFieldArray);
+ for (int32_t i = 0; i < iBlockIndex * 3; i += 3) {
+ iLinesCount -= (int32_t)(*pFieldArray)[i + 1];
+ fHeight -= (*pFieldArray)[i + 2];
+ }
+ if (iLinesCount == 0)
+ return false;
+
+ float fLineHeight = m_pNode->GetLineHeight();
+ float fFontSize = m_pNode->GetFontSize();
+ float fTextHeight = iLinesCount * fLineHeight - fLineHeight + fFontSize;
+ float fSpaceAbove = 0;
+ float fStartOffset = 0;
+ if (fHeight > 0.1f && iBlockIndex == 0) {
+ fStartOffset = fTopInset;
+ fHeight -= (fTopInset + fBottomInset);
+ CXFA_Para* para = m_pNode->GetParaIfExists();
+ if (para) {
+ fSpaceAbove = para->GetSpaceAbove();
+ float fSpaceBelow = para->GetSpaceBelow();
+ fHeight -= (fSpaceAbove + fSpaceBelow);
+ switch (para->GetVerticalAlign()) {
+ case XFA_AttributeEnum::Top:
+ fStartOffset += fSpaceAbove;
+ break;
+ case XFA_AttributeEnum::Middle:
+ fStartOffset += ((fHeight - fTextHeight) / 2 + fSpaceAbove);
+ break;
+ case XFA_AttributeEnum::Bottom:
+ fStartOffset += (fHeight - fTextHeight + fSpaceAbove);
+ break;
+ default:
+ NOTREACHED();
+ break;
+ }
+ }
+ if (fStartOffset < 0.1f)
+ fStartOffset = 0;
+ }
+ for (int32_t i = iBlockIndex - 1; iBlockIndex > 0 && i < iBlockIndex; i++) {
+ fStartOffset = (*pFieldArray)[i * 3] - (*pFieldArray)[i * 3 + 2];
+ if (fStartOffset < 0.1f)
+ fStartOffset = 0;
+ }
+ if (iFieldSplitCount / 3 == (iBlockIndex + 1))
+ (*pFieldArray)[0] = fStartOffset;
+ else
+ pFieldArray->push_back(fStartOffset);
+
+ XFA_VERSION version = docView->GetDoc()->GetXFADoc()->GetCurVersionMode();
+ bool bCanSplitNoContent = false;
+ XFA_AttributeEnum eLayoutMode = GetNode()
+ ->GetParent()
+ ->JSObject()
+ ->TryEnum(XFA_Attribute::Layout, true)
+ .value_or(XFA_AttributeEnum::Position);
+ if ((eLayoutMode == XFA_AttributeEnum::Position ||
+ eLayoutMode == XFA_AttributeEnum::Tb ||
+ eLayoutMode == XFA_AttributeEnum::Row ||
+ eLayoutMode == XFA_AttributeEnum::Table) &&
+ version > XFA_VERSION_208) {
+ bCanSplitNoContent = true;
+ }
+ if ((eLayoutMode == XFA_AttributeEnum::Tb ||
+ eLayoutMode == XFA_AttributeEnum::Row ||
+ eLayoutMode == XFA_AttributeEnum::Table) &&
+ version <= XFA_VERSION_208) {
+ if (fStartOffset < fCalcHeight) {
+ bCanSplitNoContent = true;
+ } else {
+ fCalcHeight = 0;
+ return true;
+ }
+ }
+ if (bCanSplitNoContent) {
+ if ((fCalcHeight - fTopInset - fSpaceAbove < fLineHeight)) {
+ fCalcHeight = 0;
+ return true;
+ }
+ if (fStartOffset + XFA_FLOAT_PERCISION >= fCalcHeight) {
+ if (iFieldSplitCount / 3 == (iBlockIndex + 1)) {
+ (*pFieldArray)[iBlockIndex * 3 + 1] = 0;
+ (*pFieldArray)[iBlockIndex * 3 + 2] = fCalcHeight;
+ } else {
+ pFieldArray->push_back(0);
+ pFieldArray->push_back(fCalcHeight);
+ }
+ return false;
+ }
+ if (fCalcHeight - fStartOffset < fLineHeight) {
+ fCalcHeight = fStartOffset;
+ if (iFieldSplitCount / 3 == (iBlockIndex + 1)) {
+ (*pFieldArray)[iBlockIndex * 3 + 1] = 0;
+ (*pFieldArray)[iBlockIndex * 3 + 2] = fCalcHeight;
+ } else {
+ pFieldArray->push_back(0);
+ pFieldArray->push_back(fCalcHeight);
+ }
+ return true;
+ }
+ float fTextNum =
+ fCalcHeight + XFA_FLOAT_PERCISION - fCapReserve - fStartOffset;
+ int32_t iLineNum =
+ (int32_t)((fTextNum + (fLineHeight - fFontSize)) / fLineHeight);
+ if (iLineNum >= iLinesCount) {
+ if (fCalcHeight - fStartOffset - fTextHeight >= fFontSize) {
+ if (iFieldSplitCount / 3 == (iBlockIndex + 1)) {
+ (*pFieldArray)[iBlockIndex * 3 + 1] = (float)iLinesCount;
+ (*pFieldArray)[iBlockIndex * 3 + 2] = fCalcHeight;
+ } else {
+ pFieldArray->push_back((float)iLinesCount);
+ pFieldArray->push_back(fCalcHeight);
+ }
+ return false;
+ }
+ if (fHeight - fStartOffset - fTextHeight < fFontSize) {
+ iLineNum -= 1;
+ if (iLineNum == 0) {
+ fCalcHeight = 0;
+ return true;
+ }
+ } else {
+ iLineNum = (int32_t)(fTextNum / fLineHeight);
+ }
+ }
+ if (iLineNum > 0) {
+ float fSplitHeight = iLineNum * fLineHeight + fCapReserve + fStartOffset;
+ if (iFieldSplitCount / 3 == (iBlockIndex + 1)) {
+ (*pFieldArray)[iBlockIndex * 3 + 1] = (float)iLineNum;
+ (*pFieldArray)[iBlockIndex * 3 + 2] = fSplitHeight;
+ } else {
+ pFieldArray->push_back((float)iLineNum);
+ pFieldArray->push_back(fSplitHeight);
+ }
+ if (fabs(fSplitHeight - fCalcHeight) < XFA_FLOAT_PERCISION)
+ return false;
+
+ fCalcHeight = fSplitHeight;
+ return true;
+ }
+ }
+ fCalcHeight = 0;
+ return true;
+}
+
+void CXFA_Node::InitLayoutData() {
+ if (m_pLayoutData)
+ return;
+
+ switch (m_pNode->GetUIType()) {
+ case XFA_Element::Text:
+ m_pLayoutData = pdfium::MakeUnique<CXFA_TextLayoutData>();
+ return;
+ case XFA_Element::TextEdit:
+ m_pLayoutData = pdfium::MakeUnique<CXFA_TextEditData>();
+ return;
+ case XFA_Element::Image:
+ m_pLayoutData = pdfium::MakeUnique<CXFA_ImageLayoutData>();
+ return;
+ case XFA_Element::ImageEdit:
+ m_pLayoutData = pdfium::MakeUnique<CXFA_ImageEditData>();
+ return;
+ default:
+ break;
+ }
+ if (m_pNode && m_pNode->GetElementType() == XFA_Element::Field) {
+ m_pLayoutData = pdfium::MakeUnique<CXFA_FieldLayoutData>();
+ return;
+ }
+ m_pLayoutData = pdfium::MakeUnique<CXFA_WidgetLayoutData>();
+}
+
+void CXFA_Node::StartTextLayout(CXFA_FFDoc* doc,
+ float& fCalcWidth,
+ float& fCalcHeight) {
+ LoadText(doc);
+
+ CXFA_TextLayout* pTextLayout =
+ static_cast<CXFA_TextLayoutData*>(m_pLayoutData.get())->GetTextLayout();
+ float fTextHeight = 0;
+ if (fCalcWidth > 0 && fCalcHeight > 0) {
+ float fWidth = GetWidthWithoutMargin(fCalcWidth);
+ pTextLayout->StartLayout(fWidth);
+ fTextHeight = fCalcHeight;
+ fTextHeight = GetHeightWithoutMargin(fTextHeight);
+ pTextLayout->DoLayout(0, fTextHeight, -1, fTextHeight);
+ return;
+ }
+ if (fCalcWidth > 0 && fCalcHeight < 0) {
+ float fWidth = GetWidthWithoutMargin(fCalcWidth);
+ pTextLayout->StartLayout(fWidth);
+ }
+
+ if (fCalcWidth < 0 && fCalcHeight < 0) {
+ Optional<float> width = m_pNode->TryWidth();
+ if (width) {
+ pTextLayout->StartLayout(GetWidthWithoutMargin(*width));
+ fCalcWidth = *width;
+ } else {
+ float fMaxWidth = CalculateWidgetAutoWidth(pTextLayout->StartLayout(-1));
+ pTextLayout->StartLayout(GetWidthWithoutMargin(fMaxWidth));
+ fCalcWidth = fMaxWidth;
+ }
+ }
+
+ if (m_pLayoutData->m_fWidgetHeight < 0) {
+ m_pLayoutData->m_fWidgetHeight = pTextLayout->GetLayoutHeight();
+ m_pLayoutData->m_fWidgetHeight =
+ CalculateWidgetAutoHeight(m_pLayoutData->m_fWidgetHeight);
+ }
+ fTextHeight = m_pLayoutData->m_fWidgetHeight;
+ fTextHeight = GetHeightWithoutMargin(fTextHeight);
+ pTextLayout->DoLayout(0, fTextHeight, -1, fTextHeight);
+ fCalcHeight = m_pLayoutData->m_fWidgetHeight;
+}
+
+bool CXFA_Node::LoadCaption(CXFA_FFDoc* doc) {
+ InitLayoutData();
+ return static_cast<CXFA_FieldLayoutData*>(m_pLayoutData.get())
+ ->LoadCaption(doc, this);
+}
+
+CXFA_TextLayout* CXFA_Node::GetCaptionTextLayout() {
+ return m_pLayoutData ? static_cast<CXFA_FieldLayoutData*>(m_pLayoutData.get())
+ ->m_pCapTextLayout.get()
+ : nullptr;
+}
+
+CXFA_TextLayout* CXFA_Node::GetTextLayout() {
+ return m_pLayoutData ? static_cast<CXFA_TextLayoutData*>(m_pLayoutData.get())
+ ->GetTextLayout()
+ : nullptr;
+}
+
+RetainPtr<CFX_DIBitmap> CXFA_Node::GetImageImage() {
+ return m_pLayoutData ? static_cast<CXFA_ImageLayoutData*>(m_pLayoutData.get())
+ ->m_pDIBitmap
+ : nullptr;
+}
+
+RetainPtr<CFX_DIBitmap> CXFA_Node::GetImageEditImage() {
+ return m_pLayoutData ? static_cast<CXFA_ImageEditData*>(m_pLayoutData.get())
+ ->m_pDIBitmap
+ : nullptr;
+}
+
+void CXFA_Node::SetImageImage(const RetainPtr<CFX_DIBitmap>& newImage) {
+ CXFA_ImageLayoutData* pData =
+ static_cast<CXFA_ImageLayoutData*>(m_pLayoutData.get());
+ if (pData->m_pDIBitmap != newImage)
+ pData->m_pDIBitmap = newImage;
+}
+
+void CXFA_Node::SetImageEditImage(const RetainPtr<CFX_DIBitmap>& newImage) {
+ CXFA_ImageEditData* pData =
+ static_cast<CXFA_ImageEditData*>(m_pLayoutData.get());
+ if (pData->m_pDIBitmap != newImage)
+ pData->m_pDIBitmap = newImage;
+}
+
+RetainPtr<CFGAS_GEFont> CXFA_Node::GetFDEFont(CXFA_FFDoc* doc) {
+ WideString wsFontName = L"Courier";
+ uint32_t dwFontStyle = 0;
+ CXFA_Font* font = m_pNode->GetFontIfExists();
+ if (font) {
+ if (font->IsBold())
+ dwFontStyle |= FXFONT_BOLD;
+ if (font->IsItalic())
+ dwFontStyle |= FXFONT_ITALIC;
+
+ wsFontName = font->GetTypeface();
+ }
+ return doc->GetApp()->GetXFAFontMgr()->GetFont(doc, wsFontName.AsStringView(),
+ dwFontStyle);
+}
+
+bool CXFA_Node::IsOpenAccess() const {
+ return m_pNode && m_pNode->IsOpenAccess();
+}
+
+XFA_AttributeEnum CXFA_Node::GetButtonHighlight() {
+ CXFA_Node* pUIChild = m_pNode->GetUIChild();
+ if (pUIChild)
+ return pUIChild->JSObject()->GetEnum(XFA_Attribute::Highlight);
+ return XFA_AttributeEnum::Inverted;
+}
+
+bool CXFA_Node::HasButtonRollover() const {
+ CXFA_Items* pItems =
+ m_pNode->GetChild<CXFA_Items>(0, XFA_Element::Items, false);
+ if (!pItems)
+ return false;
+
+ for (CXFA_Node* pText = pItems->GetFirstChild(); pText;
+ pText = pText->GetNextSibling()) {
+ if (pText->JSObject()->GetCData(XFA_Attribute::Name) == L"rollover")
+ return !pText->JSObject()->GetContent(false).IsEmpty();
+ }
+ return false;
+}
+
+bool CXFA_Node::HasButtonDown() const {
+ CXFA_Items* pItems =
+ m_pNode->GetChild<CXFA_Items>(0, XFA_Element::Items, false);
+ if (!pItems)
+ return false;
+
+ for (CXFA_Node* pText = pItems->GetFirstChild(); pText;
+ pText = pText->GetNextSibling()) {
+ if (pText->JSObject()->GetCData(XFA_Attribute::Name) == L"down")
+ return !pText->JSObject()->GetContent(false).IsEmpty();
+ }
+ return false;
+}
+
+bool CXFA_Node::IsCheckButtonRound() {
+ CXFA_Node* pUIChild = m_pNode->GetUIChild();
+ if (pUIChild)
+ return pUIChild->JSObject()->GetEnum(XFA_Attribute::Shape) ==
+ XFA_AttributeEnum::Round;
+ return false;
+}
+
+XFA_AttributeEnum CXFA_Node::GetCheckButtonMark() {
+ CXFA_Node* pUIChild = m_pNode->GetUIChild();
+ if (pUIChild)
+ return pUIChild->JSObject()->GetEnum(XFA_Attribute::Mark);
+ return XFA_AttributeEnum::Default;
+}
+
+bool CXFA_Node::IsRadioButton() {
+ CXFA_Node* pParent = m_pNode->GetParent();
+ return pParent && pParent->GetElementType() == XFA_Element::ExclGroup;
+}
+
+float CXFA_Node::GetCheckButtonSize() {
+ CXFA_Node* pUIChild = m_pNode->GetUIChild();
+ if (pUIChild) {
+ return pUIChild->JSObject()
+ ->GetMeasure(XFA_Attribute::Size)
+ .ToUnit(XFA_Unit::Pt);
+ }
+ return CXFA_Measurement(10, XFA_Unit::Pt).ToUnit(XFA_Unit::Pt);
+}
+
+bool CXFA_Node::IsAllowNeutral() {
+ CXFA_Node* pUIChild = m_pNode->GetUIChild();
+ return pUIChild &&
+ pUIChild->JSObject()->GetBoolean(XFA_Attribute::AllowNeutral);
+}
+
+XFA_CHECKSTATE CXFA_Node::GetCheckState() {
+ WideString wsValue = m_pNode->GetRawValue();
+ if (wsValue.IsEmpty())
+ return XFA_CHECKSTATE_Off;
+
+ auto* pItems = m_pNode->GetChild<CXFA_Items>(0, XFA_Element::Items, false);
+ if (!pItems)
+ return XFA_CHECKSTATE_Off;
+
+ CXFA_Node* pText = pItems->GetFirstChild();
+ int32_t i = 0;
+ while (pText) {
+ Optional<WideString> wsContent = pText->JSObject()->TryContent(false, true);
+ if (wsContent && *wsContent == wsValue)
+ return static_cast<XFA_CHECKSTATE>(i);
+
+ i++;
+ pText = pText->GetNextSibling();
+ }
+ return XFA_CHECKSTATE_Off;
+}
+
+void CXFA_Node::SetCheckState(XFA_CHECKSTATE eCheckState, bool bNotify) {
+ CXFA_Node* node = m_pNode->GetExclGroupIfExists();
+ if (!node) {
+ CXFA_Items* pItems =
+ m_pNode->GetChild<CXFA_Items>(0, XFA_Element::Items, false);
+ if (!pItems)
+ return;
+
+ int32_t i = -1;
+ CXFA_Node* pText = pItems->GetFirstChild();
+ WideString wsContent;
+ while (pText) {
+ i++;
+ if (i == eCheckState) {
+ wsContent = pText->JSObject()->GetContent(false);
+ break;
+ }
+ pText = pText->GetNextSibling();
+ }
+ m_pNode->SyncValue(wsContent, bNotify);
+
+ return;
+ }
+
+ WideString wsValue;
+ if (eCheckState != XFA_CHECKSTATE_Off) {
+ if (CXFA_Items* pItems =
+ m_pNode->GetChild<CXFA_Items>(0, XFA_Element::Items, false)) {
+ CXFA_Node* pText = pItems->GetFirstChild();
+ if (pText)
+ wsValue = pText->JSObject()->GetContent(false);
+ }
+ }
+ CXFA_Node* pChild = node->GetFirstChild();
+ for (; pChild; pChild = pChild->GetNextSibling()) {
+ if (pChild->GetElementType() != XFA_Element::Field)
+ continue;
+
+ CXFA_Items* pItem =
+ pChild->GetChild<CXFA_Items>(0, XFA_Element::Items, false);
+ if (!pItem)
+ continue;
+
+ CXFA_Node* pItemchild = pItem->GetFirstChild();
+ if (!pItemchild)
+ continue;
+
+ WideString text = pItemchild->JSObject()->GetContent(false);
+ WideString wsChildValue = text;
+ if (wsValue != text) {
+ pItemchild = pItemchild->GetNextSibling();
+ if (pItemchild)
+ wsChildValue = pItemchild->JSObject()->GetContent(false);
+ else
+ wsChildValue.clear();
+ }
+ pChild->SyncValue(wsChildValue, bNotify);
+ }
+ node->SyncValue(wsValue, bNotify);
+}
+
+CXFA_Node* CXFA_Node::GetSelectedMember() {
+ CXFA_Node* pSelectedMember = nullptr;
+ WideString wsState = m_pNode->GetRawValue();
+ if (wsState.IsEmpty())
+ return pSelectedMember;
+
+ for (CXFA_Node* pNode = ToNode(m_pNode->GetFirstChild()); pNode;
+ pNode = pNode->GetNextSibling()) {
+ if (pNode->GetCheckState() == XFA_CHECKSTATE_On) {
+ pSelectedMember = pNode;
+ break;
+ }
+ }
+ return pSelectedMember;
+}
+
+CXFA_Node* CXFA_Node::SetSelectedMember(const WideStringView& wsName,
+ bool bNotify) {
+ uint32_t nameHash = FX_HashCode_GetW(wsName, false);
+ for (CXFA_Node* pNode = ToNode(m_pNode->GetFirstChild()); pNode;
+ pNode = pNode->GetNextSibling()) {
+ if (pNode->GetNameHash() == nameHash) {
+ pNode->SetCheckState(XFA_CHECKSTATE_On, bNotify);
+ return pNode;
+ }
+ }
+ return nullptr;
+}
+
+void CXFA_Node::SetSelectedMemberByValue(const WideStringView& wsValue,
+ bool bNotify,
+ bool bScriptModify,
+ bool bSyncData) {
+ WideString wsExclGroup;
+ for (CXFA_Node* pNode = m_pNode->GetFirstChild(); pNode;
+ pNode = pNode->GetNextSibling()) {
+ if (pNode->GetElementType() != XFA_Element::Field)
+ continue;
+
+ CXFA_Items* pItem =
+ pNode->GetChild<CXFA_Items>(0, XFA_Element::Items, false);
+ if (!pItem)
+ continue;
+
+ CXFA_Node* pItemchild = pItem->GetFirstChild();
+ if (!pItemchild)
+ continue;
+
+ WideString wsChildValue = pItemchild->JSObject()->GetContent(false);
+ if (wsValue != wsChildValue) {
+ pItemchild = pItemchild->GetNextSibling();
+ if (pItemchild)
+ wsChildValue = pItemchild->JSObject()->GetContent(false);
+ else
+ wsChildValue.clear();
+ } else {
+ wsExclGroup = wsValue;
+ }
+ pNode->JSObject()->SetContent(wsChildValue, wsChildValue, bNotify,
+ bScriptModify, false);
+ }
+ m_pNode->JSObject()->SetContent(wsExclGroup, wsExclGroup, bNotify,
+ bScriptModify, bSyncData);
+}
+
+CXFA_Node* CXFA_Node::GetExclGroupFirstMember() {
+ CXFA_Node* pExcl = GetNode();
+ if (!pExcl)
+ return nullptr;
+
+ CXFA_Node* pNode = pExcl->GetFirstChild();
+ while (pNode) {
+ if (pNode->GetElementType() == XFA_Element::Field)
+ return pNode;
+
+ pNode = pNode->GetNextSibling();
+ }
+ return nullptr;
+}
+CXFA_Node* CXFA_Node::GetExclGroupNextMember(CXFA_Node* pNode) {
+ if (!pNode)
+ return nullptr;
+
+ CXFA_Node* pNodeField = pNode->GetNextSibling();
+ while (pNodeField) {
+ if (pNodeField->GetElementType() == XFA_Element::Field)
+ return pNodeField;
+
+ pNodeField = pNodeField->GetNextSibling();
+ }
+ return nullptr;
+}
+
+bool CXFA_Node::IsChoiceListCommitOnSelect() {
+ CXFA_Node* pUIChild = m_pNode->GetUIChild();
+ if (pUIChild) {
+ return pUIChild->JSObject()->GetEnum(XFA_Attribute::CommitOn) ==
+ XFA_AttributeEnum::Select;
+ }
+ return true;
+}
+
+bool CXFA_Node::IsChoiceListAllowTextEntry() {
+ CXFA_Node* pUIChild = m_pNode->GetUIChild();
+ return pUIChild && pUIChild->JSObject()->GetBoolean(XFA_Attribute::TextEntry);
+}
+
+bool CXFA_Node::IsChoiceListMultiSelect() {
+ CXFA_Node* pUIChild = m_pNode->GetUIChild();
+ if (pUIChild) {
+ return pUIChild->JSObject()->GetEnum(XFA_Attribute::Open) ==
+ XFA_AttributeEnum::MultiSelect;
+ }
+ return false;
+}
+
+bool CXFA_Node::IsListBox() {
+ CXFA_Node* pUIChild = m_pNode->GetUIChild();
+ if (!pUIChild)
+ return false;
+
+ XFA_AttributeEnum attr = pUIChild->JSObject()->GetEnum(XFA_Attribute::Open);
+ return attr == XFA_AttributeEnum::Always ||
+ attr == XFA_AttributeEnum::MultiSelect;
+}
+
+int32_t CXFA_Node::CountChoiceListItems(bool bSaveValue) {
+ std::vector<CXFA_Node*> pItems;
+ int32_t iCount = 0;
+ for (CXFA_Node* pNode = m_pNode->GetFirstChild(); pNode;
+ pNode = pNode->GetNextSibling()) {
+ if (pNode->GetElementType() != XFA_Element::Items)
+ continue;
+ iCount++;
+ pItems.push_back(pNode);
+ if (iCount == 2)
+ break;
+ }
+ if (iCount == 0)
+ return 0;
+
+ CXFA_Node* pItem = pItems[0];
+ if (iCount > 1) {
+ bool bItemOneHasSave =
+ pItems[0]->JSObject()->GetBoolean(XFA_Attribute::Save);
+ bool bItemTwoHasSave =
+ pItems[1]->JSObject()->GetBoolean(XFA_Attribute::Save);
+ if (bItemOneHasSave != bItemTwoHasSave && bSaveValue == bItemTwoHasSave)
+ pItem = pItems[1];
+ }
+ return pItem->CountChildren(XFA_Element::Unknown, false);
+}
+
+Optional<WideString> CXFA_Node::GetChoiceListItem(int32_t nIndex,
+ bool bSaveValue) {
+ std::vector<CXFA_Node*> pItemsArray;
+ int32_t iCount = 0;
+ for (CXFA_Node* pNode = m_pNode->GetFirstChild(); pNode;
+ pNode = pNode->GetNextSibling()) {
+ if (pNode->GetElementType() != XFA_Element::Items)
+ continue;
+
+ ++iCount;
+ pItemsArray.push_back(pNode);
+ if (iCount == 2)
+ break;
+ }
+ if (iCount == 0)
+ return {};
+
+ CXFA_Node* pItems = pItemsArray[0];
+ if (iCount > 1) {
+ bool bItemOneHasSave =
+ pItemsArray[0]->JSObject()->GetBoolean(XFA_Attribute::Save);
+ bool bItemTwoHasSave =
+ pItemsArray[1]->JSObject()->GetBoolean(XFA_Attribute::Save);
+ if (bItemOneHasSave != bItemTwoHasSave && bSaveValue == bItemTwoHasSave)
+ pItems = pItemsArray[1];
+ }
+ if (!pItems)
+ return {};
+
+ CXFA_Node* pItem =
+ pItems->GetChild<CXFA_Node>(nIndex, XFA_Element::Unknown, false);
+ if (pItem)
+ return {pItem->JSObject()->GetContent(false)};
+ return {};
+}
+
+std::vector<WideString> CXFA_Node::GetChoiceListItems(bool bSaveValue) {
+ std::vector<CXFA_Node*> items;
+ for (CXFA_Node* pNode = m_pNode->GetFirstChild(); pNode && items.size() < 2;
+ pNode = pNode->GetNextSibling()) {
+ if (pNode->GetElementType() == XFA_Element::Items)
+ items.push_back(pNode);
+ }
+ if (items.empty())
+ return std::vector<WideString>();
+
+ CXFA_Node* pItem = items.front();
+ if (items.size() > 1) {
+ bool bItemOneHasSave =
+ items[0]->JSObject()->GetBoolean(XFA_Attribute::Save);
+ bool bItemTwoHasSave =
+ items[1]->JSObject()->GetBoolean(XFA_Attribute::Save);
+ if (bItemOneHasSave != bItemTwoHasSave && bSaveValue == bItemTwoHasSave)
+ pItem = items[1];
+ }
+
+ std::vector<WideString> wsTextArray;
+ for (CXFA_Node* pNode = pItem->GetFirstChild(); pNode;
+ pNode = pNode->GetNextSibling()) {
+ wsTextArray.emplace_back(pNode->JSObject()->GetContent(false));
+ }
+ return wsTextArray;
+}
+
+int32_t CXFA_Node::CountSelectedItems() {
+ std::vector<WideString> wsValueArray = GetSelectedItemsValue();
+ if (IsListBox() || !IsChoiceListAllowTextEntry())
+ return pdfium::CollectionSize<int32_t>(wsValueArray);
+
+ int32_t iSelected = 0;
+ std::vector<WideString> wsSaveTextArray = GetChoiceListItems(true);
+ for (const auto& value : wsValueArray) {
+ if (pdfium::ContainsValue(wsSaveTextArray, value))
+ iSelected++;
+ }
+ return iSelected;
+}
+
+int32_t CXFA_Node::GetSelectedItem(int32_t nIndex) {
+ std::vector<WideString> wsValueArray = GetSelectedItemsValue();
+ if (!pdfium::IndexInBounds(wsValueArray, nIndex))
+ return -1;
+
+ std::vector<WideString> wsSaveTextArray = GetChoiceListItems(true);
+ auto it = std::find(wsSaveTextArray.begin(), wsSaveTextArray.end(),
+ wsValueArray[nIndex]);
+ return it != wsSaveTextArray.end() ? it - wsSaveTextArray.begin() : -1;
+}
+
+std::vector<int32_t> CXFA_Node::GetSelectedItems() {
+ std::vector<int32_t> iSelArray;
+ std::vector<WideString> wsValueArray = GetSelectedItemsValue();
+ std::vector<WideString> wsSaveTextArray = GetChoiceListItems(true);
+ for (const auto& value : wsValueArray) {
+ auto it = std::find(wsSaveTextArray.begin(), wsSaveTextArray.end(), value);
+ if (it != wsSaveTextArray.end())
+ iSelArray.push_back(it - wsSaveTextArray.begin());
+ }
+ return iSelArray;
+}
+
+std::vector<WideString> CXFA_Node::GetSelectedItemsValue() {
+ std::vector<WideString> wsSelTextArray;
+ WideString wsValue = m_pNode->GetRawValue();
+ if (IsChoiceListMultiSelect()) {
+ if (!wsValue.IsEmpty()) {
+ size_t iStart = 0;
+ size_t iLength = wsValue.GetLength();
+ auto iEnd = wsValue.Find(L'\n', iStart);
+ iEnd = (!iEnd.has_value()) ? iLength : iEnd;
+ while (iEnd >= iStart) {
+ wsSelTextArray.push_back(wsValue.Mid(iStart, iEnd.value() - iStart));
+ iStart = iEnd.value() + 1;
+ if (iStart >= iLength)
+ break;
+ iEnd = wsValue.Find(L'\n', iStart);
+ if (!iEnd.has_value())
+ wsSelTextArray.push_back(wsValue.Mid(iStart, iLength - iStart));
+ }
+ }
+ } else {
+ wsSelTextArray.push_back(wsValue);
+ }
+ return wsSelTextArray;
+}
+
+bool CXFA_Node::GetItemState(int32_t nIndex) {
+ std::vector<WideString> wsSaveTextArray = GetChoiceListItems(true);
+ return pdfium::IndexInBounds(wsSaveTextArray, nIndex) &&
+ pdfium::ContainsValue(GetSelectedItemsValue(),
+ wsSaveTextArray[nIndex]);
+}
+
+void CXFA_Node::SetItemState(int32_t nIndex,
+ bool bSelected,
+ bool bNotify,
+ bool bScriptModify,
+ bool bSyncData) {
+ std::vector<WideString> wsSaveTextArray = GetChoiceListItems(true);
+ if (!pdfium::IndexInBounds(wsSaveTextArray, nIndex))
+ return;
+
+ int32_t iSel = -1;
+ std::vector<WideString> wsValueArray = GetSelectedItemsValue();
+ auto it = std::find(wsValueArray.begin(), wsValueArray.end(),
+ wsSaveTextArray[nIndex]);
+ if (it != wsValueArray.end())
+ iSel = it - wsValueArray.begin();
+
+ if (IsChoiceListMultiSelect()) {
+ if (bSelected) {
+ if (iSel < 0) {
+ WideString wsValue = m_pNode->GetRawValue();
+ if (!wsValue.IsEmpty()) {
+ wsValue += L"\n";
+ }
+ wsValue += wsSaveTextArray[nIndex];
+ m_pNode->JSObject()->SetContent(wsValue, wsValue, bNotify,
+ bScriptModify, bSyncData);
+ }
+ } else if (iSel >= 0) {
+ std::vector<int32_t> iSelArray = GetSelectedItems();
+ auto it = std::find(iSelArray.begin(), iSelArray.end(), nIndex);
+ if (it != iSelArray.end())
+ iSelArray.erase(it);
+ SetSelectedItems(iSelArray, bNotify, bScriptModify, bSyncData);
+ }
+ } else {
+ if (bSelected) {
+ if (iSel < 0) {
+ WideString wsSaveText = wsSaveTextArray[nIndex];
+ m_pNode->JSObject()->SetContent(wsSaveText,
+ GetFormatDataValue(wsSaveText), bNotify,
+ bScriptModify, bSyncData);
+ }
+ } else if (iSel >= 0) {
+ m_pNode->JSObject()->SetContent(WideString(), WideString(), bNotify,
+ bScriptModify, bSyncData);
+ }
+ }
+}
+
+void CXFA_Node::SetSelectedItems(const std::vector<int32_t>& iSelArray,
+ bool bNotify,
+ bool bScriptModify,
+ bool bSyncData) {
+ WideString wsValue;
+ int32_t iSize = pdfium::CollectionSize<int32_t>(iSelArray);
+ if (iSize >= 1) {
+ std::vector<WideString> wsSaveTextArray = GetChoiceListItems(true);
+ WideString wsItemValue;
+ for (int32_t i = 0; i < iSize; i++) {
+ wsItemValue = (iSize == 1) ? wsSaveTextArray[iSelArray[i]]
+ : wsSaveTextArray[iSelArray[i]] + L"\n";
+ wsValue += wsItemValue;
+ }
+ }
+ WideString wsFormat(wsValue);
+ if (!IsChoiceListMultiSelect())
+ wsFormat = GetFormatDataValue(wsValue);
+
+ m_pNode->JSObject()->SetContent(wsValue, wsFormat, bNotify, bScriptModify,
+ bSyncData);
+}
+
+void CXFA_Node::ClearAllSelections() {
+ CXFA_Node* pBind = m_pNode->GetBindData();
+ if (!pBind || !IsChoiceListMultiSelect()) {
+ m_pNode->SyncValue(WideString(), false);
+ return;
+ }
+
+ while (CXFA_Node* pChildNode = pBind->GetFirstChild())
+ pBind->RemoveChild(pChildNode, true);
+}
+
+void CXFA_Node::InsertItem(const WideString& wsLabel,
+ const WideString& wsValue,
+ bool bNotify) {
+ int32_t nIndex = -1;
+ WideString wsNewValue(wsValue);
+ if (wsNewValue.IsEmpty())
+ wsNewValue = wsLabel;
+
+ std::vector<CXFA_Node*> listitems;
+ for (CXFA_Node* pItem = m_pNode->GetFirstChild(); pItem;
+ pItem = pItem->GetNextSibling()) {
+ if (pItem->GetElementType() == XFA_Element::Items)
+ listitems.push_back(pItem);
+ }
+ if (listitems.empty()) {
+ CXFA_Node* pItems = m_pNode->CreateSamePacketNode(XFA_Element::Items);
+ m_pNode->InsertChild(-1, pItems);
+ InsertListTextItem(pItems, wsLabel, nIndex);
+ CXFA_Node* pSaveItems = m_pNode->CreateSamePacketNode(XFA_Element::Items);
+ m_pNode->InsertChild(-1, pSaveItems);
+ pSaveItems->JSObject()->SetBoolean(XFA_Attribute::Save, true, false);
+ InsertListTextItem(pSaveItems, wsNewValue, nIndex);
+ } else if (listitems.size() > 1) {
+ for (int32_t i = 0; i < 2; i++) {
+ CXFA_Node* pNode = listitems[i];
+ bool bHasSave = pNode->JSObject()->GetBoolean(XFA_Attribute::Save);
+ if (bHasSave)
+ InsertListTextItem(pNode, wsNewValue, nIndex);
+ else
+ InsertListTextItem(pNode, wsLabel, nIndex);
+ }
+ } else {
+ CXFA_Node* pNode = listitems[0];
+ pNode->JSObject()->SetBoolean(XFA_Attribute::Save, false, false);
+ pNode->JSObject()->SetEnum(XFA_Attribute::Presence,
+ XFA_AttributeEnum::Visible, false);
+ CXFA_Node* pSaveItems = m_pNode->CreateSamePacketNode(XFA_Element::Items);
+ m_pNode->InsertChild(-1, pSaveItems);
+ pSaveItems->JSObject()->SetBoolean(XFA_Attribute::Save, true, false);
+ pSaveItems->JSObject()->SetEnum(XFA_Attribute::Presence,
+ XFA_AttributeEnum::Hidden, false);
+ CXFA_Node* pListNode = pNode->GetFirstChild();
+ int32_t i = 0;
+ while (pListNode) {
+ InsertListTextItem(pSaveItems, pListNode->JSObject()->GetContent(false),
+ i);
+ ++i;
+
+ pListNode = pListNode->GetNextSibling();
+ }
+ InsertListTextItem(pNode, wsLabel, nIndex);
+ InsertListTextItem(pSaveItems, wsNewValue, nIndex);
+ }
+ if (!bNotify)
+ return;
+
+ m_pNode->GetDocument()->GetNotify()->OnWidgetListItemAdded(
+ m_pNode, wsLabel.c_str(), wsValue.c_str(), nIndex);
+}
+
+void CXFA_Node::GetItemLabel(const WideStringView& wsValue,
+ WideString& wsLabel) {
+ int32_t iCount = 0;
+ std::vector<CXFA_Node*> listitems;
+ CXFA_Node* pItems = m_pNode->GetFirstChild();
+ for (; pItems; pItems = pItems->GetNextSibling()) {
+ if (pItems->GetElementType() != XFA_Element::Items)
+ continue;
+ iCount++;
+ listitems.push_back(pItems);
+ }
+
+ if (iCount <= 1) {
+ wsLabel = wsValue;
+ return;
+ }
+
+ CXFA_Node* pLabelItems = listitems[0];
+ bool bSave = pLabelItems->JSObject()->GetBoolean(XFA_Attribute::Save);
+ CXFA_Node* pSaveItems = nullptr;
+ if (bSave) {
+ pSaveItems = pLabelItems;
+ pLabelItems = listitems[1];
+ } else {
+ pSaveItems = listitems[1];
+ }
+ iCount = 0;
+
+ int32_t iSearch = -1;
+ for (CXFA_Node* pChildItem = pSaveItems->GetFirstChild(); pChildItem;
+ pChildItem = pChildItem->GetNextSibling()) {
+ if (pChildItem->JSObject()->GetContent(false) == wsValue) {
+ iSearch = iCount;
+ break;
+ }
+ iCount++;
+ }
+ if (iSearch < 0)
+ return;
+
+ CXFA_Node* pText =
+ pLabelItems->GetChild<CXFA_Node>(iSearch, XFA_Element::Unknown, false);
+ if (pText)
+ wsLabel = pText->JSObject()->GetContent(false);
+}
+
+WideString CXFA_Node::GetItemValue(const WideStringView& wsLabel) {
+ int32_t iCount = 0;
+ std::vector<CXFA_Node*> listitems;
+ for (CXFA_Node* pItems = m_pNode->GetFirstChild(); pItems;
+ pItems = pItems->GetNextSibling()) {
+ if (pItems->GetElementType() != XFA_Element::Items)
+ continue;
+ iCount++;
+ listitems.push_back(pItems);
+ }
+ if (iCount <= 1)
+ return WideString(wsLabel);
+
+ CXFA_Node* pLabelItems = listitems[0];
+ bool bSave = pLabelItems->JSObject()->GetBoolean(XFA_Attribute::Save);
+ CXFA_Node* pSaveItems = nullptr;
+ if (bSave) {
+ pSaveItems = pLabelItems;
+ pLabelItems = listitems[1];
+ } else {
+ pSaveItems = listitems[1];
+ }
+ iCount = 0;
+
+ int32_t iSearch = -1;
+ WideString wsContent;
+ CXFA_Node* pChildItem = pLabelItems->GetFirstChild();
+ for (; pChildItem; pChildItem = pChildItem->GetNextSibling()) {
+ if (pChildItem->JSObject()->GetContent(false) == wsLabel) {
+ iSearch = iCount;
+ break;
+ }
+ iCount++;
+ }
+ if (iSearch < 0)
+ return L"";
+
+ CXFA_Node* pText =
+ pSaveItems->GetChild<CXFA_Node>(iSearch, XFA_Element::Unknown, false);
+ return pText ? pText->JSObject()->GetContent(false) : L"";
+}
+
+bool CXFA_Node::DeleteItem(int32_t nIndex, bool bNotify, bool bScriptModify) {
+ bool bSetValue = false;
+ CXFA_Node* pItems = m_pNode->GetFirstChild();
+ for (; pItems; pItems = pItems->GetNextSibling()) {
+ if (pItems->GetElementType() != XFA_Element::Items)
+ continue;
+
+ if (nIndex < 0) {
+ while (CXFA_Node* pNode = pItems->GetFirstChild()) {
+ pItems->RemoveChild(pNode, true);
+ }
+ } else {
+ if (!bSetValue && pItems->JSObject()->GetBoolean(XFA_Attribute::Save)) {
+ SetItemState(nIndex, false, true, bScriptModify, true);
+ bSetValue = true;
+ }
+ int32_t i = 0;
+ CXFA_Node* pNode = pItems->GetFirstChild();
+ while (pNode) {
+ if (i == nIndex) {
+ pItems->RemoveChild(pNode, true);
+ break;
+ }
+ i++;
+ pNode = pNode->GetNextSibling();
+ }
+ }
+ }
+ if (bNotify)
+ m_pNode->GetDocument()->GetNotify()->OnWidgetListItemRemoved(m_pNode,
+ nIndex);
+ return true;
+}
+
+bool CXFA_Node::IsHorizontalScrollPolicyOff() {
+ CXFA_Node* pUIChild = m_pNode->GetUIChild();
+ if (pUIChild) {
+ return pUIChild->JSObject()->GetEnum(XFA_Attribute::HScrollPolicy) ==
+ XFA_AttributeEnum::Off;
+ }
+ return false;
+}
+
+bool CXFA_Node::IsVerticalScrollPolicyOff() {
+ CXFA_Node* pUIChild = m_pNode->GetUIChild();
+ if (pUIChild) {
+ return pUIChild->JSObject()->GetEnum(XFA_Attribute::VScrollPolicy) ==
+ XFA_AttributeEnum::Off;
+ }
+ return false;
+}
+
+Optional<int32_t> CXFA_Node::GetNumberOfCells() {
+ CXFA_Node* pUIChild = m_pNode->GetUIChild();
+ if (!pUIChild)
+ return {};
+ if (CXFA_Comb* pNode =
+ pUIChild->GetChild<CXFA_Comb>(0, XFA_Element::Comb, false))
+ return {pNode->JSObject()->GetInteger(XFA_Attribute::NumberOfCells)};
+ return {};
+}
+
+WideString CXFA_Node::GetPasswordChar() {
+ CXFA_Node* pUIChild = m_pNode->GetUIChild();
+ return pUIChild ? pUIChild->JSObject()->GetCData(XFA_Attribute::PasswordChar)
+ : L"*";
+}
+
+bool CXFA_Node::IsMultiLine() {
+ CXFA_Node* pUIChild = m_pNode->GetUIChild();
+ return pUIChild && pUIChild->JSObject()->GetBoolean(XFA_Attribute::MultiLine);
+}
+
+std::pair<XFA_Element, int32_t> CXFA_Node::GetMaxChars() {
+ if (CXFA_Value* pNode =
+ m_pNode->GetChild<CXFA_Value>(0, XFA_Element::Value, false)) {
+ if (CXFA_Node* pChild = pNode->GetFirstChild()) {
+ switch (pChild->GetElementType()) {
+ case XFA_Element::Text:
+ return {XFA_Element::Text,
+ pChild->JSObject()->GetInteger(XFA_Attribute::MaxChars)};
+ case XFA_Element::ExData: {
+ int32_t iMax =
+ pChild->JSObject()->GetInteger(XFA_Attribute::MaxLength);
+ return {XFA_Element::ExData, iMax < 0 ? 0 : iMax};
+ }
+ default:
+ break;
+ }
+ }
+ }
+ return {XFA_Element::Unknown, 0};
+}
+
+int32_t CXFA_Node::GetFracDigits() {
+ CXFA_Value* pNode =
+ m_pNode->GetChild<CXFA_Value>(0, XFA_Element::Value, false);
+ if (!pNode)
+ return -1;
+
+ CXFA_Decimal* pChild =
+ pNode->GetChild<CXFA_Decimal>(0, XFA_Element::Decimal, false);
+ if (!pChild)
+ return -1;
+
+ return pChild->JSObject()
+ ->TryInteger(XFA_Attribute::FracDigits, true)
+ .value_or(-1);
+}
+
+int32_t CXFA_Node::GetLeadDigits() {
+ CXFA_Value* pNode =
+ m_pNode->GetChild<CXFA_Value>(0, XFA_Element::Value, false);
+ if (!pNode)
+ return -1;
+
+ CXFA_Decimal* pChild =
+ pNode->GetChild<CXFA_Decimal>(0, XFA_Element::Decimal, false);
+ if (!pChild)
+ return -1;
+
+ return pChild->JSObject()
+ ->TryInteger(XFA_Attribute::LeadDigits, true)
+ .value_or(-1);
+}
+
+bool CXFA_Node::SetValue(XFA_VALUEPICTURE eValueType,
+ const WideString& wsValue) {
+ if (wsValue.IsEmpty()) {
+ m_pNode->SyncValue(wsValue, true);
+ return true;
+ }
+
+ m_pNode->SetPreNull(m_pNode->IsNull());
+ m_pNode->SetIsNull(false);
+
+ WideString wsNewText(wsValue);
+ WideString wsPicture = GetPictureContent(eValueType);
+ bool bValidate = true;
+ bool bSyncData = false;
+ CXFA_Node* pNode = m_pNode->GetUIChild();
+ if (!pNode)
+ return true;
+
+ XFA_Element eType = pNode->GetElementType();
+ if (!wsPicture.IsEmpty()) {
+ CXFA_LocaleMgr* pLocalMgr = m_pNode->GetDocument()->GetLocalMgr();
+ IFX_Locale* pLocale = m_pNode->GetLocale();
+ CXFA_LocaleValue widgetValue = XFA_GetLocaleValue(GetNode());
+ bValidate =
+ widgetValue.ValidateValue(wsValue, wsPicture, pLocale, &wsPicture);
+ if (bValidate) {
+ widgetValue = CXFA_LocaleValue(widgetValue.GetType(), wsNewText,
+ wsPicture, pLocale, pLocalMgr);
+ wsNewText = widgetValue.GetValue();
+ if (eType == XFA_Element::NumericEdit)
+ wsNewText = NumericLimit(wsNewText, GetLeadDigits(), GetFracDigits());
+
+ bSyncData = true;
+ }
+ } else {
+ if (eType == XFA_Element::NumericEdit) {
+ if (wsNewText != L"0")
+ wsNewText = NumericLimit(wsNewText, GetLeadDigits(), GetFracDigits());
+
+ bSyncData = true;
+ }
+ }
+ if (eType != XFA_Element::NumericEdit || bSyncData)
+ m_pNode->SyncValue(wsNewText, true);
+
+ return bValidate;
+}
+
+WideString CXFA_Node::GetPictureContent(XFA_VALUEPICTURE ePicture) {
+ if (ePicture == XFA_VALUEPICTURE_Raw)
+ return L"";
+
+ CXFA_LocaleValue widgetValue = XFA_GetLocaleValue(GetNode());
+ switch (ePicture) {
+ case XFA_VALUEPICTURE_Display: {
+ if (CXFA_Format* pFormat =
+ m_pNode->GetChild<CXFA_Format>(0, XFA_Element::Format, false)) {
+ if (CXFA_Picture* pPicture = pFormat->GetChild<CXFA_Picture>(
+ 0, XFA_Element::Picture, false)) {
+ Optional<WideString> picture =
+ pPicture->JSObject()->TryContent(false, true);
+ if (picture)
+ return *picture;
+ }
+ }
+
+ IFX_Locale* pLocale = m_pNode->GetLocale();
+ if (!pLocale)
+ return L"";
+
+ uint32_t dwType = widgetValue.GetType();
+ switch (dwType) {
+ case XFA_VT_DATE:
+ return pLocale->GetDatePattern(FX_LOCALEDATETIMESUBCATEGORY_Medium);
+ case XFA_VT_TIME:
+ return pLocale->GetTimePattern(FX_LOCALEDATETIMESUBCATEGORY_Medium);
+ case XFA_VT_DATETIME:
+ return pLocale->GetDatePattern(FX_LOCALEDATETIMESUBCATEGORY_Medium) +
+ L"T" +
+ pLocale->GetTimePattern(FX_LOCALEDATETIMESUBCATEGORY_Medium);
+ case XFA_VT_DECIMAL:
+ case XFA_VT_FLOAT:
+ default:
+ return L"";
+ }
+ }
+ case XFA_VALUEPICTURE_Edit: {
+ CXFA_Ui* pUI = m_pNode->GetChild<CXFA_Ui>(0, XFA_Element::Ui, false);
+ if (pUI) {
+ if (CXFA_Picture* pPicture =
+ pUI->GetChild<CXFA_Picture>(0, XFA_Element::Picture, false)) {
+ Optional<WideString> picture =
+ pPicture->JSObject()->TryContent(false, true);
+ if (picture)
+ return *picture;
+ }
+ }
+
+ IFX_Locale* pLocale = m_pNode->GetLocale();
+ if (!pLocale)
+ return L"";
+
+ uint32_t dwType = widgetValue.GetType();
+ switch (dwType) {
+ case XFA_VT_DATE:
+ return pLocale->GetDatePattern(FX_LOCALEDATETIMESUBCATEGORY_Short);
+ case XFA_VT_TIME:
+ return pLocale->GetTimePattern(FX_LOCALEDATETIMESUBCATEGORY_Short);
+ case XFA_VT_DATETIME:
+ return pLocale->GetDatePattern(FX_LOCALEDATETIMESUBCATEGORY_Short) +
+ L"T" +
+ pLocale->GetTimePattern(FX_LOCALEDATETIMESUBCATEGORY_Short);
+ default:
+ return L"";
+ }
+ }
+ case XFA_VALUEPICTURE_DataBind: {
+ CXFA_Bind* bind = m_pNode->GetBindIfExists();
+ if (bind)
+ return bind->GetPicture();
+ break;
+ }
+ default:
+ break;
+ }
+ return L"";
+}
+
+WideString CXFA_Node::GetValue(XFA_VALUEPICTURE eValueType) {
+ WideString wsValue = m_pNode->JSObject()->GetContent(false);
+
+ if (eValueType == XFA_VALUEPICTURE_Display)
+ GetItemLabel(wsValue.AsStringView(), wsValue);
+
+ WideString wsPicture = GetPictureContent(eValueType);
+ CXFA_Node* pNode = m_pNode->GetUIChild();
+ if (!pNode)
+ return wsValue;
+
+ switch (m_pNode->GetUIChild()->GetElementType()) {
+ case XFA_Element::ChoiceList: {
+ if (eValueType == XFA_VALUEPICTURE_Display) {
+ int32_t iSelItemIndex = GetSelectedItem(0);
+ if (iSelItemIndex >= 0) {
+ wsValue = GetChoiceListItem(iSelItemIndex, false).value_or(L"");
+ wsPicture.clear();
+ }
+ }
+ } break;
+ case XFA_Element::NumericEdit:
+ if (eValueType != XFA_VALUEPICTURE_Raw && wsPicture.IsEmpty()) {
+ IFX_Locale* pLocale = m_pNode->GetLocale();
+ if (eValueType == XFA_VALUEPICTURE_Display && pLocale)
+ wsValue = FormatNumStr(NormalizeNumStr(wsValue), pLocale);
+ }
+ break;
+ default:
+ break;
+ }
+ if (wsPicture.IsEmpty())
+ return wsValue;
+
+ if (IFX_Locale* pLocale = m_pNode->GetLocale()) {
+ CXFA_LocaleValue widgetValue = XFA_GetLocaleValue(GetNode());
+ CXFA_LocaleMgr* pLocalMgr = m_pNode->GetDocument()->GetLocalMgr();
+ switch (widgetValue.GetType()) {
+ case XFA_VT_DATE: {
+ WideString wsDate, wsTime;
+ if (SplitDateTime(wsValue, wsDate, wsTime)) {
+ CXFA_LocaleValue date(XFA_VT_DATE, wsDate, pLocalMgr);
+ if (date.FormatPatterns(wsValue, wsPicture, pLocale, eValueType))
+ return wsValue;
+ }
+ break;
+ }
+ case XFA_VT_TIME: {
+ WideString wsDate, wsTime;
+ if (SplitDateTime(wsValue, wsDate, wsTime)) {
+ CXFA_LocaleValue time(XFA_VT_TIME, wsTime, pLocalMgr);
+ if (time.FormatPatterns(wsValue, wsPicture, pLocale, eValueType))
+ return wsValue;
+ }
+ break;
+ }
+ default:
+ break;
+ }
+ widgetValue.FormatPatterns(wsValue, wsPicture, pLocale, eValueType);
+ }
+ return wsValue;
+}
+
+WideString CXFA_Node::GetNormalizeDataValue(const WideString& wsValue) {
+ if (wsValue.IsEmpty())
+ return L"";
+
+ WideString wsPicture = GetPictureContent(XFA_VALUEPICTURE_DataBind);
+ if (wsPicture.IsEmpty())
+ return wsValue;
+
+ ASSERT(GetNode());
+ CXFA_LocaleMgr* pLocalMgr = GetNode()->GetDocument()->GetLocalMgr();
+ IFX_Locale* pLocale = m_pNode->GetLocale();
+ CXFA_LocaleValue widgetValue = XFA_GetLocaleValue(GetNode());
+ if (widgetValue.ValidateValue(wsValue, wsPicture, pLocale, &wsPicture)) {
+ widgetValue = CXFA_LocaleValue(widgetValue.GetType(), wsValue, wsPicture,
+ pLocale, pLocalMgr);
+ return widgetValue.GetValue();
+ }
+ return wsValue;
+}
+
+WideString CXFA_Node::GetFormatDataValue(const WideString& wsValue) {
+ if (wsValue.IsEmpty())
+ return L"";
+
+ WideString wsPicture = GetPictureContent(XFA_VALUEPICTURE_DataBind);
+ if (wsPicture.IsEmpty())
+ return wsValue;
+
+ WideString wsFormattedValue = wsValue;
+ if (IFX_Locale* pLocale = m_pNode->GetLocale()) {
+ ASSERT(GetNode());
+ CXFA_Value* pNodeValue =
+ GetNode()->GetChild<CXFA_Value>(0, XFA_Element::Value, false);
+ if (!pNodeValue)
+ return wsValue;
+
+ CXFA_Node* pValueChild = pNodeValue->GetFirstChild();
+ if (!pValueChild)
+ return wsValue;
+
+ int32_t iVTType = XFA_VT_NULL;
+ switch (pValueChild->GetElementType()) {
+ case XFA_Element::Decimal:
+ iVTType = XFA_VT_DECIMAL;
+ break;
+ case XFA_Element::Float:
+ iVTType = XFA_VT_FLOAT;
+ break;
+ case XFA_Element::Date:
+ iVTType = XFA_VT_DATE;
+ break;
+ case XFA_Element::Time:
+ iVTType = XFA_VT_TIME;
+ break;
+ case XFA_Element::DateTime:
+ iVTType = XFA_VT_DATETIME;
+ break;
+ case XFA_Element::Boolean:
+ iVTType = XFA_VT_BOOLEAN;
+ break;
+ case XFA_Element::Integer:
+ iVTType = XFA_VT_INTEGER;
+ break;
+ case XFA_Element::Text:
+ iVTType = XFA_VT_TEXT;
+ break;
+ default:
+ iVTType = XFA_VT_NULL;
+ break;
+ }
+ CXFA_LocaleMgr* pLocalMgr = GetNode()->GetDocument()->GetLocalMgr();
+ CXFA_LocaleValue widgetValue(iVTType, wsValue, pLocalMgr);
+ switch (widgetValue.GetType()) {
+ case XFA_VT_DATE: {
+ WideString wsDate, wsTime;
+ if (SplitDateTime(wsValue, wsDate, wsTime)) {
+ CXFA_LocaleValue date(XFA_VT_DATE, wsDate, pLocalMgr);
+ if (date.FormatPatterns(wsFormattedValue, wsPicture, pLocale,
+ XFA_VALUEPICTURE_DataBind)) {
+ return wsFormattedValue;
+ }
+ }
+ break;
+ }
+ case XFA_VT_TIME: {
+ WideString wsDate, wsTime;
+ if (SplitDateTime(wsValue, wsDate, wsTime)) {
+ CXFA_LocaleValue time(XFA_VT_TIME, wsTime, pLocalMgr);
+ if (time.FormatPatterns(wsFormattedValue, wsPicture, pLocale,
+ XFA_VALUEPICTURE_DataBind)) {
+ return wsFormattedValue;
+ }
+ }
+ break;
+ }
+ default:
+ break;
+ }
+ widgetValue.FormatPatterns(wsFormattedValue, wsPicture, pLocale,
+ XFA_VALUEPICTURE_DataBind);
+ }
+ return wsFormattedValue;
+}
+
+WideString CXFA_Node::NormalizeNumStr(const WideString& wsValue) {
+ if (wsValue.IsEmpty())
+ return L"";
+
+ WideString wsOutput = wsValue;
+ wsOutput.TrimLeft('0');
+
+ if (!wsOutput.IsEmpty() && wsOutput.Contains('.') && GetFracDigits() != -1) {
+ wsOutput.TrimRight(L"0");
+ wsOutput.TrimRight(L".");
+ }
+ if (wsOutput.IsEmpty() || wsOutput[0] == '.')
+ wsOutput.InsertAtFront('0');
+
+ return wsOutput;
+}
+
+WideString CXFA_Node::FormatNumStr(const WideString& wsValue,
+ IFX_Locale* pLocale) {
+ if (wsValue.IsEmpty())
+ return L"";
+
+ WideString wsSrcNum = wsValue;
+ WideString wsGroupSymbol =
+ pLocale->GetNumbericSymbol(FX_LOCALENUMSYMBOL_Grouping);
+ bool bNeg = false;
+ if (wsSrcNum[0] == '-') {
+ bNeg = true;
+ wsSrcNum.Delete(0, 1);
+ }
+
+ auto dot_index = wsSrcNum.Find('.');
+ dot_index = !dot_index.has_value() ? wsSrcNum.GetLength() : dot_index;
+
+ if (dot_index.value() < 1)
+ return L"";
+
+ size_t nPos = dot_index.value() % 3;
+ WideString wsOutput;
+ for (size_t i = 0; i < dot_index.value(); i++) {
+ if (i % 3 == nPos && i != 0)
+ wsOutput += wsGroupSymbol;
+
+ wsOutput += wsSrcNum[i];
+ }
+ if (dot_index.value() < wsSrcNum.GetLength()) {
+ wsOutput += pLocale->GetNumbericSymbol(FX_LOCALENUMSYMBOL_Decimal);
+ wsOutput += wsSrcNum.Right(wsSrcNum.GetLength() - dot_index.value() - 1);
+ }
+ if (bNeg)
+ return pLocale->GetNumbericSymbol(FX_LOCALENUMSYMBOL_Minus) + wsOutput;
+
+ return wsOutput;
+}
+
+void CXFA_Node::InsertListTextItem(CXFA_Node* pItems,
+ const WideString& wsText,
+ int32_t nIndex) {
+ CXFA_Node* pText = pItems->CreateSamePacketNode(XFA_Element::Text);
+ pItems->InsertChild(nIndex, pText);
+ pText->JSObject()->SetContent(wsText, wsText, false, false, false);
+}
+
+WideString CXFA_Node::NumericLimit(const WideString& wsValue,
+ int32_t iLead,
+ int32_t iTread) const {
+ if ((iLead == -1) && (iTread == -1))
+ return wsValue;
+
+ WideString wsRet;
+ int32_t iLead_ = 0, iTread_ = -1;
+ int32_t iCount = wsValue.GetLength();
+ if (iCount == 0)
+ return wsValue;
+
+ int32_t i = 0;
+ if (wsValue[i] == L'-') {
+ wsRet += L'-';
+ i++;
+ }
+ for (; i < iCount; i++) {
+ wchar_t wc = wsValue[i];
+ if (FXSYS_isDecimalDigit(wc)) {
+ if (iLead >= 0) {
+ iLead_++;
+ if (iLead_ > iLead)
+ return L"0";
+ } else if (iTread_ >= 0) {
+ iTread_++;
+ if (iTread_ > iTread) {
+ if (iTread != -1) {
+ CFX_Decimal wsDeci = CFX_Decimal(wsValue.AsStringView());
+ wsDeci.SetScale(iTread);
+ wsRet = wsDeci;
+ }
+ return wsRet;
+ }
+ }
+ } else if (wc == L'.') {
+ iTread_ = 0;
+ iLead = -1;
+ }
+ wsRet += wc;
+ }
+ return wsRet;
+}
diff --git a/xfa/fxfa/parser/cxfa_node.h b/xfa/fxfa/parser/cxfa_node.h
index 0991a533c8..6b6e865353 100644
--- a/xfa/fxfa/parser/cxfa_node.h
+++ b/xfa/fxfa/parser/cxfa_node.h
@@ -18,6 +18,8 @@
#include "third_party/base/optional.h"
#include "xfa/fxfa/parser/cxfa_object.h"
+class CFGAS_GEFont;
+class CFX_DIBitmap;
class CFX_XMLNode;
class CXFA_Bind;
class CXFA_Border;
@@ -25,21 +27,37 @@ class CXFA_Calculate;
class CXFA_Caption;
class CXFA_Event;
class CXFA_EventParam;
+class CXFA_FFDoc;
class CXFA_FFDocView;
+class CXFA_FFWidget;
class CXFA_Font;
class CXFA_Margin;
class CXFA_Occur;
class CXFA_Para;
class CXFA_Script;
+class CXFA_TextLayout;
class CXFA_Validate;
class CXFA_Value;
-class CXFA_WidgetAcc;
+class CXFA_WidgetLayoutData;
class IFX_Locale;
#define XFA_NODEFILTER_Children 0x01
#define XFA_NODEFILTER_Properties 0x02
#define XFA_NODEFILTER_OneOfProperty 0x04
+enum XFA_CHECKSTATE {
+ XFA_CHECKSTATE_On = 0,
+ XFA_CHECKSTATE_Off = 1,
+ XFA_CHECKSTATE_Neutral = 2,
+};
+
+enum XFA_VALUEPICTURE {
+ XFA_VALUEPICTURE_Raw = 0,
+ XFA_VALUEPICTURE_Display,
+ XFA_VALUEPICTURE_Edit,
+ XFA_VALUEPICTURE_DataBind,
+};
+
enum XFA_NodeFlag {
XFA_NodeFlag_None = 0,
XFA_NodeFlag_Initialized = 1 << 0,
@@ -304,17 +322,130 @@ class CXFA_Node : public CXFA_Object {
bool IsNull() const { return m_bIsNull; }
void SetIsNull(bool val) { m_bIsNull = val; }
- void SetWidgetReady();
+ void SetWidgetReady() { is_widget_ready_ = true; }
bool IsWidgetReady() const { return is_widget_ready_; }
- CXFA_WidgetAcc* GetWidgetAcc() {
+ // TODO(dsinclair): Remove post WidgetAcc merge.
+ CXFA_Node* GetWidgetAcc() {
ASSERT(IsWidgetReady());
- ASSERT(acc_.get() != nullptr);
- return acc_.get();
+ return this;
}
std::vector<CXFA_Event*> GetEventByActivity(XFA_AttributeEnum iActivity,
bool bIsFormReady);
+ void ResetData();
+
+ CXFA_FFWidget* GetNextWidget(CXFA_FFWidget* pWidget);
+ void StartWidgetLayout(CXFA_FFDoc* doc,
+ float& fCalcWidth,
+ float& fCalcHeight);
+ bool FindSplitPos(CXFA_FFDocView* docView,
+ int32_t iBlockIndex,
+ float& fCalcHeight);
+
+ bool LoadCaption(CXFA_FFDoc* doc);
+ CXFA_TextLayout* GetCaptionTextLayout();
+
+ void LoadText(CXFA_FFDoc* doc);
+ CXFA_TextLayout* GetTextLayout();
+
+ bool LoadImageImage(CXFA_FFDoc* doc);
+ bool LoadImageEditImage(CXFA_FFDoc* doc);
+ void GetImageDpi(int32_t& iImageXDpi, int32_t& iImageYDpi);
+ void GetImageEditDpi(int32_t& iImageXDpi, int32_t& iImageYDpi);
+
+ RetainPtr<CFX_DIBitmap> GetImageImage();
+ RetainPtr<CFX_DIBitmap> GetImageEditImage();
+ void SetImageEdit(const WideString& wsContentType,
+ const WideString& wsHref,
+ const WideString& wsData);
+ void SetImageImage(const RetainPtr<CFX_DIBitmap>& newImage);
+ void SetImageEditImage(const RetainPtr<CFX_DIBitmap>& newImage);
+ void UpdateUIDisplay(CXFA_FFDocView* docView, CXFA_FFWidget* pExcept);
+
+ RetainPtr<CFGAS_GEFont> GetFDEFont(CXFA_FFDoc* doc);
+
+ // TODO(dsinclair): Remove post WidgetAcc merge.
+ CXFA_Node* GetNode() { return this; }
+
+ bool IsOpenAccess() const;
+ bool IsListBox();
+ bool IsAllowNeutral();
+ bool IsRadioButton();
+ bool IsChoiceListAllowTextEntry();
+ bool IsMultiLine();
+
+ XFA_AttributeEnum GetButtonHighlight();
+ bool HasButtonRollover() const;
+ bool HasButtonDown() const;
+
+ bool IsCheckButtonRound();
+ XFA_AttributeEnum GetCheckButtonMark();
+ float GetCheckButtonSize();
+
+ XFA_CHECKSTATE GetCheckState();
+ void SetCheckState(XFA_CHECKSTATE eCheckState, bool bNotify);
+
+ CXFA_Node* GetSelectedMember();
+ CXFA_Node* SetSelectedMember(const WideStringView& wsName, bool bNotify);
+ void SetSelectedMemberByValue(const WideStringView& wsValue,
+ bool bNotify,
+ bool bScriptModify,
+ bool bSyncData);
+
+ CXFA_Node* GetExclGroupFirstMember();
+ CXFA_Node* GetExclGroupNextMember(CXFA_Node* pNode);
+
+ int32_t CountChoiceListItems(bool bSaveValue);
+ Optional<WideString> GetChoiceListItem(int32_t nIndex, bool bSaveValue);
+ bool IsChoiceListMultiSelect();
+ bool IsChoiceListCommitOnSelect();
+ std::vector<WideString> GetChoiceListItems(bool bSaveValue);
+
+ int32_t CountSelectedItems();
+ int32_t GetSelectedItem(int32_t nIndex);
+ std::vector<int32_t> GetSelectedItems();
+ std::vector<WideString> GetSelectedItemsValue();
+ void SetSelectedItems(const std::vector<int32_t>& iSelArray,
+ bool bNotify,
+ bool bScriptModify,
+ bool bSyncData);
+ void InsertItem(const WideString& wsLabel,
+ const WideString& wsValue,
+ bool bNotify);
+ bool DeleteItem(int32_t nIndex, bool bNotify, bool bScriptModify);
+ void ClearAllSelections();
+
+ bool GetItemState(int32_t nIndex);
+ void SetItemState(int32_t nIndex,
+ bool bSelected,
+ bool bNotify,
+ bool bScriptModify,
+ bool bSyncData);
+
+ WideString GetItemValue(const WideStringView& wsLabel);
+
+ bool IsHorizontalScrollPolicyOff();
+ bool IsVerticalScrollPolicyOff();
+ Optional<int32_t> GetNumberOfCells();
+
+ bool SetValue(XFA_VALUEPICTURE eValueType, const WideString& wsValue);
+ WideString GetValue(XFA_VALUEPICTURE eValueType);
+
+ WideString GetPictureContent(XFA_VALUEPICTURE ePicture);
+ WideString GetNormalizeDataValue(const WideString& wsValue);
+ WideString GetFormatDataValue(const WideString& wsValue);
+ WideString NormalizeNumStr(const WideString& wsValue);
+
+ WideString GetPasswordChar();
+ std::pair<XFA_Element, int32_t> GetMaxChars();
+ int32_t GetFracDigits();
+ int32_t GetLeadDigits();
+
+ WideString NumericLimit(const WideString& wsValue,
+ int32_t iLead,
+ int32_t iTread) const;
+
protected:
CXFA_Node(CXFA_Document* pDoc,
XFA_PacketType ePacket,
@@ -363,6 +494,35 @@ class CXFA_Node : public CXFA_Object {
CXFA_Node* GetNextSameNameSiblingInternal(
const WideStringView& wsNodeName) const;
CXFA_Node* GetNextSameClassSiblingInternal(XFA_Element eType) const;
+ void CalcCaptionSize(CXFA_FFDoc* doc, CFX_SizeF& szCap);
+ bool CalculateFieldAutoSize(CXFA_FFDoc* doc, CFX_SizeF& size);
+ bool CalculateWidgetAutoSize(CFX_SizeF& size);
+ bool CalculateTextEditAutoSize(CXFA_FFDoc* doc, CFX_SizeF& size);
+ bool CalculateCheckButtonAutoSize(CXFA_FFDoc* doc, CFX_SizeF& size);
+ bool CalculatePushButtonAutoSize(CXFA_FFDoc* doc, CFX_SizeF& size);
+ CFX_SizeF CalculateImageSize(float img_width,
+ float img_height,
+ float dpi_x,
+ float dpi_y);
+ bool CalculateImageEditAutoSize(CXFA_FFDoc* doc, CFX_SizeF& size);
+ bool CalculateImageAutoSize(CXFA_FFDoc* doc, CFX_SizeF& size);
+ float CalculateWidgetAutoHeight(float fHeightCalc);
+ float CalculateWidgetAutoWidth(float fWidthCalc);
+ float GetWidthWithoutMargin(float fWidthCalc);
+ float GetHeightWithoutMargin(float fHeightCalc);
+ void CalculateTextContentSize(CXFA_FFDoc* doc, CFX_SizeF& size);
+ void CalculateAccWidthAndHeight(CXFA_FFDoc* doc,
+ XFA_Element eUIType,
+ float& fWidth,
+ float& fCalcHeight);
+ void InitLayoutData();
+ void StartTextLayout(CXFA_FFDoc* doc, float& fCalcWidth, float& fCalcHeight);
+
+ void InsertListTextItem(CXFA_Node* pItems,
+ const WideString& wsText,
+ int32_t nIndex);
+ WideString FormatNumStr(const WideString& wsValue, IFX_Locale* pLocale);
+ void GetItemLabel(const WideStringView& wsValue, WideString& wsLabel);
const PropertyData* const m_Properties;
const AttributeData* const m_Attributes;
@@ -383,7 +543,9 @@ class CXFA_Node : public CXFA_Object {
bool m_bIsNull = true;
bool m_bPreNull = true;
bool is_widget_ready_ = false;
- std::unique_ptr<CXFA_WidgetAcc> acc_;
+ std::unique_ptr<CXFA_WidgetLayoutData> m_pLayoutData;
+ // TODO(dsinclair): Remove post WidgetAcc merge.
+ CXFA_Node* m_pNode;
};
#endif // XFA_FXFA_PARSER_CXFA_NODE_H_
diff --git a/xfa/fxfa/parser/xfa_document_datamerger_imp.cpp b/xfa/fxfa/parser/xfa_document_datamerger_imp.cpp
index d843fa8896..8b0fa40250 100644
--- a/xfa/fxfa/parser/xfa_document_datamerger_imp.cpp
+++ b/xfa/fxfa/parser/xfa_document_datamerger_imp.cpp
@@ -16,7 +16,6 @@
#include "fxjs/xfa/cjx_object.h"
#include "third_party/base/logging.h"
#include "third_party/base/stl_util.h"
-#include "xfa/fxfa/cxfa_widgetacc.h"
#include "xfa/fxfa/parser/cxfa_bind.h"
#include "xfa/fxfa/parser/cxfa_datagroup.h"
#include "xfa/fxfa/parser/cxfa_document.h"