mirror of
https://github.com/ONLYOFFICE/core.git
synced 2026-02-10 18:05:41 +08:00
Fix shape with redact
This commit is contained in:
@ -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);
|
||||
|
||||
@ -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);
|
||||
};
|
||||
}
|
||||
|
||||
|
||||
@ -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;
|
||||
|
||||
@ -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);
|
||||
|
||||
|
||||
@ -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;
|
||||
}
|
||||
|
||||
|
||||
@ -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;
|
||||
};
|
||||
|
||||
|
||||
@ -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);
|
||||
*/
|
||||
}
|
||||
}
|
||||
|
||||
@ -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:
|
||||
|
||||
Reference in New Issue
Block a user