Refactoring and support binary shapes inside own pdf

This commit is contained in:
Oleg Korshul
2025-06-04 15:49:13 +03:00
parent 0f169b1491
commit c53009ee3d
3 changed files with 48 additions and 65 deletions

View File

@ -420,29 +420,31 @@ public:
oRenderer.SetExternalImageStorage(m_pImageStorage); oRenderer.SetExternalImageStorage(m_pImageStorage);
oRenderer.SetTextAssociationType(NSDocxRenderer::TextAssociationType::tatParagraphToShape); oRenderer.SetTextAssociationType(NSDocxRenderer::TextAssociationType::tatParagraphToShape);
std::vector<std::wstring> arShapes;
if (0 == mode)
arShapes = oRenderer.ScanPage(m_pFile, nPageIndex);
else if (1 == mode)
arShapes = oRenderer.ScanPagePptx(m_pFile, nPageIndex);
int nLen = (int)arShapes.size();
NSWasm::CData oRes; NSWasm::CData oRes;
switch (mode)
{
case 0:
case 1:
{
std::vector<std::wstring> arShapes = (0 == mode) ? oRenderer.ScanPage(m_pFile, nPageIndex) : oRenderer.ScanPagePptx(m_pFile, nPageIndex);
int nLen = (int)arShapes.size();
// mode 2 is binary format oRes.SkipLen();
if (mode != 2) oRes.AddInt(nLen);
{
oRes.SkipLen(); for (int i = 0; i < nLen; ++i)
oRes.AddInt(nLen); oRes.WriteString(arShapes[i]);
for (int i = 0; i < nLen; ++i)
oRes.WriteString(arShapes[i]); oRes.WriteLen();
oRes.WriteLen(); }
} case 2:
else {
{ oRes = oRenderer.ScanPageBin(m_pFile, nPageIndex);
oRes = oRenderer.ScanPageBin(m_pFile, nPageIndex); }
default:
return NULL;
} }
BYTE* res = oRes.GetBuffer(); BYTE* res = oRes.GetBuffer();
oRes.ClearWithoutAttack(); oRes.ClearWithoutAttack();
return res; return res;

View File

@ -209,7 +209,6 @@ HRESULT CDocxRenderer::IsSupportAdvancedCommand(const IAdvancedCommand::Advanced
return S_FALSE; return S_FALSE;
} }
// TODO Bin Shapes
HRESULT CDocxRenderer::AdvancedCommand(IAdvancedCommand* command) HRESULT CDocxRenderer::AdvancedCommand(IAdvancedCommand* command)
{ {
if (NULL == command) if (NULL == command)
@ -221,14 +220,33 @@ HRESULT CDocxRenderer::AdvancedCommand(IAdvancedCommand* command)
{ {
CShapeStart* pShape = (CShapeStart*)command; CShapeStart* pShape = (CShapeStart*)command;
std::string& sUtf8Shape = pShape->GetShapeXML(); std::string& sUtf8Shape = pShape->GetShapeXML();
UINT nImageId = 0xFFFFFFFF;
Aggplus::CImage* pImage = pShape->GetShapeImage(); Aggplus::CImage* pImage = pShape->GetShapeImage();
if (pImage) if (pImage)
{ {
std::shared_ptr<NSDocxRenderer::CImageInfo> pInfo = m_pInternal->m_oDocument.m_oImageManager.GenerateImageID(pImage); std::shared_ptr<NSDocxRenderer::CImageInfo> pInfo = m_pInternal->m_oDocument.m_oImageManager.GenerateImageID(pImage);
std::string sNewId = "r:embed=\"rId" + std::to_string(pInfo->m_nId + c_iStartingIdForImages) + "\""; nImageId = pInfo->m_nId;
NSStringUtils::string_replaceA(sUtf8Shape, "r:embed=\"\"", sNewId);
} }
m_pInternal->m_oDocument.m_oCurrentPage.AddCompleteXml(UTF8_TO_U(sUtf8Shape));
if (!sUtf8Shape.empty() && '<' == sUtf8Shape.at(0))
{
if (0xFFFFFFFF != nImageId)
{
std::string sNewId = "r:embed=\"rId" + std::to_string(nImageId + c_iStartingIdForImages) + "\"";
NSStringUtils::string_replaceA(sUtf8Shape, "r:embed=\"\"", sNewId);
}
m_pInternal->m_oDocument.m_oCurrentPage.AddCompleteXml(UTF8_TO_U(sUtf8Shape));
}
else
{
if (0xFFFFFFFF != nImageId)
{
// TODO:
}
m_pInternal->m_oDocument.m_oCurrentPage.AddCompleteBinBase64(sUtf8Shape);
}
return S_OK; return S_OK;
} }
case IAdvancedCommand::AdvancedCommandType::ShapeEnd: case IAdvancedCommand::AdvancedCommandType::ShapeEnd:

View File

@ -474,61 +474,24 @@ namespace NSDocxRenderer
shape->ToBin(writer); shape->ToBin(writer);
} }
/*
// testing m_arCompleteObjectsBinBase64
NSWasm::CData test_writer;
test_writer.SkipLen();
test_writer.AddInt(static_cast<unsigned int>(m_arShapes.size()));
for (const auto& shape : m_arShapes)
{
if (!shape) continue;
shape->ToBin(test_writer);
int size = test_writer.GetSize();
BYTE* data = test_writer.GetBuffer();
int size_base64 = NSBase64::Base64EncodeGetRequiredLength(size);
char* data_base64 = new char[size_base64];
NSBase64::Base64Encode(data, size, (BYTE*)data_base64, &size_base64, NSBase64::B64_BASE64_FLAG_NOCRLF);
m_arCompleteObjectsBinBase64.push_back(std::string(data_base64, size_base64));
delete[] data_base64;
}
*/
/* comment it if testing */
if (!m_arCompleteObjectsBinBase64.empty()) if (!m_arCompleteObjectsBinBase64.empty())
{ {
for (const auto& elem : m_arCompleteObjectsBinBase64) for (const auto& elem : m_arCompleteObjectsBinBase64)
{ {
int buff_len = NSBase64::Base64DecodeGetRequiredLength(elem.size()); int buff_len = NSBase64::Base64DecodeGetRequiredLength(elem.size());
BYTE* buff = new BYTE[buff_len]; BYTE* buff = new BYTE[buff_len];
bool is_ok = NSBase64::Base64Decode(elem.c_str(), elem.size(), buff, &buff_len);
if (!is_ok) if (NSBase64::Base64Decode(elem.c_str(), (int)elem.length(), buff, &buff_len))
continue; {
writer.Write(buff, buff_len);
}
writer.Write(buff, buff_len);
delete[] buff; delete[] buff;
} }
} }
writer.WriteLen(); writer.WriteLen();
/*
test_writer.WriteLen();
size_t size = writer.GetSize();
size_t test_size = test_writer.GetSize();
assert(size == test_size);
auto buffer = writer.GetBuffer();
auto test_buffer = writer.GetBuffer();
for (size_t i = 0; i < size; ++i)
assert(buffer[i] == test_buffer[i]);
*/
return writer; return writer;
} }
void CPage::AddCompleteXml(const std::wstring& oXml) void CPage::AddCompleteXml(const std::wstring& oXml)