2022-05-03 10:25:52 +00:00
|
|
|
|
#include "HGOfdImpl.hpp"
|
|
|
|
|
#include "../base/HGInc.h"
|
|
|
|
|
#include "../base/HGUtility.h"
|
|
|
|
|
#include "../utility/HGString.h"
|
|
|
|
|
|
|
|
|
|
#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;
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
int error = 0;
|
|
|
|
|
m_zip = zip_open(StdStringToUtf8(fileName).c_str(), 0, &error);
|
|
|
|
|
if (NULL == m_zip)
|
|
|
|
|
{
|
|
|
|
|
return HGBASE_ERR_FAIL;
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
std::string content;
|
|
|
|
|
if (!ReadXml("Doc_0/Document.xml", content))
|
|
|
|
|
{
|
|
|
|
|
zip_close(m_zip);
|
|
|
|
|
m_zip = NULL;
|
|
|
|
|
return HGBASE_ERR_FAIL;
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
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 HGBASE_ERR_OK;
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
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;
|
|
|
|
|
if (!ReadXml(name, content))
|
|
|
|
|
{
|
|
|
|
|
return HGBASE_ERR_FAIL;
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
HGResult ret = HGBASE_ERR_FAIL;
|
|
|
|
|
tinyxml2::XMLDocument xmlDoc;
|
|
|
|
|
if (tinyxml2::XML_SUCCESS == xmlDoc.Parse(content.c_str()))
|
|
|
|
|
{
|
|
|
|
|
tinyxml2::XMLElement* root = xmlDoc.RootElement();
|
|
|
|
|
if (NULL != root)
|
|
|
|
|
{
|
|
|
|
|
tinyxml2::XMLElement* area = root->FirstChildElement("ofd:Area");
|
|
|
|
|
if (NULL != area)
|
|
|
|
|
{
|
|
|
|
|
tinyxml2::XMLElement* physicalBox = area->FirstChildElement("ofd:PhysicalBox");
|
|
|
|
|
if (NULL != physicalBox)
|
|
|
|
|
{
|
|
|
|
|
double data[4];
|
|
|
|
|
if (GetRect(physicalBox->GetText(), data))
|
|
|
|
|
{
|
|
|
|
|
info->width = (HGUInt)data[2];
|
|
|
|
|
info->height = (HGUInt)data[3];
|
|
|
|
|
ret = HGBASE_ERR_OK;
|
|
|
|
|
}
|
|
|
|
|
}
|
|
|
|
|
}
|
|
|
|
|
}
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
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 (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;
|
|
|
|
|
if (!ReadXml(name, content))
|
|
|
|
|
{
|
|
|
|
|
return HGBASE_ERR_FAIL;
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
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 HGBASE_ERR_FAIL;
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
if (!ReadXml("Doc_0/DocumentRes.xml", content))
|
|
|
|
|
{
|
|
|
|
|
return HGBASE_ERR_FAIL;
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
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 HGBASE_ERR_FAIL;
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
char img_name[128];
|
|
|
|
|
sprintf(img_name, "Doc_0/Res/%s", imgName.c_str());
|
|
|
|
|
if (!ReadJpeg(img_name, xScale, yScale, imgType, imgOrigin, image))
|
|
|
|
|
{
|
|
|
|
|
return HGBASE_ERR_FAIL;
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
return HGBASE_ERR_OK;
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
bool 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 false;
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
zip_file* file = zip_fopen(m_zip, name, ZIP_FL_NOCASE);
|
|
|
|
|
if (NULL == file)
|
|
|
|
|
{
|
|
|
|
|
return false;
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
char* s = (char*)malloc((size_t)size + 1);
|
|
|
|
|
if (NULL == s)
|
|
|
|
|
{
|
|
|
|
|
zip_fclose(file);
|
|
|
|
|
return false;
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
zip_int64_t did_read = zip_fread(file, s, size);
|
|
|
|
|
if (did_read != size)
|
|
|
|
|
{
|
|
|
|
|
free(s);
|
|
|
|
|
zip_fclose(file);
|
|
|
|
|
return false;
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
s[size] = 0;
|
|
|
|
|
content = s;
|
|
|
|
|
|
|
|
|
|
free(s);
|
|
|
|
|
zip_fclose(file);
|
|
|
|
|
return true;
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
bool HGOfdReaderImpl::ReadJpeg(const char* name, 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 false;
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
zip_file* file = zip_fopen(m_zip, name, ZIP_FL_NOCASE);
|
|
|
|
|
if (NULL == file)
|
|
|
|
|
{
|
|
|
|
|
return false;
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
unsigned char* content = (unsigned char*)malloc((size_t)size);
|
|
|
|
|
if (NULL == content)
|
|
|
|
|
{
|
|
|
|
|
zip_fclose(file);
|
|
|
|
|
return false;
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
zip_int64_t did_read = zip_fread(file, content, size);
|
|
|
|
|
if (did_read != size)
|
|
|
|
|
{
|
|
|
|
|
free(content);
|
|
|
|
|
zip_fclose(file);
|
|
|
|
|
return false;
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
HGBuffer buffer = NULL;
|
|
|
|
|
HGBase_CreateBufferWithData(content, (size_t)size, &buffer);
|
|
|
|
|
HGResult ret = HGImgFmt_LoadJpegImageFromBuffer(buffer, NULL, imgType, imgOrigin, image);
|
|
|
|
|
HGBase_DestroyBuffer(buffer);
|
|
|
|
|
|
|
|
|
|
free(content);
|
|
|
|
|
zip_fclose(file);
|
|
|
|
|
return (HGBASE_ERR_OK == 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)
|
|
|
|
|
{
|
|
|
|
|
return HGBASE_ERR_FAIL;
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
zip_add_dir(m_zip, "Doc_0");
|
|
|
|
|
zip_add_dir(m_zip, "Doc_0/Pages");
|
|
|
|
|
zip_add_dir(m_zip, "Doc_0/Res");
|
|
|
|
|
|
|
|
|
|
if (!AddOfdXml() || !AddPublicResXml())
|
|
|
|
|
{
|
|
|
|
|
zip_close(m_zip);
|
|
|
|
|
m_zip = NULL;
|
|
|
|
|
return HGBASE_ERR_FAIL;
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
return HGBASE_ERR_OK;
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
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;
|
|
|
|
|
}
|
|
|
|
|
|
2022-05-13 03:56:46 +00:00
|
|
|
|
HGResult HGOfdImageWriterImpl::SaveJpegImage(HGImage image, const HGJpegSaveInfo* info)
|
2022-05-03 10:25:52 +00:00
|
|
|
|
{
|
|
|
|
|
HGChar name[128];
|
|
|
|
|
sprintf(name, "Doc_0/Res/image_%u.jpg", m_curImgIndex);
|
2022-05-13 03:56:46 +00:00
|
|
|
|
if (!AddJpegImageFile(image, info, name))
|
2022-05-03 10:25:52 +00:00
|
|
|
|
{
|
|
|
|
|
return HGBASE_ERR_FAIL;
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
HGImageInfo imgInfo;
|
|
|
|
|
HGBase_GetImageInfo(image, &imgInfo);
|
|
|
|
|
HGFloat physicalWidth = 25.4f * (HGFloat)imgInfo.width / 96.0f;
|
|
|
|
|
HGFloat physicalHeight = 25.4f * (HGFloat)imgInfo.height / 96.0f;
|
|
|
|
|
|
|
|
|
|
AddContentXmlFile(m_curImgIndex, physicalWidth, physicalHeight);
|
|
|
|
|
++m_curImgIndex;
|
|
|
|
|
return HGBASE_ERR_OK;
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
bool 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("HuaGo");
|
|
|
|
|
docInfo->InsertEndChild(creator);
|
|
|
|
|
|
|
|
|
|
tinyxml2::XMLElement* createVersion = xmlDoc.NewElement("ofd:CreatorVersion");
|
|
|
|
|
createVersion->SetText("1.0.0");
|
|
|
|
|
docInfo->InsertEndChild(createVersion);
|
|
|
|
|
|
|
|
|
|
return AddXmlFile(xmlDoc, "OFD.xml");
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
bool 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];
|
2022-05-11 10:30:33 +00:00
|
|
|
|
sprintf(physicalBoxText, "0.000000 0.000000 %f %f", A4page_page_PhysicalBox_Width,
|
2022-05-03 10:25:52 +00:00
|
|
|
|
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");
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
bool 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");
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
bool 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");
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
bool HGOfdImageWriterImpl::AddXmlFile(tinyxml2::XMLDocument& xmlDoc, const HGChar* name)
|
|
|
|
|
{
|
|
|
|
|
HGChar tmpName[256];
|
|
|
|
|
HGBase_GetTmpFileName(tmpName, 256);
|
|
|
|
|
if (tinyxml2::XML_SUCCESS != xmlDoc.SaveFile(tmpName))
|
|
|
|
|
{
|
|
|
|
|
return false;
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
zip_source_t* s = zip_source_file(m_zip, tmpName, 0, 0);
|
|
|
|
|
if (NULL == s)
|
|
|
|
|
{
|
|
|
|
|
HGBase_DeleteFile(tmpName);
|
|
|
|
|
return false;
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
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 false;
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
m_tmpFiles.push_back(tmpName);
|
|
|
|
|
return true;
|
|
|
|
|
}
|
|
|
|
|
|
2022-05-13 03:56:46 +00:00
|
|
|
|
bool HGOfdImageWriterImpl::AddJpegImageFile(HGImage image, const HGJpegSaveInfo* info, const HGChar* name)
|
2022-05-03 10:25:52 +00:00
|
|
|
|
{
|
|
|
|
|
HGChar tmpName[256];
|
|
|
|
|
HGBase_GetTmpFileName(tmpName, 256);
|
2022-05-13 03:56:46 +00:00
|
|
|
|
if (HGBASE_ERR_OK != HGImgFmt_SaveJpegImage(image, info, tmpName))
|
2022-05-03 10:25:52 +00:00
|
|
|
|
{
|
|
|
|
|
return false;
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
zip_source_t* s = zip_source_file(m_zip, tmpName, 0, 0);
|
|
|
|
|
if (NULL == s)
|
|
|
|
|
{
|
|
|
|
|
HGBase_DeleteFile(tmpName);
|
|
|
|
|
return false;
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
zip_int64_t ret = zip_file_add(m_zip, name, s, ZIP_FL_OVERWRITE);
|
|
|
|
|
if (ret < 0)
|
|
|
|
|
{
|
|
|
|
|
zip_source_free(s);
|
|
|
|
|
HGBase_DeleteFile(tmpName);
|
|
|
|
|
return false;
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
m_tmpFiles.push_back(tmpName);
|
|
|
|
|
return true;
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
bool 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);
|
|
|
|
|
|
2022-05-11 10:30:33 +00:00
|
|
|
|
HGChar name[256];
|
2022-05-03 10:25:52 +00:00
|
|
|
|
sprintf(name, "%s/Content.xml", dir);
|
|
|
|
|
return AddXmlFile(xmlDoc, name);
|
|
|
|
|
}
|