Fix shape with redact

This commit is contained in:
Svetlana Kulikova
2025-09-24 17:32:11 +03:00
parent d654092289
commit 1aa17ba09e
8 changed files with 120 additions and 88 deletions

View File

@ -46,8 +46,16 @@ namespace NSOnlineOfficeBinToPdf
RELEASEOBJECT(command);
return command;
}
template<typename T>
inline IAdvancedCommand* Read_Command_Len(CBufferReader* pReader, IMetafileToRenderter* pCorrector, int nLen)
{
T* command = new T();
if (!command->Read(pReader, pCorrector, nLen))
RELEASEOBJECT(command);
return command;
}
IAdvancedCommand* CBufferReader::Read(int type, IMetafileToRenderter* pCorrector)
IAdvancedCommand* CBufferReader::Read(int type, IMetafileToRenderter* pCorrector, int nLen)
{
switch (type)
{
@ -58,7 +66,7 @@ namespace NSOnlineOfficeBinToPdf
case ctFormField: return Read_Command<CFormFieldInfo> (this, pCorrector);
case ctAnnotFieldDelete: return Read_Command<CAnnotFieldDelete>(this, pCorrector);
case ctWidgetsInfo: return Read_Command<CWidgetsInfo> (this, pCorrector);
case ctShapeStart: return Read_Command<CShapeStart> (this, pCorrector);
case ctShapeStart: return Read_Command_Len<CShapeStart> (this, pCorrector, nLen);
case ctShapeEnd: return new CEmptyComand(IAdvancedCommand::AdvancedCommandType::ShapeEnd);
case ctPageClear: return new CEmptyComand(IAdvancedCommand::AdvancedCommandType::PageClear);
case ctPageRotate: return Read_Command<CPageRotate> (this, pCorrector);

View File

@ -190,8 +190,12 @@ namespace NSOnlineOfficeBinToPdf
int len = 2 * ReadUShort();
SkipString16(len);
}
inline int Tell()
{
return (int)(m_cur - m_buffer);
}
IAdvancedCommand* Read(int type, IMetafileToRenderter* pCorrector);
IAdvancedCommand* Read(int type, IMetafileToRenderter* pCorrector, int nLen = 0);
};
}

View File

@ -1224,34 +1224,34 @@ bool CWidgetsInfo::Read(NSOnlineOfficeBinToPdf::CBufferReader* pReader, IMetafil
}
CRedact::CRedact() : IAdvancedCommand(AdvancedCommandType::Redact) {}
CRedact::~CRedact() {}
int CRedact::GetFlag() const { return m_nFlag; }
const std::vector<double>& CRedact::GetQuadPoints() { return m_arrQuadPoints; }
const std::vector<std::wstring>& CRedact::GetID() { return m_arrID; }
BYTE* CRedact::GetRender(LONG& nLen)
CRedact::~CRedact()
{
nLen = m_nRenderLen;
return m_pRender;
for (int i = 0; i < m_arrRedact.size(); ++i)
RELEASEOBJECT(m_arrRedact[i]);
}
const std::vector<CRedact::SRedact*>& CRedact::GetRedact() { return m_arrRedact; }
bool CRedact::Read(NSOnlineOfficeBinToPdf::CBufferReader* pReader, IMetafileToRenderter* pCorrector)
{
int n = pReader->ReadInt();
m_arrQuadPoints.reserve(n * 4);
m_arrRedact.reserve(n);
for (int i = 0; i < n; ++i)
{
for (int j = 0; j < 4; ++j)
m_arrQuadPoints.push_back(pReader->ReadDouble());
}
m_arrID.reserve(n);
for (int i = 0; i < n; ++i)
m_arrID.push_back(pReader->ReadString());
m_nFlag = pReader->ReadInt();
if (m_nFlag & (1 << 0))
{
m_nRenderLen = pReader->ReadInt() - 4;
m_pRender = pReader->GetCurrentBuffer();
pReader->Skip(m_nRenderLen);
SRedact* pRedact = new SRedact();
pRedact->sID = pReader->ReadString();
int m = pReader->ReadInt();
pRedact->arrQuadPoints.reserve(m * 4);
for (int j = 0; j < m; ++j)
{
for (int k = 0; k < 4; ++k)
pRedact->arrQuadPoints.push_back(pReader->ReadDouble());
}
pRedact->nFlag = pReader->ReadInt();
if (pRedact->nFlag & (1 << 0))
{
pRedact->nRenderLen = pReader->ReadInt() - 4;
pRedact->pRender = pReader->GetCurrentBuffer();
pReader->Skip(pRedact->nRenderLen);
}
}
return true;

View File

@ -646,10 +646,7 @@ public:
CRedact();
virtual ~CRedact();
int GetFlag() const;
const std::vector<double>& GetQuadPoints();
const std::vector<std::wstring>& GetID();
BYTE* GetRender(LONG& nLen);
const std::vector<SRedact*>& GetRedact();
bool Read(NSOnlineOfficeBinToPdf::CBufferReader* pReader, IMetafileToRenderter* pCorrector);

View File

@ -147,10 +147,20 @@ void CShapeStart::SetShapeImage(BYTE* pImgData, int nWidth, int nHeight)
}
}
std::string& CShapeStart::GetShapeXML() { return m_sShapeXML; }
const std::vector<std::wstring>& CShapeStart::GetRedactID() { return m_arrRedactID; }
Aggplus::CImage* CShapeStart::GetShapeImage() { return m_pImage; }
bool CShapeStart::Read(NSOnlineOfficeBinToPdf::CBufferReader* pReader, IMetafileToRenderter* pCorrector)
bool CShapeStart::Read(NSOnlineOfficeBinToPdf::CBufferReader* pReader, IMetafileToRenderter* pCorrector, int nLen)
{
int nStart = pReader->Tell();
m_sShapeXML = pReader->ReadStringA();
int nEnd = pReader->Tell();
if (nEnd - nStart < nLen)
{
int n = pReader->ReadInt();
m_arrRedactID.reserve(n);
for (int i = 0; i < n; ++i)
m_arrRedactID.push_back(pReader->ReadString());
}
return true;
}

View File

@ -139,15 +139,17 @@ public:
~CShapeStart();
std::string& GetShapeXML();
const std::vector<std::wstring>& GetRedactID();
Aggplus::CImage* GetShapeImage();
void SetShapeXML(const std::string& sShapeXML);
void SetShapeImage(BYTE* pImgData, int nWidth, int nHeight);
bool Read(NSOnlineOfficeBinToPdf::CBufferReader* pReader, IMetafileToRenderter* pCorrector);
bool Read(NSOnlineOfficeBinToPdf::CBufferReader* pReader, IMetafileToRenderter* pCorrector, int nLen);
private:
std::string m_sShapeXML;
std::vector<std::wstring> m_arrRedactID;
Aggplus::CImage* m_pImage;
};

View File

@ -3520,24 +3520,31 @@ void CPdfEditor::Redact(IAdvancedCommand* _pCommand)
Page* pPage = pPDFDocument->getCatalog()->getPage(nPageIndex);
PDFRectangle* cropBox = pPage->getCropBox();
std::vector<double> arrAllQuads;
CRedact* pCommand = (CRedact*)_pCommand;
std::vector<double> arrQuads = pCommand->GetQuadPoints();
std::vector<std::wstring> arrID = pCommand->GetID();
for (int i = 0; i < arrQuads.size() / 4; ++i)
std::vector<CRedact::SRedact*> arrRedacts = pCommand->GetRedact();
for (CRedact::SRedact* pRedact : arrRedacts)
{
arrQuads[i * 4 + 0] += cropBox->x1;
double dQ = arrQuads[i * 4 + 1];
arrQuads[i * 4 + 1] = cropBox->y2 - arrQuads[i * 4 + 3];
arrQuads[i * 4 + 2] += cropBox->x1;
arrQuads[i * 4 + 3] = cropBox->y2 - dQ;
int nRect = pRedact->arrQuadPoints.size() / 4;
m_mRedact[pRedact->sID].reserve(nRect);
for (int i = 0; i < nRect; ++i)
{
std::vector<double> arrQuads = { pRedact->arrQuadPoints[i * 4 + 0], pRedact->arrQuadPoints[i * 4 + 1], pRedact->arrQuadPoints[i * 4 + 2], pRedact->arrQuadPoints[i * 4 + 3] };
arrQuads[i * 4 + 0] += cropBox->x1;
double dQ = arrQuads[i * 4 + 1];
arrQuads[i * 4 + 1] = cropBox->y2 - arrQuads[i * 4 + 3];
arrQuads[i * 4 + 2] += cropBox->x1;
arrQuads[i * 4 + 3] = cropBox->y2 - dQ;
m_mRedact[arrID[i]] = { arrQuads[i * 4 + 0], arrQuads[i * 4 + 1], arrQuads[i * 4 + 2], arrQuads[i * 4 + 3] };
m_mRedact[pRedact->sID].insert(m_mRedact[pRedact->sID].end(), arrQuads.begin(), arrQuads.end());
arrAllQuads.insert(arrAllQuads.end(), arrQuads.begin(), arrQuads.end());
}
}
#ifndef BUILDING_WASM_MODULE
PdfWriter::RedactOutputDev oRedactOut(m_pWriter);
oRedactOut.NewPDF(pPDFDocument->getXRef());
oRedactOut.SetRedact(arrQuads);
oRedactOut.SetRedact(arrAllQuads);
Object oContents;
pPage->getContents(&oContents);
@ -3548,56 +3555,59 @@ void CPdfEditor::Redact(IAdvancedCommand* _pCommand)
RELEASEOBJECT(gfx);
#endif
int nFlags = pCommand->GetFlag();
if (nFlags & (1 << 0))
for (CRedact::SRedact* pRedact : arrRedacts)
{
m_pWriter->SetTransform(1, 0, 0, 1, 0, 0);
LONG nLenRender = 0;
BYTE* pRender = pCommand->GetRender(nLenRender);
BYTE* pMemory = pRender;
int ret = *((int*)pMemory);
pMemory += 4;
double R = ret / 100000.0;
ret = *((int*)pMemory);
pMemory += 4;
double G = ret / 100000.0;
ret = *((int*)pMemory);
double B = ret / 100000.0;
LONG lColor = (LONG)(((LONG)(R * 255)) | ((LONG)(G * 255) << 8) | ((LONG)(B * 255) << 16) | ((LONG)255 << 24));
for (int i = 0; i < arrQuads.size() / 4; ++i)
int nFlags = pRedact->nFlag;
if (nFlags & (1 << 0))
{
m_pWriter->PathCommandEnd();
m_pWriter->put_BrushColor1(lColor);
m_pWriter->PathCommandMoveTo(PdfReader::PDFCoordsToMM(arrQuads[i * 4 + 0] - cropBox->x1), PdfReader::PDFCoordsToMM(cropBox->y2 - arrQuads[i * 4 + 1]));
m_pWriter->PathCommandLineTo(PdfReader::PDFCoordsToMM(arrQuads[i * 4 + 0] - cropBox->x1), PdfReader::PDFCoordsToMM(cropBox->y2 - arrQuads[i * 4 + 3]));
m_pWriter->PathCommandLineTo(PdfReader::PDFCoordsToMM(arrQuads[i * 4 + 2] - cropBox->x1), PdfReader::PDFCoordsToMM(cropBox->y2 - arrQuads[i * 4 + 3]));
m_pWriter->PathCommandLineTo(PdfReader::PDFCoordsToMM(arrQuads[i * 4 + 2] - cropBox->x1), PdfReader::PDFCoordsToMM(cropBox->y2 - arrQuads[i * 4 + 1]));
m_pWriter->PathCommandClose();
m_pWriter->DrawPath(NULL, L"", c_nWindingFillMode);
m_pWriter->PathCommandEnd();
m_pWriter->SetTransform(1, 0, 0, 1, 0, 0);
LONG nLenRender = pRedact->nRenderLen;
BYTE* pRender = pRedact->pRender;
BYTE* pMemory = pRender;
int ret = *((int*)pMemory);
pMemory += 4;
double R = ret / 100000.0;
ret = *((int*)pMemory);
pMemory += 4;
double G = ret / 100000.0;
ret = *((int*)pMemory);
double B = ret / 100000.0;
LONG lColor = (LONG)(((LONG)(R * 255)) | ((LONG)(G * 255) << 8) | ((LONG)(B * 255) << 16) | ((LONG)255 << 24));
for (int i = 0; i < pRedact->arrQuadPoints.size() / 4; ++i)
{
m_pWriter->PathCommandEnd();
m_pWriter->put_BrushColor1(lColor);
m_pWriter->PathCommandMoveTo(PdfReader::PDFCoordsToMM(pRedact->arrQuadPoints[i * 4 + 0]), PdfReader::PDFCoordsToMM(pRedact->arrQuadPoints[i * 4 + 1]));
m_pWriter->PathCommandLineTo(PdfReader::PDFCoordsToMM(pRedact->arrQuadPoints[i * 4 + 0]), PdfReader::PDFCoordsToMM(pRedact->arrQuadPoints[i * 4 + 3]));
m_pWriter->PathCommandLineTo(PdfReader::PDFCoordsToMM(pRedact->arrQuadPoints[i * 4 + 2]), PdfReader::PDFCoordsToMM(pRedact->arrQuadPoints[i * 4 + 3]));
m_pWriter->PathCommandLineTo(PdfReader::PDFCoordsToMM(pRedact->arrQuadPoints[i * 4 + 2]), PdfReader::PDFCoordsToMM(pRedact->arrQuadPoints[i * 4 + 1]));
m_pWriter->PathCommandClose();
m_pWriter->DrawPath(NULL, L"", c_nWindingFillMode);
m_pWriter->PathCommandEnd();
}
/*
PdfWriter::CPage* pCurPage = m_pWriter->GetPage();
pDoc->FixEditPage(pCurPage);
PdfWriter::CPage* pFakePage = new PdfWriter::CPage(pDoc);
m_pWriter->SetPage(pFakePage);
pDoc->SetCurPage(pFakePage);
// TODO Нужно нивелировать текущую матрицу до единичной, а потом сместить ещё на CropBox
pFakePage->SetStream(pCurPage->GetStream());
pFakePage->Add("Resources", pCurPage->Get("Resources"));
IMetafileToRenderter* pCorrector = new IMetafileToRenderter(m_pWriter->GetRenderer());
NSOnlineOfficeBinToPdf::ConvertBufferToRenderer(pRender, nLenRender, pCorrector);
RELEASEOBJECT(pCorrector);
m_pWriter->SetPage(pCurPage);
pDoc->SetCurPage(pCurPage);
RELEASEOBJECT(pFakePage);
*/
}
/*
PdfWriter::CPage* pCurPage = m_pWriter->GetPage();
pDoc->FixEditPage(pCurPage);
PdfWriter::CPage* pFakePage = new PdfWriter::CPage(pDoc);
m_pWriter->SetPage(pFakePage);
pDoc->SetCurPage(pFakePage);
// TODO Нужно нивелировать текущую матрицу до единичной, а потом сместить ещё на CropBox
pFakePage->SetStream(pCurPage->GetStream());
pFakePage->Add("Resources", pCurPage->Get("Resources"));
IMetafileToRenderter* pCorrector = new IMetafileToRenderter(m_pWriter->GetRenderer());
NSOnlineOfficeBinToPdf::ConvertBufferToRenderer(pRender, nLenRender, pCorrector);
RELEASEOBJECT(pCorrector);
m_pWriter->SetPage(pCurPage);
pDoc->SetCurPage(pCurPage);
RELEASEOBJECT(pFakePage);
*/
}
}

View File

@ -1330,6 +1330,7 @@ HRESULT CPdfFile::AdvancedCommand(IAdvancedCommand* command)
CShapeStart* pCommand = (CShapeStart*)command;
if (m_pInternal->pEditor)
m_pInternal->pEditor->AddShapeXML(pCommand->GetShapeXML());
// TODO Здесь необходимо наложить на рендер области редактов
return S_OK;
}
case IAdvancedCommand::AdvancedCommandType::ShapeEnd: