diff --git a/PdfFile/PdfEditor.cpp b/PdfFile/PdfEditor.cpp index ed34386b31..83f520f4b2 100644 --- a/PdfFile/PdfEditor.cpp +++ b/PdfFile/PdfEditor.cpp @@ -1288,9 +1288,32 @@ bool CPdfEditor::EditAnnot(int nPageIndex, int nID) } } oParentRef.free(); + continue; } else if (!strcmp("Opt", chKey)) bUnicode = true; + else if (!strcmp("AP", chKey) && pAnnot->GetAnnotationType() == PdfWriter::AnnotWidget) + { + PdfWriter::EWidgetType nType = ((PdfWriter::CWidgetAnnotation*)pAnnot)->GetWidgetType(); + if (nType == PdfWriter::WidgetRadiobutton || nType == PdfWriter::WidgetCheckbox) + { + PdfWriter::CCheckBoxWidget* pCAnnot = dynamic_cast(pAnnot); + + Object oAP, oN; + if (oAnnot.dictGetVal(nIndex, &oAP)->isDict() && oAP.dictLookup("N", &oN)->isDict()) + { + for (int j = 0, nNormLength = oN.dictGetLength(); j < nNormLength; ++j) + { + std::string sNormName(oN.dictGetKey(j)); + if (sNormName != "Off") + { + pCAnnot->SetAP_N_Yes(UTF8_TO_U(sNormName)); + break; + } + } + } + } + } Object oTemp; oAnnot.dictGetValNF(nIndex, &oTemp); DictToCDictObject(&oTemp, pAnnot, false, chKey, bUnicode); diff --git a/PdfFile/PdfWriter.cpp b/PdfFile/PdfWriter.cpp index a66eb2e115..9e39fec54c 100644 --- a/PdfFile/PdfWriter.cpp +++ b/PdfFile/PdfWriter.cpp @@ -2378,46 +2378,14 @@ HRESULT CPdfWriter::AddAnnotField(NSFonts::IApplicationFonts* pAppFonts, CAnnotF CAnnotFieldInfo::CWidgetAnnotPr::CButtonWidgetPr* pPrB = oInfo.GetWidgetAnnotPr()->GetButtonWidgetPr(); PdfWriter::CCheckBoxWidget* pButtonWidget = (PdfWriter::CCheckBoxWidget*)pAnnot; - std::wstring wsValue; if (nFlags & (1 << 14)) pButtonWidget->SetAP_N_Yes(pPrB->GetAP_N_Yes()); - if (nFlags & (1 << 9)) - { - wsValue = pPrB->GetV(); - pButtonWidget->SetV(wsValue); - } pButtonWidget->SetStyle(pPrB->GetStyle()); // ВНЕШНИЙ ВИД - // Если изменился текущий внешний вид - if (pButtonWidget->Get("AP")) - { - if (!wsValue.empty()) - pButtonWidget->SwitchAP(U_TO_UTF8(wsValue)); - return S_OK; - } - - pButtonWidget->SetAP(); - /* - put_FontName(wsFontName); - put_FontStyle(nStyle); - put_FontSize(dFontSize); - - if (m_bNeedUpdateTextFont) - UpdateFont(); - if (m_pFont) - pFontTT = m_pDocument->CreateTrueTypeFont(m_pFont); - pWidgetAnnot->SetDA(pFontTT, pPr->GetFontSize(), dFontSize, pPr->GetTC()); - - pButtonWidget->SetFont(m_pFont, dFontSize, isBold, isItalic); - if (!wsStyleValue.empty()) - { - double dMargin = 2; - double dBaseLine = dY2 - dY1 - dFontSize - dMargin; - pButtonWidget->SetAP(wsStyleValue, NULL, 0, 0, dBaseLine, NULL, NULL); - } - */ + if (!pButtonWidget->Get("AP")) + pButtonWidget->SetAP(); } } else if (oInfo.IsTextWidget()) @@ -2645,7 +2613,7 @@ HRESULT CPdfWriter::EditWidgetParents(NSFonts::IApplicationFonts* pAppFonts, CWi if (nFlags & (1 << 0)) pParentObj->Add("T", new PdfWriter::CStringObject((U_TO_UTF8(pParent->sName)).c_str())); - m_pDocument->SetParentKids(pParent->nID); + std::string sFT = m_pDocument->SetParentKids(pParent->nID); PdfWriter::CArrayObject* pKids = dynamic_cast(pParentObj->Get("Kids")); if (!pKids) { @@ -2653,46 +2621,6 @@ HRESULT CPdfWriter::EditWidgetParents(NSFonts::IApplicationFonts* pAppFonts, CWi pParentObj->Add("Kids", pKids); } - if (nFlags & (1 << 1)) - { - std::string sV = U_TO_UTF8(pParent->sV); - bool bName = !sV.empty() && (iswdigit(pParent->sV[0]) || sV == "Off"); - - for (int i = 0; i < pKids->GetCount(); ++i) - { - PdfWriter::CObjectBase* pObj = pKids->Get(i); - if (pObj->GetType() != PdfWriter::object_type_DICT || - ((PdfWriter::CDictObject*)pObj)->GetDictType() != PdfWriter::dict_type_ANNOTATION || - ((PdfWriter::CAnnotation*)pObj)->GetAnnotationType() != PdfWriter::AnnotWidget) - continue; - PdfWriter::EWidgetType nType = ((PdfWriter::CWidgetAnnotation*)pObj)->GetWidgetType(); - if (nType == PdfWriter::WidgetCheckbox || nType == PdfWriter::WidgetRadiobutton) - { - PdfWriter::CCheckBoxWidget* pKid = dynamic_cast(pObj); - if (pKid) - pKid->SwitchAP(sV, i); - } - if (nType == PdfWriter::WidgetCombobox || nType == PdfWriter::WidgetListbox) - { - PdfWriter::CChoiceWidget* pKid = dynamic_cast(pObj); - if (!pKid->HaveAPV()) - DrawChoiceWidget(pAppFonts, pKid, {pParent->sV}); - bName = false; - } - if (nType == PdfWriter::WidgetText) - { - PdfWriter::CTextWidget* pKid = dynamic_cast(pObj); - if (!pKid->HaveAPV()) - DrawTextWidget(pAppFonts, pKid, pParent->sV); - bName = false; - } - } - - if (bName) - pParentObj->Add("V", sV.c_str()); - else - pParentObj->Add("V", new PdfWriter::CStringObject(sV.c_str(), true)); - } if (nFlags & (1 << 2)) pParentObj->Add("DV", new PdfWriter::CStringObject((U_TO_UTF8(pParent->sDV)).c_str(), true)); if (nFlags & (1 << 3)) @@ -2735,6 +2663,8 @@ HRESULT CPdfWriter::EditWidgetParents(NSFonts::IApplicationFonts* pAppFonts, CWi } } } + int nIndexName = 0; + std::map mNameAP_N_Yes; if (nFlags & (1 << 6)) { PdfWriter::CArrayObject* pArray = new PdfWriter::CArrayObject(); @@ -2742,24 +2672,129 @@ HRESULT CPdfWriter::EditWidgetParents(NSFonts::IApplicationFonts* pAppFonts, CWi for (const std::pair& PV : pParent->arrOpt) { + std::string sValue; if (PV.first.empty()) { - std::string sValue = U_TO_UTF8(PV.second); + sValue = U_TO_UTF8(PV.second); pArray->Add(new PdfWriter::CStringObject(sValue.c_str(), true)); + + if (mNameAP_N_Yes.find(PV.second) == mNameAP_N_Yes.end()) + mNameAP_N_Yes[PV.second] = std::to_wstring(nIndexName++); } else { PdfWriter::CArrayObject* pArray2 = new PdfWriter::CArrayObject(); pArray->Add(pArray2); - std::string sValue = U_TO_UTF8(PV.first); + sValue = U_TO_UTF8(PV.first); pArray2->Add(new PdfWriter::CStringObject(sValue.c_str(), true)); + if (mNameAP_N_Yes.find(PV.first) == mNameAP_N_Yes.end()) + mNameAP_N_Yes[PV.first] = std::to_wstring(nIndexName++); + sValue = U_TO_UTF8(PV.second); pArray2->Add(new PdfWriter::CStringObject(sValue.c_str(), true)); } } } + if (nFlags & (1 << 1)) + { + std::string sV = U_TO_UTF8(pParent->sV); + if (sFT == "Btn") + { + int nOptIndex = -1; + if (isdigit(sV[0])) + nOptIndex = std::stoi(sV); + + if (!pParent->arrOpt.empty() && nOptIndex >= 0 && nOptIndex < pParent->arrOpt.size()) + { + std::pair PV = pParent->arrOpt[nOptIndex]; + std::wstring sOpt = PV.first.empty() ? PV.second : PV.first; + + for (int i = 0; i < pParent->arrOpt.size(); ++i) + { + if (i >= pKids->GetCount()) + break; + PdfWriter::CObjectBase* pObj = pKids->Get(i); + if (pObj->GetType() != PdfWriter::object_type_DICT || + ((PdfWriter::CDictObject*)pObj)->GetDictType() != PdfWriter::dict_type_ANNOTATION || + ((PdfWriter::CAnnotation*)pObj)->GetAnnotationType() != PdfWriter::AnnotWidget) + continue; + PdfWriter::EWidgetType nType = ((PdfWriter::CWidgetAnnotation*)pObj)->GetWidgetType(); + if (nType != PdfWriter::WidgetCheckbox && nType != PdfWriter::WidgetRadiobutton) + continue; + PdfWriter::CCheckBoxWidget* pKid = dynamic_cast(pObj); + if (!pKid) + continue; + + PV = pParent->arrOpt[i]; + std::wstring sOptI = PV.first.empty() ? PV.second : PV.first; + if (pKid->NeedAP_N_Yes()) + pKid->SetAP_N_Yes(mNameAP_N_Yes[sOptI]); + + if (sOptI == sOpt) + sV = pKid->Yes(); + else + pKid->Off(); + } + } + else + { + for (int i = 0; i < pKids->GetCount(); ++i) + { + PdfWriter::CObjectBase* pObj = pKids->Get(i); + if (pObj->GetType() != PdfWriter::object_type_DICT || + ((PdfWriter::CDictObject*)pObj)->GetDictType() != PdfWriter::dict_type_ANNOTATION || + ((PdfWriter::CAnnotation*)pObj)->GetAnnotationType() != PdfWriter::AnnotWidget) + continue; + PdfWriter::EWidgetType nType = ((PdfWriter::CWidgetAnnotation*)pObj)->GetWidgetType(); + if (nType != PdfWriter::WidgetCheckbox && nType != PdfWriter::WidgetRadiobutton) + continue; + PdfWriter::CCheckBoxWidget* pKid = dynamic_cast(pObj); + if (!pKid) + continue; + if (pKid->NeedAP_N_Yes()) + { + std::pair PV = pParent->arrOpt[i]; + std::wstring sOpt = PV.first.empty() ? PV.second : PV.first; + pKid->SetAP_N_Yes(mNameAP_N_Yes[sOpt]); + } + + if (pKid->GetAP_N_Yes() == sV) + sV = pKid->Yes(); + else + pKid->Off(); + } + } + + pParentObj->Add("V", sV.c_str()); + } + else + { + for (int i = 0; i < pKids->GetCount(); ++i) + { + PdfWriter::CObjectBase* pObj = pKids->Get(i); + if (pObj->GetType() != PdfWriter::object_type_DICT || + ((PdfWriter::CDictObject*)pObj)->GetDictType() != PdfWriter::dict_type_ANNOTATION || + ((PdfWriter::CAnnotation*)pObj)->GetAnnotationType() != PdfWriter::AnnotWidget) + continue; + PdfWriter::EWidgetType nType = ((PdfWriter::CWidgetAnnotation*)pObj)->GetWidgetType(); + if (nType == PdfWriter::WidgetCombobox || nType == PdfWriter::WidgetListbox) + { + PdfWriter::CChoiceWidget* pKid = dynamic_cast(pObj); + if (!pKid->HaveAPV()) + DrawChoiceWidget(pAppFonts, pKid, {pParent->sV}); + } + else if (nType == PdfWriter::WidgetText) + { + PdfWriter::CTextWidget* pKid = dynamic_cast(pObj); + if (!pKid->HaveAPV()) + DrawTextWidget(pAppFonts, pKid, pParent->sV); + } + } + pParentObj->Add("V", new PdfWriter::CStringObject(sV.c_str(), true)); + } + } if (nFlags & (1 << 7)) pParentObj->Add("Ff", pParent->nFieldFlag); if (nFlags & (1 << 8)) diff --git a/PdfFile/SrcWriter/Annotation.cpp b/PdfFile/SrcWriter/Annotation.cpp index fb390d5d43..274aa2160e 100644 --- a/PdfFile/SrcWriter/Annotation.cpp +++ b/PdfFile/SrcWriter/Annotation.cpp @@ -1854,6 +1854,20 @@ namespace PdfWriter { std::string sValue = U_TO_UTF8(wsAP_N_Yes); m_sAP_N_Yes = sValue; + + if (m_pAP) + { + CDictObject* pDict = (CDictObject*)m_pAP->Get("N"); + pDict->Add(m_sAP_N_Yes, m_pAP->GetYesN()); + pDict->Remove("Yes"); + pDict = (CDictObject*)m_pAP->Get("D"); + pDict->Add(m_sAP_N_Yes, m_pAP->GetYesD()); + pDict->Remove("Yes"); + } + } + bool CCheckBoxWidget::NeedAP_N_Yes() + { + return m_sAP_N_Yes.empty(); } void CCheckBoxWidget::SetAP() { @@ -1878,6 +1892,16 @@ namespace PdfWriter m_pAP->GetOffD()->DrawCheckBoxSquare(false, false); } } + std::string CCheckBoxWidget::Yes() + { + std::string sName = m_sAP_N_Yes.empty() ? "Yes" : m_sAP_N_Yes; + Add("AS", sName.c_str()); + return sName; + } + void CCheckBoxWidget::Off() + { + Add("AS", "Off"); + } void CCheckBoxWidget::SwitchAP(const std::string& sV, int nI) { CObjectBase* pAP, *pAPN; diff --git a/PdfFile/SrcWriter/Annotation.h b/PdfFile/SrcWriter/Annotation.h index 3ec35f7969..5b17d2c1eb 100644 --- a/PdfFile/SrcWriter/Annotation.h +++ b/PdfFile/SrcWriter/Annotation.h @@ -539,9 +539,14 @@ namespace PdfWriter void SetStyle(BYTE nStyle); ECheckBoxStyle GetStyle() { return m_nStyle; } void SetAP_N_Yes(const std::wstring& wsAP_N_Yes); + std::string GetAP_N_Yes() { return m_sAP_N_Yes; } + bool NeedAP_N_Yes(); virtual void SetFlag (const int& nFlag); void SetAP(); void SwitchAP(const std::string& sV, int nI = -1); + + std::string Yes(); + void Off(); }; class CTextWidget : public CWidgetAnnotation { diff --git a/PdfFile/SrcWriter/Document.cpp b/PdfFile/SrcWriter/Document.cpp index 4d6322d906..9cf53fee48 100644 --- a/PdfFile/SrcWriter/Document.cpp +++ b/PdfFile/SrcWriter/Document.cpp @@ -1558,11 +1558,11 @@ namespace PdfWriter return p->second; return NULL; } - void CDocument::SetParentKids(int nParentID) + std::string CDocument::SetParentKids(int nParentID) { CDictObject* pParent = GetParent(nParentID); if (!pParent) - return; + return ""; for (auto it = m_mAnnotations.begin(); it != m_mAnnotations.end(); it++) { @@ -1603,6 +1603,11 @@ namespace PdfWriter if (!bReplase) pKids->Add(pWidget); } + + CObjectBase* pFT = pParent->Get("FT"); + if (pFT && pFT->GetType() == object_type_NAME) + return ((CNameObject*)pFT)->Get(); + return ""; } CPage* CDocument::CreateFakePage() { diff --git a/PdfFile/SrcWriter/Document.h b/PdfFile/SrcWriter/Document.h index 2d825b31d8..fc511360d1 100644 --- a/PdfFile/SrcWriter/Document.h +++ b/PdfFile/SrcWriter/Document.h @@ -209,7 +209,7 @@ namespace PdfWriter void SetCurPage(CPage* pPage) { m_pCurPage = pPage; } CPage* CreateFakePage(); bool EditCO(const std::vector& arrCO); - void SetParentKids(int nParentID); + std::string SetParentKids(int nParentID); const std::map& GetAnnots() { return m_mAnnotations; } const std::map& GetParents() { return m_mParents; } void AddShapeXML(const std::string& sXML);