diff --git a/DesktopEditor/graphics/pro/js/drawingfile.json b/DesktopEditor/graphics/pro/js/drawingfile.json index b424e1e37e..7681a1fa99 100644 --- a/DesktopEditor/graphics/pro/js/drawingfile.json +++ b/DesktopEditor/graphics/pro/js/drawingfile.json @@ -32,6 +32,7 @@ "_GetStructure", "_GetInteractiveFormsInfo", "_GetInteractiveFormsAP", + "_GetButtonIcons", "_InitializeFontsBin", "_InitializeFontsBase64", "_InitializeFontsRanges", diff --git a/DesktopEditor/graphics/pro/js/wasm/js/drawingfile_base.js b/DesktopEditor/graphics/pro/js/wasm/js/drawingfile_base.js index f6e786e075..1c0f3e1ea5 100644 --- a/DesktopEditor/graphics/pro/js/wasm/js/drawingfile_base.js +++ b/DesktopEditor/graphics/pro/js/wasm/js/drawingfile_base.js @@ -469,6 +469,7 @@ if (rec["type"] == "checkbox" || rec["type"] == "radiobutton" || rec["type"] == "button") { rec["value"] = flags & (1 << 9) ? "Yes" : "Off"; + let IFflags = reader.readInt(); // Характеристики внешнего вида - MK if (rec["type"] == "button") { @@ -487,6 +488,22 @@ // Расположение заголовка - TP if (flags & (1 << 13)) rec["positionCaption"] = reader.readInt(); + // Справочный словарь иконок - IF + if (IFflags & (1 << 0)) + { + rec["IF"] = {}; + if (IFflags & (1 << 1)) + rec["IF"]["SW"] = reader.readString(); + if (IFflags & (1 << 2)) + rec["IF"]["S"] = reader.readString(); + if (IFflags & (1 << 3)) + { + rec["IF"]["A"] = []; + rec["IF"]["A"].push(reader.readDouble()); + rec["IF"]["A"].push(reader.readDouble()); + } + rec["IF"]["FB"] = IFflags & (1 << 4); + } if (flags & (1 << 14)) { rec["NameOfYes"] = reader.readString(); @@ -597,10 +614,27 @@ Module["_free"](ext); return res; }; - CFile.prototype["getInteractiveFormsAP"] = function(pageIndex, width, height, backgroundColor) + // необязательный nWidget - номер сопоставления аннотации - rec["AP"]["i"] + // необязательный sView - определенный внешний вид аннотации - N/D/R + // необязательный sButtonView - состояние pushbutton-аннотации - Off/Yes(или rec["NameOfYes"]) + CFile.prototype["getInteractiveFormsAP"] = function(pageIndex, width, height, backgroundColor, nWidget, sView, sButtonView) { + var nView = -1; + if (sView) + { + if (sView == "N") + nView = 0; + else if (sView == "D") + nView = 1; + else if (sView == "R") + nView = 2; + } + var nButtonView = -1; + if (sButtonView) + nButtonView = (sButtonView == "Off" ? 0 : 1); + var res = []; - var ext = Module["_GetInteractiveFormsAP"](this.nativeFile, pageIndex, width, height, backgroundColor === undefined ? 0xFFFFFF : backgroundColor); + var ext = Module["_GetInteractiveFormsAP"](this.nativeFile, width, height, backgroundColor === undefined ? 0xFFFFFF : backgroundColor, pageIndex, nWidget === undefined ? -1 : nWidget, nView, nButtonView); if (ext == 0) return res; @@ -654,47 +688,63 @@ APi["fontInfo"].push(fontInfo); } } - n = reader.readInt(); + res.push(AP); + } + + Module["_free"](ext); + return res; + }; + // необязательный nWidget ... + // необязательный sIconView - определенная иконка - I/RI/IX + CFile.prototype["getButtonIcons"] = function(pageIndex, width, height, backgroundColor, nWidget, sIconView) + { + var nView = -1; + if (sIconView) + { + if (sIconView == "I") + nView = 0; + else if (sIconView == "RI") + nView = 1; + else if (sIconView == "IX") + nView = 2; + } + + var res = []; + var ext = Module["_GetButtonIcons"](this.nativeFile, width, height, backgroundColor === undefined ? 0xFFFFFF : backgroundColor, pageIndex, nWidget === undefined ? -1 : nWidget, nView); + if (ext == 0) + return res; + + var lenArray = new Int32Array(Module["HEAP8"].buffer, ext, 4); + if (lenArray == null) + return res; + + var len = lenArray[0]; + len -= 4; + if (len <= 0) + return res; + + var buffer = new Uint8Array(Module["HEAP8"].buffer, ext + 4, len); + var reader = new CBinaryReader(buffer, 0, len); + + while (reader.isValid()) + { + // Иконка pushbutton аннотации + var MK = {}; + // Номер для сопоставление с AP + MK["i"] = reader.readInt(); + let n = reader.readInt(); for (let i = 0; i < n; ++i) { var MKType = reader.readString(); - AP[MKType] = {}; - AP[MKType]["x"] = reader.readInt(); - AP[MKType]["y"] = reader.readInt(); - AP[MKType]["w"] = reader.readInt(); - AP[MKType]["h"] = reader.readInt(); + MK[MKType] = {}; + MK[MKType]["w"] = reader.readInt(); + MK[MKType]["h"] = reader.readInt(); let np1 = reader.readInt(); let np2 = reader.readInt(); // Указатель на память, аналогичный возвращаемому getPagePixmap. Память необходимо освободить - AP[MKType]["retValue"] = np2 << 32 | np1; - let k = reader.readInt(); - AP[MKType]["fontInfo"] = []; - for (let i = 0; i < k; ++i) - { - let fontInfo = {}; - fontInfo["text"] = reader.readString(); - fontInfo["fontName"] = reader.readString(); - fontInfo["fontSize"] = reader.readDouble(); - AP[MKType]["fontInfo"].push(fontInfo); - } + MK[MKType]["retValue"] = np2 << 32 | np1; } - let flags = reader.readInt(); - if (flags & (1 << 0)) - { - AP["IF"] = {}; - if (flags & (1 << 1)) - AP["IF"]["SW"] = reader.readString(); - if (flags & (1 << 2)) - AP["IF"]["S"] = reader.readString(); - if (flags & (1 << 3)) - { - AP["IF"]["A"] = []; - AP["IF"]["A"].push(reader.readDouble()); - AP["IF"]["A"].push(reader.readDouble()); - } - AP["IF"]["FB"] = flags & (1 << 4); - } - res.push(AP); + res.push(MK); } Module["_free"](ext); diff --git a/DesktopEditor/graphics/pro/js/wasm/src/drawingfile.cpp b/DesktopEditor/graphics/pro/js/wasm/src/drawingfile.cpp index e1190615f8..16363770a3 100644 --- a/DesktopEditor/graphics/pro/js/wasm/src/drawingfile.cpp +++ b/DesktopEditor/graphics/pro/js/wasm/src/drawingfile.cpp @@ -134,7 +134,7 @@ WASM_EXPORT BYTE* GetInfo (CGraphicsFileDrawing* pGraphics) oRes.ClearWithoutAttack(); return bRes; } -WASM_EXPORT BYTE* GetPixmap(CGraphicsFileDrawing* pGraphics, int nPageIndex, int nRasterW, int nRasterH, int nBackgroundColor) +WASM_EXPORT BYTE* GetPixmap (CGraphicsFileDrawing* pGraphics, int nPageIndex, int nRasterW, int nRasterH, int nBackgroundColor) { return pGraphics->GetPage(nPageIndex, nRasterW, nRasterH, nBackgroundColor); } @@ -150,32 +150,38 @@ WASM_EXPORT BYTE* GetStructure(CGraphicsFileDrawing* pGraphics) { return pGraphics->GetStructure(); } -WASM_EXPORT BYTE* GetInteractiveFormsInfo(CGraphicsFileDrawing* pGraphics) +WASM_EXPORT BYTE* GetInteractiveFormsInfo (CGraphicsFileDrawing* pGraphics) { return pGraphics->GetInteractiveFormsInfo(); } -WASM_EXPORT BYTE* GetInteractiveFormsAP(CGraphicsFileDrawing* pGraphics, int nRasterW, int nRasterH, int nBackgroundColor, int nPageIndex) -{ - return pGraphics->GetAPWidget(nRasterW, nRasterH, nBackgroundColor, nPageIndex); -} -WASM_EXPORT BYTE* GetInteractiveFormAP(CGraphicsFileDrawing* pGraphics, int nRasterW, int nRasterH, int nBackgroundColor, int nPageIndex, int nWidget) -{ - return pGraphics->GetAPWidget(nRasterW, nRasterH, nBackgroundColor, nPageIndex, nWidget); -} -WASM_EXPORT BYTE* GetInteractiveFormAPView(CGraphicsFileDrawing* pGraphics, int nRasterW, int nRasterH, int nBackgroundColor, int nPageIndex, int nWidget, const char* sView, const char* sButtonView) +WASM_EXPORT BYTE* GetInteractiveFormsAP(CGraphicsFileDrawing* pGraphics, int nRasterW, int nRasterH, int nBackgroundColor, int nPageIndex, int nWidget, int nView, int nButtonView) { + const char* sView = NULL; + if (nView == 0) + sView = "N"; + else if (nView == 1) + sView = "D"; + else if (nView == 2) + sView = "R"; + + const char* sButtonView = NULL; + if (nButtonView == 0) + sButtonView = "Off"; + else if (nButtonView == 1) + sButtonView = "Yes"; + return pGraphics->GetAPWidget(nRasterW, nRasterH, nBackgroundColor, nPageIndex, nWidget, sView, sButtonView); } -WASM_EXPORT BYTE* GetButtonInteractiveFormsIcons(CGraphicsFileDrawing* pGraphics, int nRasterW, int nRasterH, int nBackgroundColor, int nPageIndex) -{ - return pGraphics->GetButtonIcon(nRasterW, nRasterH, nBackgroundColor, nPageIndex); -} -WASM_EXPORT BYTE* GetButtonInteractiveFormIcons(CGraphicsFileDrawing* pGraphics, int nRasterW, int nRasterH, int nBackgroundColor, int nPageIndex, int nButtonWidget) -{ - return pGraphics->GetButtonIcon(nRasterW, nRasterH, nBackgroundColor, nPageIndex, nButtonWidget); -} -WASM_EXPORT BYTE* GetButtonInteractiveFormIcon(CGraphicsFileDrawing* pGraphics, int nRasterW, int nRasterH, int nBackgroundColor, int nPageIndex, int nButtonWidget, const char* sIconView) +WASM_EXPORT BYTE* GetButtonIcons(CGraphicsFileDrawing* pGraphics, int nRasterW, int nRasterH, int nBackgroundColor, int nPageIndex, int nButtonWidget, int nIconView) { + const char* sIconView = NULL; + if (nIconView == 0) + sIconView = "I"; + else if (nIconView == 1) + sIconView = "RI"; + else if (nIconView == 2) + sIconView = "IX"; + return pGraphics->GetButtonIcon(nRasterW, nRasterH, nBackgroundColor, nPageIndex, nButtonWidget, sIconView); } WASM_EXPORT void DestroyTextInfo(CGraphicsFileDrawing* pGraphics) @@ -754,7 +760,7 @@ int main(int argc, char* argv[]) if (pWidgets) free(pWidgets); - BYTE* pWidgetsAP = GetInteractiveFormsAP(pGrFile, nWidth, nHeight, 0xFFFFFF, nTestPage); + BYTE* pWidgetsAP = GetInteractiveFormsAP(pGrFile, nWidth, nHeight, 0xFFFFFF, nTestPage, -1, -1, -1); nLength = READ_INT(pWidgetsAP); i = 4; nLength -= 4; @@ -829,7 +835,7 @@ int main(int argc, char* argv[]) if (pWidgetsAP) free(pWidgetsAP); - BYTE* pWidgetsMK = GetButtonInteractiveFormsIcons(pGrFile, nWidth, nHeight, 0xFFFFFF, nTestPage); + BYTE* pWidgetsMK = GetButtonIcons(pGrFile, nWidth, nHeight, 0xFFFFFF, nTestPage, -1, -1); nLength = READ_INT(pWidgetsMK); i = 4; nLength -= 4; diff --git a/PdfFile/PdfReader.cpp b/PdfFile/PdfReader.cpp index 7a02eb63f5..1a657ca162 100644 --- a/PdfFile/PdfReader.cpp +++ b/PdfFile/PdfReader.cpp @@ -1904,8 +1904,13 @@ BYTE* CPdfReader::GetAPWidget(int nRasterW, int nRasterH, int nBackgroundColor, { for (int k = 0; k < oObj.dictGetLength(); ++k) { - if (sButtonView && strcmp(sButtonView, oObj.dictGetKey(k)) != 0) - continue; + if (sButtonView) + { + if (strcmp(sButtonView, "Off") == 0 && strcmp(oObj.dictGetKey(k), "Off") != 0) + continue; + if (strcmp(sButtonView, "Yes") == 0 && strcmp(oObj.dictGetKey(k), "Off") == 0) + continue; + } std::string sASName(oObj.dictGetKey(k)); oRes.WriteString((BYTE*)sAPName.c_str(), sAPName.length()); if ((oType == acroFormFieldRadioButton || oType == acroFormFieldCheckbox) && sASName != "Off") @@ -1968,7 +1973,8 @@ BYTE* CPdfReader::GetButtonIcon(int nRasterW, int nRasterH, int nBackgroundColor for (int i = 0, nNum = pAcroForms->getNumFields(); i < nNum; ++i) { AcroFormField* pField = pAcroForms->getField(i); - if (pField->getPageNum() != nPageIndex + 1 || (nButtonWidget >= 0 && i != nButtonWidget)) + AcroFormFieldType oType = pField->getAcroFormFieldType(); + if (pField->getPageNum() != nPageIndex + 1 || oType != acroFormFieldPushbutton || (nButtonWidget >= 0 && i != nButtonWidget)) continue; // Номер аннотации для сопоставления с AP