code_app/modules/imgfmt/HGOfdImpl.cpp

917 lines
21 KiB
C++

#include "HGOfdImpl.hpp"
#include "../base/HGInc.h"
#include "../base/HGUtility.h"
#include "log/log.h"
#include "HGString.h"
extern HLOG g_hLog;
#define A4page_page_PhysicalBox_Width 210.000000
#define A4page_page_PhysicalBox_Height 297.000000
HGOfdReaderImpl::HGOfdReaderImpl()
{
m_zip = NULL;
}
HGOfdReaderImpl::~HGOfdReaderImpl()
{
}
HGResult HGOfdReaderImpl::Open(const HGChar* fileName)
{
if (NULL != m_zip)
{
return HGBASE_ERR_FAIL;
}
#if defined(HG_CMP_MSC)
if (0 != _access(fileName, 0))
#else
if (0 != access(fileName, 0))
#endif
{
return HGBASE_ERR_FILENOTEXIST;
}
int error = 0;
m_zip = zip_open(StdStringToUtf8(fileName).c_str(), 0, &error);
if (NULL == m_zip)
{
return HGBASE_ERR_FILEERROR;
}
std::string content;
HGResult ret = ReadXml("Doc_0/Document.xml", content);
if (HGBASE_ERR_OK != ret)
{
zip_close(m_zip);
m_zip = NULL;
return ret;
}
tinyxml2::XMLDocument xmlDoc;
if (tinyxml2::XML_SUCCESS == xmlDoc.Parse(content.c_str()))
{
tinyxml2::XMLElement* root = xmlDoc.RootElement();
if (NULL != root)
{
tinyxml2::XMLElement* pages = root->FirstChildElement("ofd:Pages");
if (NULL != pages)
{
tinyxml2::XMLElement* page = pages->FirstChildElement("ofd:Page");
if (NULL != page)
{
const char* attr = page->Attribute("BaseLoc");
if (NULL != attr)
m_contentNames.push_back(attr);
tinyxml2::XMLElement* p = page->NextSiblingElement("ofd:Page");
while (NULL != p)
{
const char* attr = p->Attribute("BaseLoc");
if (NULL != attr)
m_contentNames.push_back(attr);
p = p->NextSiblingElement("ofd:Page");
}
}
}
}
}
return ret;
}
HGResult HGOfdReaderImpl::Close()
{
if (NULL == m_zip)
{
return HGBASE_ERR_FAIL;
}
m_contentNames.clear();
zip_close(m_zip);
m_zip = NULL;
return HGBASE_ERR_OK;
}
HGResult HGOfdReaderImpl::GetPageCount(HGUInt* count)
{
if (NULL == m_zip)
{
return HGBASE_ERR_FAIL;
}
if (NULL == count)
{
return HGBASE_ERR_INVALIDARG;
}
*count = (HGUInt)m_contentNames.size();
return HGBASE_ERR_OK;
}
static bool GetRect(const char *text, double data[4])
{
bool ret = false;
if (NULL == text)
{
return ret;
}
char str[256];
strcpy(str, text);
int i = 0;
char* pStr = strtok(str, " ");
if (NULL != pStr)
{
data[i] = atof(pStr);
++i;
}
while (i < 4)
{
pStr = strtok(NULL, " ");
if (NULL == pStr)
break;
data[i] = atof(pStr);
++i;
}
return (4 == i);
}
HGResult HGOfdReaderImpl::GetPageInfo(HGUInt page, HGOfdPageInfo* info)
{
if (NULL == m_zip)
{
return HGBASE_ERR_FAIL;
}
if (page >= (HGUInt)m_contentNames.size() || NULL == info)
{
return HGBASE_ERR_INVALIDARG;
}
char name[128];
sprintf(name, "Doc_0/%s", m_contentNames[page].c_str());
std::string content;
HGResult ret = ReadXml(name, content);
if (HGBASE_ERR_OK != ret)
{
return ret;
}
tinyxml2::XMLDocument xmlDoc;
std::string resId;
if (tinyxml2::XML_SUCCESS == xmlDoc.Parse(content.c_str()))
{
tinyxml2::XMLElement* root = xmlDoc.RootElement();
if (NULL != root)
{
tinyxml2::XMLElement* content = root->FirstChildElement("ofd:Content");
if (NULL != content)
{
tinyxml2::XMLElement* layer = content->FirstChildElement("ofd:Layer");
if (NULL != layer)
{
const char* attr = layer->Attribute("Type");
#if defined(HG_CMP_MSC)
if (NULL == attr || 0 != _stricmp("Background", attr))
#else
if (NULL == attr || 0 != strcasecmp("Background", attr))
#endif
{
tinyxml2::XMLElement* p = layer->NextSiblingElement("ofd:Layer");
while (NULL != p)
{
const char* attr = p->Attribute("Type");
#if defined(HG_CMP_MSC)
if (NULL != attr && 0 == _stricmp("Background", attr))
#else
if (NULL != attr && 0 == strcasecmp("Background", attr))
#endif
{
break;
}
p = p->NextSiblingElement("ofd:Layer");
}
layer = p;
}
if (NULL != layer)
{
tinyxml2::XMLElement* imgObject = layer->FirstChildElement("ofd:ImageObject");
if (NULL != imgObject)
{
resId = imgObject->Attribute("ResourceID");
}
}
}
}
}
}
if (resId.empty())
{
return HGIMGFMT_ERR_FAIL;
}
ret = ReadXml("Doc_0/DocumentRes.xml", content);
if (HGBASE_ERR_OK != ret)
{
return ret;
}
std::string imgName;
if (tinyxml2::XML_SUCCESS == xmlDoc.Parse(content.c_str()))
{
tinyxml2::XMLElement* root = xmlDoc.RootElement();
if (NULL != root)
{
tinyxml2::XMLElement* multiMedias = root->FirstChildElement("ofd:MultiMedias");
if (NULL != multiMedias)
{
tinyxml2::XMLElement* multiMedia = multiMedias->FirstChildElement("ofd:MultiMedia");
if (NULL != multiMedia)
{
const char* attr = multiMedia->Attribute("ID");
#if defined(HG_CMP_MSC)
if (NULL == attr || 0 != _stricmp(resId.c_str(), attr))
#else
if (NULL == attr || 0 != strcasecmp(resId.c_str(), attr))
#endif
{
tinyxml2::XMLElement* p = multiMedia->NextSiblingElement("ofd:MultiMedia");
while (NULL != p)
{
const char* attr = p->Attribute("ID");
#if defined(HG_CMP_MSC)
if (NULL != attr && 0 == _stricmp(resId.c_str(), attr))
#else
if (NULL != attr && 0 == strcasecmp(resId.c_str(), attr))
#endif
{
break;
}
p = p->NextSiblingElement("ofd:MultiMedia");
}
multiMedia = p;
}
if (NULL != multiMedia)
{
tinyxml2::XMLElement* mediaFile = multiMedia->FirstChildElement("ofd:MediaFile");
if (NULL != mediaFile)
{
imgName = mediaFile->GetText();
}
}
}
}
}
}
if (imgName.empty())
{
return HGIMGFMT_ERR_FAIL;
}
char img_name[128];
sprintf(img_name, "Doc_0/Res/%s", imgName.c_str());
HGJpegLoadInfo jpegInfo;
ret = ReadJpeg(img_name, &jpegInfo, 0, 0, 0, 0, NULL);
if (HGBASE_ERR_OK != ret)
{
return ret;
}
info->width = jpegInfo.width;
info->height = jpegInfo.height;
info->bpp = jpegInfo.numComponents * 8;
return ret;
}
HGResult HGOfdReaderImpl::LoadImage(HGUInt page, HGFloat xScale, HGFloat yScale,
HGUInt imgType, HGUInt imgOrigin, HGImage* image)
{
if (NULL == m_zip)
{
return HGBASE_ERR_FAIL;
}
if (0 != imgOrigin && HGBASE_IMGORIGIN_TOP != imgOrigin && HGBASE_IMGORIGIN_BOTTOM != imgOrigin)
{
return HGBASE_ERR_INVALIDARG;
}
if (page >= (HGUInt)m_contentNames.size() || NULL == image)
{
return HGBASE_ERR_INVALIDARG;
}
char name[128];
sprintf(name, "Doc_0/%s", m_contentNames[page].c_str());
std::string content;
HGResult ret = ReadXml(name, content);
if (HGBASE_ERR_OK != ret)
{
return ret;
}
tinyxml2::XMLDocument xmlDoc;
std::string resId;
if (tinyxml2::XML_SUCCESS == xmlDoc.Parse(content.c_str()))
{
tinyxml2::XMLElement* root = xmlDoc.RootElement();
if (NULL != root)
{
tinyxml2::XMLElement* content = root->FirstChildElement("ofd:Content");
if (NULL != content)
{
tinyxml2::XMLElement* layer = content->FirstChildElement("ofd:Layer");
if (NULL != layer)
{
const char* attr = layer->Attribute("Type");
#if defined(HG_CMP_MSC)
if (NULL == attr || 0 != _stricmp("Background", attr))
#else
if (NULL == attr || 0 != strcasecmp("Background", attr))
#endif
{
tinyxml2::XMLElement* p = layer->NextSiblingElement("ofd:Layer");
while (NULL != p)
{
const char* attr = p->Attribute("Type");
#if defined(HG_CMP_MSC)
if (NULL != attr && 0 == _stricmp("Background", attr))
#else
if (NULL != attr && 0 == strcasecmp("Background", attr))
#endif
{
break;
}
p = p->NextSiblingElement("ofd:Layer");
}
layer = p;
}
if (NULL != layer)
{
tinyxml2::XMLElement* imgObject = layer->FirstChildElement("ofd:ImageObject");
if (NULL != imgObject)
{
resId = imgObject->Attribute("ResourceID");
}
}
}
}
}
}
if (resId.empty())
{
return HGIMGFMT_ERR_FAIL;
}
ret = ReadXml("Doc_0/DocumentRes.xml", content);
if (HGBASE_ERR_OK != ret)
{
return ret;
}
std::string imgName;
if (tinyxml2::XML_SUCCESS == xmlDoc.Parse(content.c_str()))
{
tinyxml2::XMLElement* root = xmlDoc.RootElement();
if (NULL != root)
{
tinyxml2::XMLElement* multiMedias = root->FirstChildElement("ofd:MultiMedias");
if (NULL != multiMedias)
{
tinyxml2::XMLElement* multiMedia = multiMedias->FirstChildElement("ofd:MultiMedia");
if (NULL != multiMedia)
{
const char* attr = multiMedia->Attribute("ID");
#if defined(HG_CMP_MSC)
if (NULL == attr || 0 != _stricmp(resId.c_str(), attr))
#else
if (NULL == attr || 0 != strcasecmp(resId.c_str(), attr))
#endif
{
tinyxml2::XMLElement* p = multiMedia->NextSiblingElement("ofd:MultiMedia");
while (NULL != p)
{
const char* attr = p->Attribute("ID");
#if defined(HG_CMP_MSC)
if (NULL != attr && 0 == _stricmp(resId.c_str(), attr))
#else
if (NULL != attr && 0 == strcasecmp(resId.c_str(), attr))
#endif
{
break;
}
p = p->NextSiblingElement("ofd:MultiMedia");
}
multiMedia = p;
}
if (NULL != multiMedia)
{
tinyxml2::XMLElement* mediaFile = multiMedia->FirstChildElement("ofd:MediaFile");
if (NULL != mediaFile)
{
imgName = mediaFile->GetText();
}
}
}
}
}
}
if (imgName.empty())
{
return HGIMGFMT_ERR_FAIL;
}
char img_name[128];
sprintf(img_name, "Doc_0/Res/%s", imgName.c_str());
ret = ReadJpeg(img_name, NULL, xScale, yScale, imgType, imgOrigin, image);
if (HGBASE_ERR_OK != ret)
{
return ret;
}
return ret;
}
HGResult HGOfdReaderImpl::ReadXml(const char* name, std::string& content)
{
struct zip_stat st;
zip_stat_init(&st);
zip_stat(m_zip, name, ZIP_FL_NOCASE, &st);
zip_int64_t size = st.size;
if (0 == size)
{
return HGIMGFMT_ERR_FAIL;
}
zip_file* file = zip_fopen(m_zip, name, ZIP_FL_NOCASE);
if (NULL == file)
{
return HGIMGFMT_ERR_FAIL;
}
char* s = (char*)malloc((size_t)size + 1);
if (NULL == s)
{
zip_fclose(file);
return HGBASE_ERR_OUTOFMEMORY;
}
zip_int64_t did_read = zip_fread(file, s, size);
if (did_read != size)
{
free(s);
zip_fclose(file);
return HGIMGFMT_ERR_FAIL;
}
s[size] = 0;
content = s;
free(s);
zip_fclose(file);
return HGBASE_ERR_OK;
}
HGResult HGOfdReaderImpl::ReadJpeg(const char* name, HGJpegLoadInfo* info, HGFloat xScale, HGFloat yScale, HGUInt imgType, HGUInt imgOrigin, HGImage* image)
{
struct zip_stat st;
zip_stat_init(&st);
zip_stat(m_zip, name, ZIP_FL_NOCASE, &st);
zip_int64_t size = st.size;
if (0 == size)
{
return HGIMGFMT_ERR_FAIL;
}
zip_file* file = zip_fopen(m_zip, name, ZIP_FL_NOCASE);
if (NULL == file)
{
return HGIMGFMT_ERR_FAIL;
}
unsigned char* content = (unsigned char*)malloc((size_t)size);
if (NULL == content)
{
zip_fclose(file);
return HGBASE_ERR_OUTOFMEMORY;
}
zip_int64_t did_read = zip_fread(file, content, size);
if (did_read != size)
{
free(content);
zip_fclose(file);
return HGIMGFMT_ERR_FAIL;
}
HGBuffer buffer = NULL;
HGBase_CreateBufferWithData(content, (size_t)size, &buffer);
HGResult ret = HGImgFmt_LoadJpegImageFromBuffer(buffer, info, imgType, imgOrigin, image);
HGBase_DestroyBuffer(buffer);
free(content);
zip_fclose(file);
return ret;
}
HGOfdImageWriterImpl::HGOfdImageWriterImpl()
{
m_zip = NULL;
m_curImgIndex = 0;
}
HGOfdImageWriterImpl::~HGOfdImageWriterImpl()
{
}
HGResult HGOfdImageWriterImpl::Open(const HGChar* fileName)
{
if (NULL != m_zip)
{
return HGBASE_ERR_FAIL;
}
int error = 0;
m_zip = zip_open(StdStringToUtf8(fileName).c_str(), ZIP_CREATE | ZIP_TRUNCATE, &error);
if (NULL == m_zip)
{
ErrorLog(g_hLog, "HGOfdImageWriterImpl::Open: zip_open fail, %s", fileName);
return HGBASE_ERR_ACCESSDENIED;
}
zip_add_dir(m_zip, "Doc_0");
zip_add_dir(m_zip, "Doc_0/Pages");
zip_add_dir(m_zip, "Doc_0/Res");
HGResult ret = AddOfdXml();
if (HGBASE_ERR_OK != ret)
{
zip_close(m_zip);
m_zip = NULL;
return ret;
}
ret = AddPublicResXml();
if (HGBASE_ERR_OK != ret)
{
zip_close(m_zip);
m_zip = NULL;
return ret;
}
return ret;
}
HGResult HGOfdImageWriterImpl::Close()
{
if (NULL == m_zip)
{
return HGBASE_ERR_FAIL;
}
AddDocXml();
AddDocResXml();
zip_close(m_zip);
m_zip = NULL;
// 清理临时文件
std::list<std::string>::const_iterator iter;
for (iter = m_tmpFiles.begin(); iter != m_tmpFiles.end(); ++iter)
{
HGBase_DeleteFile(iter->c_str());
}
m_tmpFiles.clear();
return HGBASE_ERR_OK;
}
HGResult HGOfdImageWriterImpl::SaveJpegImage(HGImage image, const HGJpegSaveInfo* info)
{
HGChar name[128];
sprintf(name, "Doc_0/Res/image_%u.jpg", m_curImgIndex);
HGResult ret = AddJpegImageFile(image, info, name);
if (HGBASE_ERR_OK != ret)
{
return ret;
}
HGUInt xDpi, yDpi;
HGBase_GetImageDpi(image, &xDpi, &yDpi);
if (NULL != info)
{
if (HGIMGFMT_JPEGDENUNIT_INCH == info->densityUnit)
{
xDpi = info->xDensity;
yDpi = info->yDensity;
}
else if (HGIMGFMT_JPEGDENUNIT_CENTIMETER == info->densityUnit)
{
xDpi = (uint32_t)((double)info->xDensity / 0.393700787 + 0.5);
yDpi = (uint32_t)((double)info->yDensity / 0.393700787 + 0.5);
}
}
HGImageInfo imgInfo;
HGBase_GetImageInfo(image, &imgInfo);
HGFloat physicalWidth = 25.4f * (HGFloat)imgInfo.width / (HGFloat)xDpi;
HGFloat physicalHeight = 25.4f * (HGFloat)imgInfo.height / (HGFloat)yDpi;
AddContentXmlFile(m_curImgIndex, physicalWidth, physicalHeight);
++m_curImgIndex;
return HGBASE_ERR_OK;
}
HGResult HGOfdImageWriterImpl::AddOfdXml()
{
tinyxml2::XMLDocument xmlDoc;
HGChar uuid[128];
HGBase_GetUuid(uuid, 128);
time_t tm = time(NULL);
struct tm *local_tm = localtime(&tm);
char local_tm_str[256];
strftime(local_tm_str, 256, "%c", local_tm);
tinyxml2::XMLElement *root = xmlDoc.NewElement("ofd:OFD");
root->SetAttribute("xmlns:ofd", "http://www.ofdspec.org/2016");
root->SetAttribute("DocType", "OFD");
root->SetAttribute("Version", "1.0");
xmlDoc.InsertEndChild(root);
tinyxml2::XMLElement* docBody = xmlDoc.NewElement("ofd:DocBody");
root->InsertEndChild(docBody);
tinyxml2::XMLElement* docRoot = xmlDoc.NewElement("ofd:DocRoot");
docRoot->SetText("Doc_0/Document.xml");
docBody->InsertEndChild(docRoot);
tinyxml2::XMLElement* docInfo = xmlDoc.NewElement("ofd:DocInfo");
docBody->InsertEndChild(docInfo);
tinyxml2::XMLElement* docId = xmlDoc.NewElement("ofd:DocID");
docId->SetText(uuid);
docInfo->InsertEndChild(docId);
tinyxml2::XMLElement* creationDate = xmlDoc.NewElement("ofd:CreationDate");
creationDate->SetText(local_tm_str);
docInfo->InsertEndChild(creationDate);
tinyxml2::XMLElement* modDate = xmlDoc.NewElement("ofd:ModDate");
modDate->SetText(local_tm_str);
docInfo->InsertEndChild(modDate);
tinyxml2::XMLElement* creator = xmlDoc.NewElement("ofd:Creator");
creator->SetText("ofd");
docInfo->InsertEndChild(creator);
tinyxml2::XMLElement* createVersion = xmlDoc.NewElement("ofd:CreatorVersion");
createVersion->SetText("1.0.0");
docInfo->InsertEndChild(createVersion);
return AddXmlFile(xmlDoc, "OFD.xml");
}
HGResult HGOfdImageWriterImpl::AddDocXml()
{
tinyxml2::XMLDocument xmlDoc;
tinyxml2::XMLElement* root = xmlDoc.NewElement("ofd:Document");
root->SetAttribute("xmlns:ofd", "http://www.ofdspec.org/2016");
xmlDoc.InsertEndChild(root);
tinyxml2::XMLElement* commonData = xmlDoc.NewElement("ofd:CommonData");
root->InsertEndChild(commonData);
tinyxml2::XMLElement* maxUnitID = xmlDoc.NewElement("ofd:MaxUnitID");
HGChar maxId[24];
sprintf(maxId, "%u", m_curImgIndex * 10 + 2);
maxUnitID->SetText(maxId);
commonData->InsertEndChild(maxUnitID);
tinyxml2::XMLElement* pageArea = xmlDoc.NewElement("ofd:PageArea");
commonData->InsertEndChild(pageArea);
tinyxml2::XMLElement* publicRes = xmlDoc.NewElement("ofd:PublicRes");
publicRes->SetText("PublicRes.xml");
commonData->InsertEndChild(publicRes);
tinyxml2::XMLElement* documentRes = xmlDoc.NewElement("ofd:DocumentRes");
documentRes->SetText("DocumentRes.xml");
commonData->InsertEndChild(documentRes);
tinyxml2::XMLElement* physicalBox = xmlDoc.NewElement("ofd:PhysicalBox");
char physicalBoxText[512];
sprintf(physicalBoxText, "0.000000 0.000000 %f %f", A4page_page_PhysicalBox_Width,
A4page_page_PhysicalBox_Height);
physicalBox->SetText(physicalBoxText);
pageArea->InsertEndChild(physicalBox);
tinyxml2::XMLElement* pages = xmlDoc.NewElement("ofd:Pages");
root->InsertEndChild(pages);
for (HGUInt i = 0; i < m_curImgIndex; ++i)
{
tinyxml2::XMLElement* page = xmlDoc.NewElement("ofd:Page");
HGChar id[24];
sprintf(id, "%u", i * 10 + 1);
page->SetAttribute("ID", id);
HGChar loc[128];
sprintf(loc, "Pages/Page_%u/Content.xml", i);
page->SetAttribute("BaseLoc", loc);
pages->InsertEndChild(page);
}
return AddXmlFile(xmlDoc, "Doc_0/Document.xml");
}
HGResult HGOfdImageWriterImpl::AddDocResXml()
{
tinyxml2::XMLDocument xmlDoc;
tinyxml2::XMLElement* root = xmlDoc.NewElement("ofd:Res");
root->SetAttribute("xmlns:ofd", "http://www.ofdspec.org/2016");
root->SetAttribute("BaseLoc", "Res");
xmlDoc.InsertEndChild(root);
tinyxml2::XMLElement* multiMedias = xmlDoc.NewElement("ofd:MultiMedias");
root->InsertEndChild(multiMedias);
for (HGUInt i = 0; i < m_curImgIndex; ++i)
{
tinyxml2::XMLElement* multiMedia = xmlDoc.NewElement("ofd:MultiMedia");
multiMedia->SetAttribute("Type", "Image");
HGChar id[24];
sprintf(id, "%u", i * 10 + 2);
multiMedia->SetAttribute("ID", id);
multiMedias->InsertEndChild(multiMedia);
tinyxml2::XMLElement* mediaFile = xmlDoc.NewElement("ofd:MediaFile");
HGChar loc[128];
sprintf(loc, "image_%u.jpg", i);
mediaFile->SetText(loc);
multiMedia->InsertEndChild(mediaFile);
}
return AddXmlFile(xmlDoc, "Doc_0/DocumentRes.xml");
}
HGResult HGOfdImageWriterImpl::AddPublicResXml()
{
tinyxml2::XMLDocument xmlDoc;
tinyxml2::XMLElement* root = xmlDoc.NewElement("ofd:Res");
root->SetAttribute("xmlns:ofd", "http://www.ofdspec.org/2016");
root->SetAttribute("BaseLoc", "Res");
xmlDoc.InsertEndChild(root);
tinyxml2::XMLElement* fonts = xmlDoc.NewElement("ofd:Fonts");
root->InsertEndChild(fonts);
return AddXmlFile(xmlDoc, "Doc_0/PublicRes.xml");
}
HGResult HGOfdImageWriterImpl::AddXmlFile(tinyxml2::XMLDocument& xmlDoc, const HGChar* name)
{
HGChar tmpName[256];
HGBase_GetTmpFileName(NULL, tmpName, 256);
if (tinyxml2::XML_SUCCESS != xmlDoc.SaveFile(tmpName))
{
return HGIMGFMT_ERR_FAIL;
}
zip_source_t* s = zip_source_file(m_zip, tmpName, 0, 0);
if (NULL == s)
{
HGBase_DeleteFile(tmpName);
return HGIMGFMT_ERR_FAIL;
}
zip_int64_t ret = zip_file_add(m_zip, name, s, ZIP_FL_ENC_UTF_8 | ZIP_FL_OVERWRITE);
if (ret < 0)
{
zip_source_free(s);
HGBase_DeleteFile(tmpName);
return HGIMGFMT_ERR_FAIL;
}
m_tmpFiles.push_back(tmpName);
return HGBASE_ERR_OK;
}
HGResult HGOfdImageWriterImpl::AddJpegImageFile(HGImage image, const HGJpegSaveInfo* info, const HGChar* name)
{
HGChar tmpName[256];
HGBase_GetTmpFileName(NULL, tmpName, 256);
HGResult ret = HGImgFmt_SaveJpegImage(image, info, tmpName);
if (HGBASE_ERR_OK != ret)
{
return ret;
}
zip_source_t* s = zip_source_file(m_zip, tmpName, 0, 0);
if (NULL == s)
{
HGBase_DeleteFile(tmpName);
return HGIMGFMT_ERR_FAIL;
}
zip_int64_t rc = zip_file_add(m_zip, name, s, ZIP_FL_OVERWRITE);
if (rc < 0)
{
zip_source_free(s);
HGBase_DeleteFile(tmpName);
return HGIMGFMT_ERR_FAIL;
}
m_tmpFiles.push_back(tmpName);
return HGBASE_ERR_OK;
}
HGResult HGOfdImageWriterImpl::AddContentXmlFile(HGUInt index, HGFloat physicalWidth, HGFloat physicalHeight)
{
HGChar dir[128];
sprintf(dir, "Doc_0/Pages/Page_%u", index);
zip_add_dir(m_zip, dir);
tinyxml2::XMLDocument xmlDoc;
tinyxml2::XMLElement* root = xmlDoc.NewElement("ofd:Page");
root->SetAttribute("xmlns:ofd", "http://www.ofdspec.org/2016");
xmlDoc.InsertEndChild(root);
tinyxml2::XMLElement* area = xmlDoc.NewElement("ofd:Area");
root->InsertEndChild(area);
tinyxml2::XMLElement* physicalBox = xmlDoc.NewElement("ofd:PhysicalBox");
char physicalBoxText[512];
sprintf(physicalBoxText, "0.000000 0.000000 %f %f", physicalWidth, physicalHeight);
physicalBox->SetText(physicalBoxText);
area->InsertEndChild(physicalBox);
tinyxml2::XMLElement* content = xmlDoc.NewElement("ofd:Content");
root->InsertEndChild(content);
tinyxml2::XMLElement* layer = xmlDoc.NewElement("ofd:Layer");
HGChar layerId[24];
sprintf(layerId, "%u", index * 10 + 3);
layer->SetAttribute("ID", layerId);
layer->SetAttribute("Type", "Background");
content->InsertEndChild(layer);
tinyxml2::XMLElement* imgObject = xmlDoc.NewElement("ofd:ImageObject");
HGChar imgObjectId[24];
sprintf(imgObjectId, "%u", index * 10 + 4);
imgObject->SetAttribute("ID", imgObjectId);
char boundaryText[512];
sprintf(boundaryText, "0.000000 0.000000 %f %f", physicalWidth, physicalHeight);
imgObject->SetAttribute("Boundary", boundaryText);
HGChar imgObjectResId[24];
sprintf(imgObjectResId, "%u", index * 10 + 2);
imgObject->SetAttribute("ResourceID", imgObjectResId);
char ctmText[512];
sprintf(ctmText, "%f 0 0 %f 0 0", physicalWidth, physicalHeight);
imgObject->SetAttribute("CTM", ctmText);
layer->InsertEndChild(imgObject);
HGChar name[256];
sprintf(name, "%s/Content.xml", dir);
return AddXmlFile(xmlDoc, name);
}