From a417e9a38cbee59cb3794bb024fbdc8e6eb32184 Mon Sep 17 00:00:00 2001 From: Svetlana Kulikova Date: Wed, 6 Sep 2023 15:23:48 +0300 Subject: [PATCH] Reader Polygon, PolyLine annots --- .../pro/js/wasm/js/drawingfile_base.js | 28 ++++ .../graphics/pro/js/wasm/src/drawingfile.cpp | 49 +++++++ PdfFile/PdfReader.cpp | 8 +- PdfFile/SrcReader/PdfAnnot.cpp | 126 ++++++++++++++++++ PdfFile/SrcReader/PdfAnnot.h | 20 +++ 5 files changed, 225 insertions(+), 6 deletions(-) diff --git a/DesktopEditor/graphics/pro/js/wasm/js/drawingfile_base.js b/DesktopEditor/graphics/pro/js/wasm/js/drawingfile_base.js index 682d3e03da..b245d28185 100644 --- a/DesktopEditor/graphics/pro/js/wasm/js/drawingfile_base.js +++ b/DesktopEditor/graphics/pro/js/wasm/js/drawingfile_base.js @@ -1131,6 +1131,34 @@ rec["IC"].push(reader.readDouble()); } } + // Polygon, PolyLine + else if (rec["Type"] == 6 || rec["Type"] == 7) + { + let nVertices = reader.readInt(); + rec["Vertices"] = []; + for (let i = 0; i < nVertices; ++i) + rec["Vertices"].push(reader.readDouble()); + // Стили окончания линии - LE + // 0 - Square, 1 - Circle, 2 - Diamond, 3 - OpenArrow, 4 - ClosedArrow, 5 - None, 6 - Butt, 7 - ROpenArrow, 8 - RClosedArrow, 9 - Slash + if (flags & (1 << 15)) + { + rec["LE"] = []; + rec["LE"].push(reader.readByte()); + rec["LE"].push(reader.readByte()); + } + // Цвет окончаний линии - IC + if (flags & (1 << 16)) + { + let n = reader.readInt(); + rec["IC"] = []; + for (let i = 0; i < n; ++i) + rec["IC"].push(reader.readDouble()); + } + // Назначение аннотации - IT + // 0 - PolygonCloud, 1 - PolyLineDimension, 2 - PolygonDimension + if (flags & (1 << 20)) + rec["IT"] = reader.readByte(); + } // Popup else if (rec["Type"] == 15) { diff --git a/DesktopEditor/graphics/pro/js/wasm/src/drawingfile.cpp b/DesktopEditor/graphics/pro/js/wasm/src/drawingfile.cpp index b5ec727a33..b66ea239e8 100644 --- a/DesktopEditor/graphics/pro/js/wasm/src/drawingfile.cpp +++ b/DesktopEditor/graphics/pro/js/wasm/src/drawingfile.cpp @@ -1843,6 +1843,55 @@ int main(int argc, char* argv[]) std::cout << ", "; } } + else if (sType == "Polygon" || + sType == "PolyLine") + { + int nVerticesLength = READ_INT(pAnnots + i); + i += 4; + std::cout << "Vertices"; + + for (int j = 0; j < nVerticesLength; ++j) + { + nPathLength = READ_INT(pAnnots + i); + i += 4; + std::cout << " " << (double)nPathLength / 100.0; + } + std::cout << ", "; + + if (nFlags & (1 << 15)) + { + std::cout << "LE"; + for (int j = 0; j < 2; ++j) + { + nPathLength = READ_BYTE(pAnnots + i); + i += 1; + std::string arrLE[] = {"Square", "Circle", "Diamond", "OpenArrow", "ClosedArrow", "None", "Butt", "ROpenArrow", "RClosedArrow", "Slash"}; + std::cout << " " << arrLE[nPathLength]; + } + std::cout << ", "; + } + if (nFlags & (1 << 16)) + { + int nICLength = READ_INT(pAnnots + i); + i += 4; + std::cout << "IC"; + + for (int j = 0; j < nICLength; ++j) + { + nPathLength = READ_INT(pAnnots + i); + i += 4; + std::cout << " " << (double)nPathLength / 100.0; + } + std::cout << ", "; + } + if (nFlags & (1 << 20)) + { + nPathLength = READ_BYTE(pAnnots + i); + i += 1; + std::string arrIT[] = {"PolygonCloud", "PolyLineDimension", "PolygonDimension"}; + std::cout << "IT " << arrIT[nPathLength] << ", "; + } + } else if (sType == "Popup") { nFlags = READ_INT(pAnnots + i); diff --git a/PdfFile/PdfReader.cpp b/PdfFile/PdfReader.cpp index 67a24c4d50..5394a20e31 100644 --- a/PdfFile/PdfReader.cpp +++ b/PdfFile/PdfReader.cpp @@ -2139,13 +2139,9 @@ void GetPageAnnots(PDFDoc* pdfDoc, NSWasm::CData& oRes, int nPageIndex) { pAnnot = new PdfReader::CAnnotSquareCircle(pdfDoc, &oAnnotRef, nPageIndex); } - else if (sType == "Polygon") + else if (sType == "Polygon" || sType == "PolyLine") { - - } - else if (sType == "PolyLine") - { - + pAnnot = new PdfReader::CAnnotPolygonLine(pdfDoc, &oAnnotRef, nPageIndex); } else if (sType == "Highlight" || sType == "Underline" || diff --git a/PdfFile/SrcReader/PdfAnnot.cpp b/PdfFile/SrcReader/PdfAnnot.cpp index ec4cedb372..829d286b37 100644 --- a/PdfFile/SrcReader/PdfAnnot.cpp +++ b/PdfFile/SrcReader/PdfAnnot.cpp @@ -911,6 +911,8 @@ CAnnotInk::CAnnotInk(PDFDoc* pdfDoc, Object* oAnnotRef, int nPageIndex) : CMarku Object oObj1; if (oObj2.arrayGet(k, &oObj1)->isNum()) arrLine.push_back(k % 2 == 0 ? oObj1.getNum() : m_dHeight - oObj1.getNum()); + else + arrLine.push_back(0.0); oObj1.free(); } if (!arrLine.empty()) @@ -1142,6 +1144,105 @@ CAnnotSquareCircle::CAnnotSquareCircle(PDFDoc* pdfDoc, Object* oAnnotRef, int nP oAnnot.free(); } +//------------------------------------------------------------------------ +// Polygon, PolyLine +//------------------------------------------------------------------------ + +CAnnotPolygonLine::CAnnotPolygonLine(PDFDoc* pdfDoc, Object* oAnnotRef, int nPageIndex) : CMarkupAnnot(pdfDoc, oAnnotRef, nPageIndex) +{ + Object oAnnot, oObj, oObj2; + XRef* pXref = pdfDoc->getXRef(); + oAnnotRef->fetch(pXref, &oAnnot); + + // Подтип - Subtype + std::string sType; + if (oAnnot.dictLookup("Subtype", &oObj)->isName()) + sType = oObj.getName(); + oObj.free(); + + if (sType == "Polygon") + m_nSubtype = 6; + else if (sType == "PolyLine") + m_nSubtype = 7; + + // Координаты вершин - Vertices + if (oAnnot.dictLookup("Vertices", &oObj)->isArray()) + { + for (int j = 0; j < oObj.arrayGetLength(); ++j) + { + if (oObj.arrayGet(j, &oObj2)->isNum()) + m_arrVertices.push_back(j % 2 == 0 ? oObj2.getNum() : m_dHeight - oObj2.getNum()); + else + m_arrVertices.push_back(0.0); + oObj2.free(); + } + } + oObj.free(); + + // 16 - Стили окончания линии - LE + if (oAnnot.dictLookup("LE", &oObj)->isArray()) + { + m_unFlags |= (1 << 15); + m_nLE[0] = 5; m_nLE[1] = 5; // None + for (int i = 0; i < oObj.arrayGetLength() && i < 2; ++i) + { + if (!oObj.arrayGet(i, &oObj2)->isName()) + { + oObj2.free(); + continue; + } + + if (oObj2.isName("Square")) + m_nLE[i] = 0; + else if (oObj2.isName("Circle")) + m_nLE[i] = 1; + else if (oObj2.isName("Diamond")) + m_nLE[i] = 2; + else if (oObj2.isName("OpenArrow")) + m_nLE[i] = 3; + else if (oObj2.isName("ClosedArrow")) + m_nLE[i] = 4; + else if (oObj2.isName("Butt")) + m_nLE[i] = 6; + else if (oObj2.isName("ROpenArrow")) + m_nLE[i] = 7; + else if (oObj2.isName("RClosedArrow")) + m_nLE[i] = 8; + else if (oObj2.isName("Slash")) + m_nLE[i] = 9; + + oObj2.free(); + } + } + oObj.free(); + + // 17 - Цвет заполнения - IC + if (oAnnot.dictLookup("IC", &oObj)->isArray()) + { + m_unFlags |= (1 << 16); + for (int j = 0; j < oObj.arrayGetLength(); ++j) + { + m_arrIC.push_back(oObj.arrayGet(j, &oObj2)->isNum() ? oObj2.getNum() : 0.0); + oObj2.free(); + } + } + oObj.free(); + + // 21 - Назначение аннотации - IT + if (oAnnot.dictLookup("IT", &oObj)->isName()) + { + m_unFlags |= (1 << 20); + m_nIT = 0; // PolygonCloud + if (oObj.isName("PolyLineDimension")) + m_nIT = 1; + else if (oObj.isName("PolygonDimension")) + m_nIT = 2; + } + oObj.free(); + + oAnnot.free(); +} + //------------------------------------------------------------------------ // Annots //------------------------------------------------------------------------ @@ -2360,4 +2461,29 @@ void CAnnotSquareCircle::ToWASM(NSWasm::CData& oRes) oRes.AddDouble(m_arrIC[i]); } } + +void CAnnotPolygonLine::ToWASM(NSWasm::CData& oRes) +{ + oRes.WriteBYTE(m_nSubtype); // Polygon, PolyLine + + CMarkupAnnot::ToWASM(oRes); + + oRes.AddInt((unsigned int)m_arrVertices.size()); + for (int i = 0; i < m_arrVertices.size(); ++i) + oRes.AddDouble(m_arrVertices[i]); + + if (m_unFlags & (1 << 15)) + { + oRes.WriteBYTE(m_nLE[0]); + oRes.WriteBYTE(m_nLE[1]); + } + if (m_unFlags & (1 << 16)) + { + oRes.AddInt((unsigned int)m_arrIC.size()); + for (int i = 0; i < m_arrIC.size(); ++i) + oRes.AddDouble(m_arrIC[i]); + } + if (m_unFlags & (1 << 20)) + oRes.WriteBYTE(m_nIT); +} } diff --git a/PdfFile/SrcReader/PdfAnnot.h b/PdfFile/SrcReader/PdfAnnot.h index ea7a8b2721..bd0e11d49f 100644 --- a/PdfFile/SrcReader/PdfAnnot.h +++ b/PdfFile/SrcReader/PdfAnnot.h @@ -417,6 +417,26 @@ private: std::vector m_arrIC; // Цвет заполнения }; +//------------------------------------------------------------------------ +// PdfReader::CAnnotPolygonPolyline +//------------------------------------------------------------------------ + +class CAnnotPolygonLine final : public CMarkupAnnot +{ +public: + CAnnotPolygonLine(PDFDoc* pdfDoc, Object* oAnnotRef, int nPageIndex); + + void ToWASM(NSWasm::CData& oRes) override; + +private: + BYTE m_nIT; // Назначение аннотации + BYTE m_nSubtype; // Подтип Polygon или Polyline аннотации + BYTE m_nLE[2]; // Стили окончания линии + std::vector m_arrIC; // Цвет заполнения + std::vector m_arrVertices; // Координаты вершин + // TODO Measure Показатели масштаба, единиц измерения +}; + //------------------------------------------------------------------------ // PdfReader::CAnnots //------------------------------------------------------------------------