From 8cc343b8858a7f8abb77e5377468daa348925126 Mon Sep 17 00:00:00 2001 From: Kulikova Svetlana Date: Mon, 27 Mar 2023 18:51:24 +0300 Subject: [PATCH] DV, TI, rect update --- .../pro/js/wasm/js/drawingfile_base.js | 14 ++-- .../graphics/pro/js/wasm/src/drawingfile.cpp | 25 +++++-- .../graphics/pro/js/wasm/src/serialize.h | 4 ++ PdfFile/PdfReader.cpp | 66 +++++++++---------- PdfFile/SrcReader/Adaptors.cpp | 34 ++++++++++ PdfFile/SrcReader/Adaptors.h | 14 ++++ PdfFile/SrcReader/RendererOutputDev.cpp | 7 ++ PdfFile/lib/xpdf/AcroForm.cc | 4 +- 8 files changed, 125 insertions(+), 43 deletions(-) diff --git a/DesktopEditor/graphics/pro/js/wasm/js/drawingfile_base.js b/DesktopEditor/graphics/pro/js/wasm/js/drawingfile_base.js index 9a50fc1829..e8ca026a75 100644 --- a/DesktopEditor/graphics/pro/js/wasm/js/drawingfile_base.js +++ b/DesktopEditor/graphics/pro/js/wasm/js/drawingfile_base.js @@ -408,10 +408,10 @@ rec["page"] = reader.readInt(); // Необходимо смещение полученных координат как у getStructure и viewer.navigate rec["rect"] = {}; - rec["rect"]["x1"] = reader.readDouble(); - rec["rect"]["y1"] = reader.readDouble(); - rec["rect"]["x2"] = reader.readDouble(); - rec["rect"]["y2"] = reader.readDouble(); + rec["rect"]["x1"] = parseFloat(reader.readString()); + rec["rect"]["y1"] = parseFloat(reader.readString()); + rec["rect"]["x2"] = parseFloat(reader.readString()); + rec["rect"]["y2"] = parseFloat(reader.readString()); rec["alignment"] = reader.readInt(); rec["type"] = reader.readString(); rec["flag"] = reader.readInt(); @@ -462,6 +462,9 @@ for (let i = 0; i < n; ++i) rec["BG"].push(reader.readDouble()); } + // Значение по-умолчанию - DV + if (flags & (1 << 8)) + rec["defaultValue"] = reader.readString(); if (rec["type"] == "checkbox" || rec["type"] == "radiobutton" || rec["type"] == "button") { @@ -527,6 +530,9 @@ rec["opt"].push([opt1, opt2]); } } + // Индекс верхнего элемента - TI + if (flags & (1 << 11)) + rec["TI"] = reader.readInt(); // 12.7.4.4 rec["editable"] = rec["flag"] & (1 << 18); // Edit rec["multipleSelection"] = rec["flag"] & (1 << 21); // MultiSelect diff --git a/DesktopEditor/graphics/pro/js/wasm/src/drawingfile.cpp b/DesktopEditor/graphics/pro/js/wasm/src/drawingfile.cpp index b853c42dfe..c7ca021075 100644 --- a/DesktopEditor/graphics/pro/js/wasm/src/drawingfile.cpp +++ b/DesktopEditor/graphics/pro/js/wasm/src/drawingfile.cpp @@ -400,16 +400,20 @@ int main(int argc, char* argv[]) std::cout << "Page " << nPathLength << ", "; nPathLength = READ_INT(pWidgets + i); i += 4; - std::cout << "X1 " << (double)nPathLength / 100.0 << ", "; + std::cout << "X1 " << std::string((char*)(pWidgets + i), nPathLength) << ", "; + i += nPathLength; nPathLength = READ_INT(pWidgets + i); i += 4; - std::cout << "Y1 " << (double)nPathLength / 100.0 << ", "; + std::cout << "Y1 " << std::string((char*)(pWidgets + i), nPathLength) << ", "; + i += nPathLength; nPathLength = READ_INT(pWidgets + i); i += 4; - std::cout << "X2 " << (double)nPathLength / 100.0 << ", "; + std::cout << "X2 " << std::string((char*)(pWidgets + i), nPathLength) << ", "; + i += nPathLength; nPathLength = READ_INT(pWidgets + i); i += 4; - std::cout << "Y2 " << (double)nPathLength / 100.0 << ", "; + std::cout << "Y2 " << std::string((char*)(pWidgets + i), nPathLength) << ", "; + i += nPathLength; nPathLength = READ_INT(pWidgets + i); i += 4; std::cout << "Q " << nPathLength << ", "; @@ -502,6 +506,13 @@ int main(int argc, char* argv[]) } std::cout << ", "; } + if (nFlags & (1 << 8)) + { + nPathLength = READ_INT(pWidgets + i); + i += 4; + std::cout << "DV " << std::string((char*)(pWidgets + i), nPathLength) << ", "; + i += nPathLength; + } if (sType == "checkbox" || sType == "radiobutton" || sType == "button") { std::cout << (nFlags & (1 << 9) ? "Yes" : "Off") << ", "; @@ -591,6 +602,12 @@ int main(int argc, char* argv[]) i += nPathLength; } } + if (nFlags & (1 << 11)) + { + nPathLength = READ_INT(pWidgets + i); + i += 4; + std::cout << "TI " << nPathLength << ", "; + } } if (nFlags & (1 << 19)) { diff --git a/DesktopEditor/graphics/pro/js/wasm/src/serialize.h b/DesktopEditor/graphics/pro/js/wasm/src/serialize.h index 3048fabc2e..bff8b8a155 100644 --- a/DesktopEditor/graphics/pro/js/wasm/src/serialize.h +++ b/DesktopEditor/graphics/pro/js/wasm/src/serialize.h @@ -188,6 +188,10 @@ namespace NSWasm unsigned int len = (unsigned int)m_lSizeCur; memcpy(m_pData, &len, sizeof(unsigned int)); } + static unsigned int GetLen(BYTE* x) + { + return x ? (x[0] | x[1] << 8 | x[2] << 16 | x[3] << 24) : 4; + } }; class CHChar diff --git a/PdfFile/PdfReader.cpp b/PdfFile/PdfReader.cpp index 21950d1cd1..6692b30560 100644 --- a/PdfFile/PdfReader.cpp +++ b/PdfFile/PdfReader.cpp @@ -773,10 +773,14 @@ BYTE* CPdfReader::GetWidgets() double dTemp = dy1; dy1 = dHeight - dy2; dy2 = dHeight - dTemp; - oRes.AddDouble(dx1); - oRes.AddDouble(dy1); - oRes.AddDouble(dx2); - oRes.AddDouble(dy2); + std::string sX1 = std::to_string(dx1); + std::string sY1 = std::to_string(dy1); + std::string sX2 = std::to_string(dx2); + std::string sY2 = std::to_string(dy2); + oRes.WriteString((BYTE*)sX1.c_str(), (unsigned int)sX1.length()); + oRes.WriteString((BYTE*)sY1.c_str(), (unsigned int)sY1.length()); + oRes.WriteString((BYTE*)sX2.c_str(), (unsigned int)sX2.length()); + oRes.WriteString((BYTE*)sY2.c_str(), (unsigned int)sY2.length()); // Выравнивание текста - Q Object oQ; @@ -938,38 +942,9 @@ oObj.free();\ } } - // Значение аннотации из текущего внешнего вида - /* - Object oAP, oAppearance; - if (oField.dictLookup("AP", &oAP)->isDict()) - { - Object oN; - oAP.dictLookup("N", &oN); - if (oN.isDict()) - { - Object oAS; - if (oField.dictLookup("AS", &oAS)->isName()) - oN.dictLookup(oAS.getName(), &oAppearance); - else if (oN.dictGetLength() == 1) - oN.dictGetVal(0, &oAppearance); - else - oN.dictLookup("Off", &oAppearance); - oAS.free(); - } - else - oN.copy(&oAppearance); - oN.free(); - } - oAP.free(); - - if (oAppearance.isStream()) - { - } - oAppearance.free(); - */ Object oMK; - if (oField.dictLookup("MK", &oMK) && oMK.isDict()) + if (oField.dictLookup("MK", &oMK)->isDict()) { // 6 - Цвет границ - BC. Даже если граница не задана BS/Border, то при наличии BC предоставляется граница по-умолчанию (сплошная, толщиной 1) if (oMK.dictLookup("BC", &oObj)->isArray()) @@ -1011,6 +986,17 @@ oObj.free();\ } oMK.free(); + // 9 - Значение по-умолчанию + if (pField->fieldLookup("DV", &oObj)->isString()) + { + TextString* s = new TextString(oObj.getString()); + std::string sStr = NSStringExt::CConverter::GetUtf8FromUTF32(s->getUnicode(), s->getLength()); + nFlags |= (1 << 8); + oRes.WriteString((BYTE*)sStr.c_str(), (unsigned int)sStr.length()); + delete s; + } + oObj.free(); + // Значение поля - V int nValueLength; Unicode* pValue = pField->getValue(&nValueLength); @@ -1205,6 +1191,14 @@ oObj.free();\ } oOpt.free(); + // 12 - Индекс верхнего элемента - TI + if (pField->fieldLookup("TI", &oObj)->isInt()) + { + nFlags |= (1 << 11); + oRes.AddInt(oObj.getInt()); + } + oObj.free(); + break; } case acroFormFieldSignature: @@ -1515,6 +1509,10 @@ BYTE* CPdfReader::GetAPWidgets(int nPageIndex, int nRasterW, int nRasterH, int n unsigned int npSubMatrix1 = npSubMatrix & 0xFFFFFFFF; oRes.AddInt(npSubMatrix1); oRes.AddInt(npSubMatrix >> 32); + + BYTE* pTextFormField = ((GlobalParamsAdaptor*)globalParams)->GetTextFormField(); + ((GlobalParamsAdaptor*)globalParams)->ClearTextFormField(); + unsigned int nLength = NSWasm::CData::GetLen(pTextFormField); } globalParams->setDrawContent(bDrawContent); diff --git a/PdfFile/SrcReader/Adaptors.cpp b/PdfFile/SrcReader/Adaptors.cpp index facfc52913..a09cb1648c 100644 --- a/PdfFile/SrcReader/Adaptors.cpp +++ b/PdfFile/SrcReader/Adaptors.cpp @@ -32,6 +32,7 @@ #include "Adaptors.h" #include "../lib/xpdf/NameToCharCode.h" #include "../lib/xpdf/TextString.h" +#include "../../DesktopEditor/graphics/pro/js/wasm/src/serialize.h" void GlobalParamsAdaptor::SetFontManager(NSFonts::IFontManager *pFontManager) @@ -186,6 +187,39 @@ bool GlobalParamsAdaptor::GetCMap(const char* sName, char*& pData, unsigned int& return false; } +void GlobalParamsAdaptor::AddTextFormField(const std::wstring& sText, const std::wstring& sFontName, double dFontSize) +{ + if (!m_arrTextFormField.empty()) + { + TextFormField& tFF = m_arrTextFormField.back(); + if (tFF.sFontName == sFontName && tFF.dFontSize == dFontSize) + { + tFF.sText += sText; + return; + } + } + m_arrTextFormField.push_back({sText, sFontName, dFontSize}); +} +BYTE* GlobalParamsAdaptor::GetTextFormField() +{ + NSWasm::CData oRes; + oRes.SkipLen(); + + for (TextFormField& tFF : m_arrTextFormField) + { + std::string sText = U_TO_UTF8(tFF.sText); + std::string sFontName = U_TO_UTF8(tFF.sFontName); + oRes.WriteString((BYTE*)sText.c_str(), (unsigned int)sText.length()); + oRes.WriteString((BYTE*)sFontName.c_str(), (unsigned int)sFontName.length()); + oRes.AddDouble(tFF.dFontSize); + } + + oRes.WriteLen(); + BYTE* bRes = oRes.GetBuffer(); + oRes.ClearWithoutAttack(); + return bRes; +} + bool operator==(const Ref &a, const Ref &b) { return a.gen == b.gen && a.num == b.gen; diff --git a/PdfFile/SrcReader/Adaptors.h b/PdfFile/SrcReader/Adaptors.h index 4f26f80263..fbb4861a26 100644 --- a/PdfFile/SrcReader/Adaptors.h +++ b/PdfFile/SrcReader/Adaptors.h @@ -44,6 +44,7 @@ #include "../../DesktopEditor/common/File.h" #include "../../DesktopEditor/common/Directory.h" #include +#include #include "../lib/goo/GList.h" #include "../lib/goo/GHash.h" @@ -57,6 +58,15 @@ class GlobalParamsAdaptor : public GlobalParams BYTE* m_bCMapData; DWORD m_nCMapDataLength; + + struct TextFormField + { + std::wstring sText; + std::wstring sFontName; + double dFontSize; + }; + std::vector m_arrTextFormField; + public: NSFonts::IFontManager *m_pFontManager; GlobalParamsAdaptor(const char *filename) : GlobalParams(filename) @@ -84,6 +94,10 @@ public: void SetCMapFile(const std::wstring &wsFile); void SetCMapMemory(BYTE* pData, DWORD nSizeData); bool GetCMap(const char* sName, char*& pData, unsigned int& nSize); + + void AddTextFormField(const std::wstring& sText, const std::wstring& sFontName, double dFontSize); + BYTE* GetTextFormField(); + void ClearTextFormField() { m_arrTextFormField.clear(); }; private: void AddNameToUnicode(const char* sFile); diff --git a/PdfFile/SrcReader/RendererOutputDev.cpp b/PdfFile/SrcReader/RendererOutputDev.cpp index 9b4f2302d0..cbde2b70ec 100644 --- a/PdfFile/SrcReader/RendererOutputDev.cpp +++ b/PdfFile/SrcReader/RendererOutputDev.cpp @@ -3922,10 +3922,17 @@ namespace PdfReader return; } m_pRenderer->put_FontPath(wsFileName); + sFontPath = wsFileName; } } } } + if (globalParams->getDrawFormField() >= 0) + { + double dFontSize; + m_pRenderer->get_FontSize(&dFontSize); + ((GlobalParamsAdaptor*)globalParams)->AddTextFormField(wsUnicodeText, sFontPath, dFontSize); + } #endif m_pRenderer->CommandDrawTextEx(wsUnicodeText, &unGid, unGidsCount, PDFCoordsToMM(0 + dShiftX), PDFCoordsToMM(dShiftY), PDFCoordsToMM(dDx), PDFCoordsToMM(dDy)); diff --git a/PdfFile/lib/xpdf/AcroForm.cc b/PdfFile/lib/xpdf/AcroForm.cc index c411725259..77ef4185a8 100644 --- a/PdfFile/lib/xpdf/AcroForm.cc +++ b/PdfFile/lib/xpdf/AcroForm.cc @@ -562,10 +562,12 @@ void AcroForm::scanField(Object *fieldRef) { void AcroForm::draw(int pageNum, Gfx *gfx, GBool printing) { int i; - int formField = globalParams->getDrawFormField(); for (i = 0; i < fields->getLength(); ++i) { +#ifdef BUILDING_WASM_MODULE + int formField = globalParams->getDrawFormField(); if (formField >= 0 && formField != i) continue; +#endif ((AcroFormField *)fields->get(i))->draw(pageNum, gfx, printing); } }