#include "core/fpdfdoc/cpdf_interactiveform.h"
#include <optional>
#include <type_traits>
#include <utility>
#include <vector>
#include "build/build_config.h"
#include "constants/form_fields.h"
#include "constants/form_flags.h"
#include "constants/stream_dict_common.h"
#include "core/fpdfapi/font/cpdf_font.h"
#include "core/fpdfapi/font/cpdf_fontencoding.h"
#include "core/fpdfapi/page/cpdf_docpagedata.h"
#include "core/fpdfapi/page/cpdf_page.h"
#include "core/fpdfapi/parser/cfdf_document.h"
#include "core/fpdfapi/parser/cpdf_array.h"
#include "core/fpdfapi/parser/cpdf_dictionary.h"
#include "core/fpdfapi/parser/cpdf_document.h"
#include "core/fpdfapi/parser/cpdf_name.h"
#include "core/fpdfapi/parser/cpdf_reference.h"
#include "core/fpdfapi/parser/cpdf_stream.h"
#include "core/fpdfapi/parser/cpdf_string.h"
#include "core/fpdfapi/parser/fpdf_parser_utility.h"
#include "core/fpdfdoc/cpdf_filespec.h"
#include "core/fpdfdoc/cpdf_formcontrol.h"
#include "core/fxcrt/check.h"
#include "core/fxcrt/compiler_specific.h"
#include "core/fxcrt/containers/contains.h"
#include "core/fxcrt/fx_codepage.h"
#include "core/fxcrt/fx_memcpy_wrappers.h"
#include "core/fxcrt/numerics/safe_conversions.h"
#include "core/fxcrt/stl_util.h"
#include "core/fxge/fx_font.h"
#if BUILDFLAG(IS_WIN)
#include "core/fxcrt/win/win_util.h"
#endif
namespace {
const int nMaxRecursion = …;
#if BUILDFLAG(IS_WIN)
struct PDF_FONTDATA {
bool bFind;
LOGFONTA lf;
};
int CALLBACK EnumFontFamExProc(ENUMLOGFONTEXA* lpelfe,
NEWTEXTMETRICEX* lpntme,
DWORD FontType,
LPARAM lParam) {
if (FontType != 0x004 || strchr(lpelfe->elfLogFont.lfFaceName, '@'))
return 1;
PDF_FONTDATA* pData = (PDF_FONTDATA*)lParam;
pData->lf = lpelfe->elfLogFont;
pData->bFind = true;
return 0;
}
bool RetrieveSpecificFont(FX_Charset charSet,
LPCSTR pcsFontName,
LOGFONTA& lf) {
lf = {};
static_assert(std::is_aggregate_v<std::remove_reference_t<decltype(lf)>>);
lf.lfCharSet = static_cast<int>(charSet);
lf.lfPitchAndFamily = DEFAULT_PITCH | FF_DONTCARE;
if (pcsFontName) {
strcpy(lf.lfFaceName, pcsFontName);
}
PDF_FONTDATA fd = {};
static_assert(std::is_aggregate_v<decltype(fd)>);
HDC hDC = ::GetDC(nullptr);
EnumFontFamiliesExA(hDC, &lf, (FONTENUMPROCA)EnumFontFamExProc, (LPARAM)&fd,
0);
::ReleaseDC(nullptr, hDC);
if (fd.bFind) {
UNSAFE_TODO(FXSYS_memcpy(&lf, &fd.lf, sizeof(LOGFONTA)));
}
return fd.bFind;
}
#endif
ByteString GetNativeFontName(FX_Charset charSet, void* pLogFont) { … }
ByteString GenerateNewFontResourceName(const CPDF_Dictionary* pResDict,
const ByteString& csPrefix) { … }
RetainPtr<CPDF_Font> AddStandardFont(CPDF_Document* pDocument) { … }
RetainPtr<CPDF_Font> AddNativeFont(FX_Charset charSet,
CPDF_Document* pDocument) { … }
bool FindFont(const CPDF_Dictionary* pFormDict,
const CPDF_Font* pFont,
ByteString* csNameTag) { … }
bool FindFontFromDoc(const CPDF_Dictionary* pFormDict,
CPDF_Document* pDocument,
ByteString csFontName,
RetainPtr<CPDF_Font>& pFont,
ByteString* csNameTag) { … }
void AddFont(CPDF_Dictionary* pFormDict,
CPDF_Document* pDocument,
const RetainPtr<CPDF_Font>& pFont,
ByteString* csNameTag) { … }
FX_Charset GetNativeCharSet() { … }
RetainPtr<CPDF_Dictionary> InitDict(CPDF_Document* pDocument) { … }
RetainPtr<CPDF_Font> GetNativeFont(const CPDF_Dictionary* pFormDict,
CPDF_Document* pDocument,
FX_Charset charSet,
ByteString* csNameTag) { … }
class CFieldNameExtractor { … };
}
class CFieldTree { … };
CFieldTree::CFieldTree() : … { … }
CFieldTree::~CFieldTree() = default;
CFieldTree::Node* CFieldTree::AddChild(Node* pParent,
const WideString& short_name) { … }
CFieldTree::Node* CFieldTree::Lookup(Node* pParent, WideStringView short_name) { … }
bool CFieldTree::SetField(const WideString& full_name,
std::unique_ptr<CPDF_FormField> pField) { … }
CPDF_FormField* CFieldTree::GetField(const WideString& full_name) { … }
CFieldTree::Node* CFieldTree::FindNode(const WideString& full_name) { … }
CPDF_InteractiveForm::CPDF_InteractiveForm(CPDF_Document* pDocument)
: … { … }
CPDF_InteractiveForm::~CPDF_InteractiveForm() = default;
bool CPDF_InteractiveForm::s_bUpdateAP = …;
bool CPDF_InteractiveForm::IsUpdateAPEnabled() { … }
void CPDF_InteractiveForm::SetUpdateAP(bool bUpdateAP) { … }
RetainPtr<CPDF_Font> CPDF_InteractiveForm::AddNativeInteractiveFormFont(
CPDF_Document* pDocument,
ByteString* csNameTag) { … }
size_t CPDF_InteractiveForm::CountFields(const WideString& csFieldName) const { … }
CPDF_FormField* CPDF_InteractiveForm::GetField(
size_t index,
const WideString& csFieldName) const { … }
CPDF_FormField* CPDF_InteractiveForm::GetFieldByDict(
const CPDF_Dictionary* pFieldDict) const { … }
const CPDF_FormControl* CPDF_InteractiveForm::GetControlAtPoint(
const CPDF_Page* pPage,
const CFX_PointF& point,
int* z_order) const { … }
CPDF_FormControl* CPDF_InteractiveForm::GetControlByDict(
const CPDF_Dictionary* pWidgetDict) const { … }
bool CPDF_InteractiveForm::NeedConstructAP() const { … }
int CPDF_InteractiveForm::CountFieldsInCalculationOrder() { … }
CPDF_FormField* CPDF_InteractiveForm::GetFieldInCalculationOrder(int index) { … }
int CPDF_InteractiveForm::FindFieldInCalculationOrder(
const CPDF_FormField* pField) { … }
RetainPtr<CPDF_Font> CPDF_InteractiveForm::GetFormFont(
ByteString csNameTag) const { … }
RetainPtr<CPDF_Font> CPDF_InteractiveForm::GetFontForElement(
RetainPtr<CPDF_Dictionary> pElement) const { … }
CPDF_DefaultAppearance CPDF_InteractiveForm::GetDefaultAppearance() const { … }
int CPDF_InteractiveForm::GetFormAlignment() const { … }
void CPDF_InteractiveForm::ResetForm(pdfium::span<CPDF_FormField*> fields,
bool bIncludeOrExclude) { … }
void CPDF_InteractiveForm::ResetForm() { … }
const std::vector<UnownedPtr<CPDF_FormControl>>&
CPDF_InteractiveForm::GetControlsForField(const CPDF_FormField* pField) { … }
void CPDF_InteractiveForm::LoadField(RetainPtr<CPDF_Dictionary> pFieldDict,
int nLevel) { … }
void CPDF_InteractiveForm::FixPageFields(CPDF_Page* pPage) { … }
void CPDF_InteractiveForm::AddTerminalField(
RetainPtr<CPDF_Dictionary> pFieldDict) { … }
CPDF_FormControl* CPDF_InteractiveForm::AddControl(
CPDF_FormField* pField,
RetainPtr<CPDF_Dictionary> pWidgetDict) { … }
bool CPDF_InteractiveForm::CheckRequiredFields(
const std::vector<CPDF_FormField*>* fields,
bool bIncludeOrExclude) const { … }
std::unique_ptr<CFDF_Document> CPDF_InteractiveForm::ExportToFDF(
const WideString& pdf_path) const { … }
std::unique_ptr<CFDF_Document> CPDF_InteractiveForm::ExportToFDF(
const WideString& pdf_path,
const std::vector<CPDF_FormField*>& fields,
bool bIncludeOrExclude) const { … }
void CPDF_InteractiveForm::SetNotifierIface(NotifierIface* pNotify) { … }
bool CPDF_InteractiveForm::NotifyBeforeValueChange(CPDF_FormField* pField,
const WideString& csValue) { … }
void CPDF_InteractiveForm::NotifyAfterValueChange(CPDF_FormField* pField) { … }
bool CPDF_InteractiveForm::NotifyBeforeSelectionChange(
CPDF_FormField* pField,
const WideString& csValue) { … }
void CPDF_InteractiveForm::NotifyAfterSelectionChange(CPDF_FormField* pField) { … }
void CPDF_InteractiveForm::NotifyAfterCheckedStatusChange(
CPDF_FormField* pField) { … }