diff --git a/PdfFile/PdfReader.cpp b/PdfFile/PdfReader.cpp index b4c45fcd81..2f8a7c2082 100644 --- a/PdfFile/PdfReader.cpp +++ b/PdfFile/PdfReader.cpp @@ -914,7 +914,7 @@ void getAction(PDFDoc* pdfDoc, NSWasm::CData& oRes, Object* oAction, int nAnnot) } else if (oHide.isRef()) { - int nFind = pAcroForms->findFieldIdx(&oHide); + int nFind = pAcroForms->findFirstFieldIdx(&oHide); if (nFind >= 0) { nFields++; @@ -966,7 +966,7 @@ void getAction(PDFDoc* pdfDoc, NSWasm::CData& oRes, Object* oAction, int nAnnot) } else if (oField.isRef()) { - int nFind = pAcroForms->findFieldIdx(&oField); + int nFind = pAcroForms->findFirstFieldIdx(&oField); if (nFind >= 0) { nFields++; @@ -1024,7 +1024,7 @@ BYTE* CPdfReader::GetWidgets() oCO.arrayGetNF(j, &oField); if (oField.isRef()) { - int nFind = pAcroForms->findFieldIdx(&oField); + int nFind = pAcroForms->findFirstFieldIdx(&oField); if (nFind >= 0) { nFields++; @@ -1035,6 +1035,8 @@ BYTE* CPdfReader::GetWidgets() } oRes.AddInt(nFields, nFieldsPos); } + else + oRes.AddInt(0); oCO.free(); for (int i = 0, nNum = pAcroForms->getNumFields(); i < nNum; ++i) @@ -2078,6 +2080,7 @@ BYTE* CPdfReader::GetAPWidget(int nRasterW, int nRasterH, int nBackgroundColor, nWidth += 2; nHeight += 2; + // Отрисовка на прозрачном холсте с заданым цветом фона BYTE* pBgraData = new BYTE[nWidth * nHeight * 4]; unsigned int nColor = (unsigned int)nBackgroundColor; unsigned int nSize = (unsigned int)(nWidth * nHeight); diff --git a/PdfFile/lib/xpdf/AcroForm.cc b/PdfFile/lib/xpdf/AcroForm.cc index e77defa35f..5064e2640f 100644 --- a/PdfFile/lib/xpdf/AcroForm.cc +++ b/PdfFile/lib/xpdf/AcroForm.cc @@ -608,21 +608,60 @@ int AcroForm::findFieldIdx(int pg, double x, double y) { return -1; } -int AcroForm::findFieldIdx(Object* oRefObj) { +int AcroForm::findFirstFieldIdx(Object* fieldRef) { AcroFormField *field; - int i; + Object fieldObj, kidsObj, kidRef, kidObj, subtypeObj; + GBool isTerminal; + int i, nRes; + nRes = -1; - if (!oRefObj || !oRefObj->isRef()) { - return -1; + if (!fieldRef || !fieldRef->isRef()) { + return nRes; } - for (i = 0; i < fields->getLength(); ++i) { - field = (AcroFormField *)fields->get(i); - if (oRefObj->getRefGen() == field->fieldRef.getRefGen() && - oRefObj->getRefNum() == field->fieldRef.getRefNum()) { - return i; + + fieldRef->fetch(doc->getXRef(), &fieldObj); + if (!fieldObj.isDict()) { + fieldObj.free(); + return nRes; + } + + isTerminal = gTrue; + if (fieldObj.dictLookup("Kids", &kidsObj)->isArray()) { + isTerminal = gFalse; + for (i = 0; !isTerminal && i < kidsObj.arrayGetLength(); ++i) { + kidsObj.arrayGet(i, &kidObj); + if (kidObj.isDict()) { + if (kidObj.dictLookup("Parent", &subtypeObj)->isNull()) { + isTerminal = gTrue; + } + subtypeObj.free(); + } + kidObj.free(); + } + if (!isTerminal) { + for (i = 0; !isTerminal && i < kidsObj.arrayGetLength(); ++i) { + kidsObj.arrayGetNF(i, &kidRef); + nRes = findFirstFieldIdx(&kidRef); + kidRef.free(); + if (nRes >= 0) + break; + } } } - return -1; + kidsObj.free(); + fieldObj.free(); + + if (isTerminal) { + for (i = 0; i < fields->getLength(); ++i) { + field = (AcroFormField *)fields->get(i); + if (fieldRef->getRefGen() == field->fieldRef.getRefGen() && + fieldRef->getRefNum() == field->fieldRef.getRefNum()) { + return i; + } + } + } + + return nRes; } GList* AcroForm::findFieldIdx(GString* fullName) { AcroFormField *field; diff --git a/PdfFile/lib/xpdf/AcroForm.h b/PdfFile/lib/xpdf/AcroForm.h index 7b16b576c8..f0fc2a6056 100644 --- a/PdfFile/lib/xpdf/AcroForm.h +++ b/PdfFile/lib/xpdf/AcroForm.h @@ -41,7 +41,7 @@ public: AcroFormField *getField(int idx); AcroFormField *findField(int pg, double x, double y); int findFieldIdx(int pg, double x, double y); - int findFieldIdx(Object* oRefObj); + int findFirstFieldIdx(Object* oRefObj); GList* findFieldIdx(GString* fullName); Object* getAcroFormObj() { return &acroFormObj; }