Compare commits

..

25 Commits

Author SHA1 Message Date
12ef2e6510 Fix bug 59462 2022-11-24 18:11:20 +03:00
da3a6b3189 Fix bugs with cache 2022-11-18 12:20:05 +03:00
81e03f64db Add support print custom pages in pdf/xps/djvu 2022-11-17 19:24:11 +03:00
0aed94b748 Fix ios/android build 2022-11-17 10:19:34 +03:00
5af4ebba9e Fix bug with caches 2022-11-16 23:25:19 +03:00
a8f0c12d0f Merge pull request #1068 from ONLYOFFICE/feature/cacheJS
Feature/cache js
2022-11-16 20:46:01 +03:00
e5351899c5 Refactoring js cache directory 2022-11-16 18:58:48 +03:00
fa094e152c Create js caches for server 2022-11-16 17:34:45 +03:00
a69bff9e4e Merge branch hotfix/v7.2.1 into master 2022-10-20 13:06:36 +00:00
9b5fbdfa96 fix bug #59332 2022-10-17 18:39:01 +03:00
55f026bac4 Fix bug 59404 2022-10-17 16:04:22 +03:00
63b2ddfff3 fix build 2022-10-15 08:42:26 +03:00
0cad3436fd Merge pull request #1045 from ONLYOFFICE/fix/bug59199
Fix bug #59199
2022-10-14 12:53:10 +03:00
8aa54ed2e2 fix bug #59357 2022-10-14 12:48:47 +03:00
efb1511c59 Merge pull request #1048 from ONLYOFFICE/hotfix/v7.2.1-ppt
Hotfix/v7.2.1 ppt
2022-10-14 12:46:27 +03:00
34e9d98bee fix 59277 59281 59261 2022-10-14 12:08:05 +03:00
b25c3d3022 Switch to openssl 1.1.1i on android 2022-10-14 10:48:00 +03:00
2de73e8c02 fix part of 59276 2022-10-13 20:48:10 +03:00
a4b767303d small fixes. Audio inside animation problem 2022-10-12 18:55:09 +03:00
889721fd7e fix part of 59276. correct tmAbs 2022-10-12 00:23:54 +03:00
1df71c6504 fix part of 59276. Added new animation 2022-10-11 14:35:59 +03:00
cbd5d75532 trying to fix 59276. Old animation problem 2022-10-11 00:30:38 +03:00
cd0c129afb fix bug #59261 2022-10-07 14:32:06 +03:00
d322c08d98 Added temporary file deletion 2022-09-30 17:52:15 +03:00
e175b310f5 Fix bug #59199 2022-09-30 17:43:11 +03:00
27 changed files with 968 additions and 455 deletions

View File

@ -2089,11 +2089,11 @@ void variable_set::docx_convert(oox::docx_conversion_context & Context)
Context.output_stream() << L"<w:id w:val=\"" + std::to_wstring(Context.get_drawing_context().get_current_shape_id()) + L"\"/>";
if (name_)
{
Context.output_stream() << L"<w:placeholder>";
Context.output_stream() << L"<w:placeholder/>";
Context.output_stream() << L"<w:docPart w:val=\"" + xml::utils::replace_text_to_xml(*name_) + L"\"/>";
}
Context.output_stream() << L"<w:showingPlcHdr/>";
//Context.output_stream() << L"<w:text/>";
Context.output_stream() << L"<w:text/>";
}
Context.output_stream() << L"</w:sdtPr>";
Context.output_stream() << L"<w:sdtContent>";

View File

@ -52,6 +52,7 @@ void Animation::Convert(PPTX::Logic::Timing &oTiming)
{
if (m_pPPT10)
{
m_isPPT10Broken = false;
// It must be first to write some reference from ExtTimeNodeContainer
if (m_pPPT10->m_haveBuildList && !m_pPPT10->m_pBuildListContainer->n_arrRgChildRec.empty())
{
@ -66,7 +67,7 @@ void Animation::Convert(PPTX::Logic::Timing &oTiming)
FillTnLst(m_pPPT10->m_pExtTimeNodeContainer, *(oTiming.tnLst));
}
}
if (!m_arrOldAnim.empty() || m_isPPT10Broken)
if (!m_arrOldAnim.empty() && m_isPPT10Broken)
{
oTiming = PPTX::Logic::Timing();
InitTimingTags(oTiming);
@ -162,8 +163,8 @@ void Animation::FillAnim(
}
auto tavTime = animValue->m_oTimeAnimationValueAtom.m_nTime;
if (tavTime < 1000 && tavTime >= 0)
tav.tm = std::to_wstring((1000 - tavTime) * 100);
if (tavTime <= 1000 && tavTime >= 0) // todo check
tav.tm = std::to_wstring((/*1000 - */tavTime) * 100);
if (!animValue->m_VarFormula.m_Value.empty())
{
@ -424,6 +425,8 @@ void Animation::FillAudio(CRecordExtTimeNodeContainer *pETNC,
{
oAudio.cMediaNode.tgtEl.spTgt = new PPTX::Logic::SpTgt;
oAudio.cMediaNode.tgtEl.spTgt->spid = std::to_wstring(pCVEC->m_oVisualShapeAtom.m_nObjectIdRef);
// oAudio.isNarration = true;
// oAudio.cMediaNode.showWhenStopped = false;
} else
return;
FillCTn(pETNC, oAudio.cMediaNode.cTn);
@ -634,7 +637,6 @@ void Animation::FillCBhvr(
// accumulate - MUST be 0
// xfrmType - MUST be 0
if (pBhvr->m_haveStringList)
{
if (!pBhvr->m_pStringList->m_arrRgChildRec.empty())
@ -678,6 +680,46 @@ void Animation::FillCBhvr(
oBhvr.tgtEl.spTgt->txEl->end = pBhvr->m_oClientVisualElement.m_oVisualShapeAtom.m_nData2;
}
}
if (pBhvr->m_pPropertyList == nullptr)
return;
for (const auto prop : pBhvr->m_pPropertyList->m_arRecords)
{
if (prop == nullptr)
continue;
switch (prop->m_oHeader.RecInstance)
{
case TL_TBPID_RuntimeContext:
break;
case TL_TBPID_MotionPathEditRelative:
break;
case TL_TBPID_ColorColorModel:
break;
case TL_TBPID_ColorDirection:
break;
case TL_TBPID_Override:
{
auto override_ = new PPTX::Limit::TLOverride;
override_->set(L"childStyle");
oBhvr.override_= override_;
break;
}
case TL_TBPID_PathEditRotationAngle:
break;
case TL_TBPID_PathEditRotationX:
break;
case TL_TBPID_PathEditRotationY:
break;
case TL_TBPID_PointsTypes:
break;
case TL_TBPID_UnknownPropertyList:
default:
break;
}
}
}
void Animation::FillCBhvr(
PPTX::Logic::CBhvr &oBhvr, int dur,
@ -780,6 +822,9 @@ void Animation::FillCond(
cond.tgtEl->spTgt = new PPTX::Logic::SpTgt;
cond.tgtEl->spTgt->spid = std::to_wstring(
oldCond->m_oVisualElement.m_oVisualShapeAtom.m_nObjectIdRef);
} else if (oldCond->m_oVisualElement.m_bVisualPageAtom)
{
cond.tgtEl = new PPTX::Logic::TgtEl;
}
}
@ -873,12 +918,15 @@ void Animation::FillCTn(
if (iter->m_fIterateDirectionPropertyUsed)
oCTn.iterate->backwards = (bool)iter->m_nIterateDirection;
if (iter->m_fIterateIntervalTypePropertyUsed)
oCTn.iterate->tmPct = iter->m_nIterateInterval;
if (iter->m_fIterateIntervalPropertyUsed)
oCTn.iterate->tmAbs = std::to_wstring(iter->m_nIterateIntervalType);
int intervalType = iter->m_fIterateIntervalTypePropertyUsed ?
iter->m_nIterateIntervalType : 0;
unsigned int iterateInterval = iter->m_fIterateIntervalPropertyUsed ?
iter->m_nIterateInterval : 0;
if (intervalType)
oCTn.iterate->tmPct = iterateInterval > 1000 ? 10000 : iterateInterval * 10;
else
oCTn.iterate->tmAbs = std::to_wstring(iterateInterval);
}
@ -1437,6 +1485,9 @@ void Animation::SplitAnim(std::list<std::list<SOldAnimation*> >& arrClickPar)
for (auto& oldAnim : m_arrOldAnim)
{
if (isSpidReal(oldAnim.shapeId) == false)
continue;
if (arrClickPar.empty())
{
std::list<SOldAnimation*> clickPar;
@ -1670,6 +1721,7 @@ void Animation::FillCTnAnimation (PPTX::Logic::CTn &oCTN, SOldAnimation *pOldAn
const UINT effect = pOldAnim->anim->m_AnimationAtom.m_AnimEffect;
const UINT direct = pOldAnim->anim->m_AnimationAtom.m_AnimEffectDirection;
// Todo 4, 7. 0x11 - 0x1B
switch (effect)
{
case 0x00:
@ -1702,6 +1754,12 @@ void Animation::FillCTnAnimation (PPTX::Logic::CTn &oCTN, SOldAnimation *pOldAn
ConvertDissolveIn(oCTN.childTnLst.get2(), pOldAnim);
break;
}
case 0x06:
{
oCTN.presetID = 10;
ConvertFade(oCTN.childTnLst.get2(), pOldAnim);
break;
}
case 0x08:
{
oCTN.presetID = 14;
@ -1771,6 +1829,11 @@ void Animation::FillCTnAnimation (PPTX::Logic::CTn &oCTN, SOldAnimation *pOldAn
ConvertFlashOnce(oCTN.childTnLst.get2(), pOldAnim, presetSub);
break;
}
default:
oCTN.presetID = 1;
ConvertAppear(oCTN.childTnLst.get2(), pOldAnim);
std::wcout << "Error: Unknown old animation id: " << std::to_wstring(effect) << L"\n";
}
if (presetSub != -1)
@ -1970,6 +2033,12 @@ void Animation::ConvertDissolveIn(PPTX::Logic::ChildTnLst& oParent, SOldAnimatio
PushAnimEffect(oParent, pOldAnim, L"dissolve", L"in");
}
void Animation::ConvertFade(PPTX::Logic::ChildTnLst &oParent, SOldAnimation *pOldAnim)
{
PushSet(oParent, pOldAnim);
PushAnimEffect(oParent, pOldAnim, L"fade", L"in");
}
void Animation::ConvertFlashOnce(PPTX::Logic::ChildTnLst& oParent, SOldAnimation *pOldAnim, int& presetSub)
{
PushSet(oParent, pOldAnim);
@ -2389,14 +2458,19 @@ void Animation::PushSet(PPTX::Logic::ChildTnLst& oParent, SOldAnimation *pOldAni
bool Animation::isSpidReal(const UINT spid)
{
if (m_arrOldAnim.empty())
if (m_realShapesId.find(spid) == m_realShapesId.end())
return false;
else
return true;
for (const auto& oldAnim : m_arrOldAnim)
if (oldAnim.shapeId == spid)
return true;
// if (m_arrOldAnim.empty())
// return true;
return false;
// for (const auto& oldAnim : m_arrOldAnim)
// if (oldAnim.shapeId == spid)
// return true;
// return false;
}

View File

@ -53,6 +53,7 @@
#include "../Records/SlideProgTagsContainer.h"
#include "ImageManager.h"
#include "../Records/Animations/AnimationInfoContainer.h"
#include <unordered_set>
namespace PPT_FORMAT
{
@ -86,14 +87,16 @@ struct SValue
class Animation
{
public:
Animation(CRecordPP10SlideBinaryTagExtension *pPPT10Ext, const std::vector<SOldAnimation> &oldAnim, CExMedia* pExMedia, CRelsGenerator* pRels) :
Animation(CRecordPP10SlideBinaryTagExtension *pPPT10Ext, const std::vector<SOldAnimation> &oldAnim,
CExMedia* pExMedia, CRelsGenerator* pRels, const std::unordered_set<int>& realShapesId) :
m_pPPT10(pPPT10Ext),
m_arrOldAnim(oldAnim),
m_pExMedia(pExMedia),
m_pRels(pRels),
m_cTnId(1),
m_pBldLst(nullptr),
m_currentBldP(nullptr)
m_currentBldP(nullptr),
m_realShapesId(realShapesId)
{
}
@ -216,6 +219,7 @@ private:
void ConvertCheckerboard(PPTX::Logic::ChildTnLst& oParent, SOldAnimation* pOldAnim);
void ConvertCrawlIn(PPTX::Logic::ChildTnLst& oParent, SOldAnimation* pOldAnim, int& presetSub);
void ConvertDissolveIn(PPTX::Logic::ChildTnLst& oParent, SOldAnimation* pOldAnim);
void ConvertFade(PPTX::Logic::ChildTnLst& oParent, SOldAnimation* pOldAnim);
void ConvertFlashOnce(PPTX::Logic::ChildTnLst& oParent, SOldAnimation* pOldAnim, int& presetSub);
void ConvertPeekIn(PPTX::Logic::ChildTnLst& oParent, SOldAnimation* pOldAnim, int& presetSub);
void ConvertRandomBars(PPTX::Logic::ChildTnLst& oParent, SOldAnimation* pOldAnim, int& presetSub);
@ -259,9 +263,10 @@ private:
int m_cTnDeep = 0;
PPTX::Logic::BldLst *m_pBldLst; // Do not delete
PPTX::Logic::BldP *m_currentBldP;
const std::unordered_set<int> m_realShapesId;
int m_nextRID; // it needs for audio maybe video for compisation id number;
bool m_isPPT10Broken = false;
bool m_isPPT10Broken = true;
};
}

View File

@ -136,7 +136,7 @@ void PPT_FORMAT::CPPTXWriter::CreateFile(CPPTUserInfo* pUserInfo)
// core
oFile.CreateFileW(m_strTempDirectory + FILE_SEPARATOR_STR + _T("docProps") + FILE_SEPARATOR_STR + _T("core.xml"));
if (m_xmlCore.empty())
if (m_xmlCore.empty())
m_xmlCore = NSPPTXWriterConst::g_string_core;
oFile.WriteStringUTF8(m_xmlCore);
oFile.CloseFile();
@ -1537,12 +1537,16 @@ void PPT_FORMAT::CPPTXWriter::WriteSlide(int nIndexSlide)
CGroupElement *pGroupElement = !pSlide->m_arElements.empty() ? dynamic_cast<CGroupElement *>(pSlide->m_arElements[0].get()) : NULL;
size_t start_index = 0;
std::unordered_set<int> realShapesId;
if (pGroupElement)
{
for (size_t i = 0; i < pGroupElement->m_pChildElements.size(); ++i)
{
WriteElement(oWriter, oRels, pGroupElement->m_pChildElements[i]);
auto& element = pGroupElement->m_pChildElements[i];
WriteElement(oWriter, oRels, element);
if (element)
realShapesId.insert(element->m_lID);
}
start_index = 1;
@ -1550,7 +1554,10 @@ void PPT_FORMAT::CPPTXWriter::WriteSlide(int nIndexSlide)
for (size_t i = start_index; i < pSlide->m_arElements.size(); ++i)
{
WriteElement(oWriter, oRels, pSlide->m_arElements[i]);
auto& element = pSlide->m_arElements[i];
WriteElement(oWriter, oRels, element);
if (element)
realShapesId.insert(element->m_lID);
}
oWriter.WriteString(std::wstring(L"</p:spTree></p:cSld>"));
@ -1560,7 +1567,7 @@ void PPT_FORMAT::CPPTXWriter::WriteSlide(int nIndexSlide)
WriteTransition(oWriter, pSlide->m_oSlideShow);
// TODO write new method and class for timing
WriteTiming(oWriter, oRels, nIndexSlide);
WriteTiming(oWriter, oRels, realShapesId, nIndexSlide);
oWriter.WriteString(std::wstring(L"</p:sld>"));
@ -2029,7 +2036,7 @@ void CPPTXWriter::WriteLayoutAfterTheme(CThemePtr pTheme, const int nIndexTheme,
}
void PPT_FORMAT::CPPTXWriter::WriteTiming(CStringWriter& oWriter, CRelsGenerator &oRels, int nIndexSlide)
void PPT_FORMAT::CPPTXWriter::WriteTiming(CStringWriter& oWriter, CRelsGenerator &oRels, const std::unordered_set<int>& realShapesId, int nIndexSlide)
{
PPTX::Logic::Timing oTiming;
@ -2056,10 +2063,10 @@ void PPT_FORMAT::CPPTXWriter::WriteTiming(CStringWriter& oWriter, CRelsGenerator
}
}
if (!pPP10SlideBinaryTag && arrOldAnim.empty())
if (/*!pPP10SlideBinaryTag && */arrOldAnim.empty()) // todo check condition
return;
Animation animation(pPP10SlideBinaryTag, arrOldAnim, &(m_pUserInfo->m_oExMedia), &oRels);
Animation animation(pPP10SlideBinaryTag, arrOldAnim, &(m_pUserInfo->m_oExMedia), &oRels, realShapesId);
animation.Convert(oTiming);
oWriter.WriteString(oTiming.toXML());

View File

@ -89,7 +89,7 @@ namespace PPT_FORMAT
// void WriteRelsMaster (std::wstring path, int type, )
void WriteSlide (int nIndexSlide);
void WriteNotes (int nIndexNotes);
void WriteTiming (CStringWriter& oWriter, CRelsGenerator &oRels, int nIndexSlide); // TODO write spec class for timing
void WriteTiming (CStringWriter& oWriter, CRelsGenerator &oRels, const std::unordered_set<int> &realShapesId, int nIndexSlide);
void WriteTransition (CStringWriter& oWriter, CSlideShowInfo& oSSInfo);
void WriteColorScheme (CStringWriter& oWriter, const std::wstring & name, const std::vector<CColor> & colors, bool extra = false);

View File

@ -482,7 +482,7 @@ std::wstring PPT_FORMAT::CShapeWriter::ConvertShadow(CShadow & shadow)
}
else
{
// needHiddenEffect = shadow.Visible;
// needHiddenEffect = shadow.Visible;
shadow_writer.WriteString(L"<a:outerShdw");
shadow_writer.WriteString(strDist);
shadow_writer.WriteString(strDir);
@ -499,14 +499,14 @@ std::wstring PPT_FORMAT::CShapeWriter::ConvertShadow(CShadow & shadow)
shadow_writer.WriteString(L"</a:outerShdw>");
}
shadow_writer.WriteString(L"</a:effectLst>");
// if (needHiddenEffect)
// {
// std::wstring STRshadow;
// STRshadow = L"<a:extLst><a:ext uri=\"{AF507438-7753-43E0-B8FC-AC1667EBCBE1}\"><a14:hiddenEffects xmlns:a14=\"http://schemas.microsoft.com/office/drawing/2010/main\">";
// STRshadow += shadow_writer.GetData();
// STRshadow += L"</a14:hiddenEffects></a:ext><a:ext uri=\"{53640926-AAD7-44D8-BBD7-CCE9431645EC}\"><a14:shadowObscured xmlns:a14=\"http://schemas.microsoft.com/office/drawing/2010/main\" val=\"1\"/></a:ext></a:extLst>";
// return STRshadow;
// }
// if (needHiddenEffect)
// {
// std::wstring STRshadow;
// STRshadow = L"<a:extLst><a:ext uri=\"{AF507438-7753-43E0-B8FC-AC1667EBCBE1}\"><a14:hiddenEffects xmlns:a14=\"http://schemas.microsoft.com/office/drawing/2010/main\">";
// STRshadow += shadow_writer.GetData();
// STRshadow += L"</a14:hiddenEffects></a:ext><a:ext uri=\"{53640926-AAD7-44D8-BBD7-CCE9431645EC}\"><a14:shadowObscured xmlns:a14=\"http://schemas.microsoft.com/office/drawing/2010/main\" val=\"1\"/></a:ext></a:extLst>";
// return STRshadow;
// }
return shadow_writer.GetData();
}
@ -628,11 +628,11 @@ void PPT_FORMAT::CShapeWriter::WriteImageInfo()
bool bExternal = false;
std::wstring strRid = m_pRels->WriteAudio(pAudioElement->m_strAudioFileName, bExternal);
if ((int)pAudioElement->m_strAudioFileName.find(L".WAV") == -1 &&
(int)pAudioElement->m_strAudioFileName.find(L".wav") == -1)
m_oWriter.WriteString(L"<a:audioFile r:link=\"" + strRid + L"\"/>");
else
m_oWriter.WriteString(L"<a:wavAudioFile r:embed=\"" + strRid + L"\"/>");
// if ((int)pAudioElement->m_strAudioFileName.find(L".WAV") == -1 &&
// (int)pAudioElement->m_strAudioFileName.find(L".wav") == -1)
// m_oWriter.WriteString(L"<a:wavAudioFile r:embed=\"" + strRid + L"\"/>");
// else
m_oWriter.WriteString(L"<a:audioFile r:link=\"" + strRid + L"\"/>"); // todo for anim connection
sMediaFile = bExternal ? L"" : pAudioElement->m_strAudioFileName;
}
@ -676,7 +676,7 @@ void PPT_FORMAT::CShapeWriter::WriteGroupInfo()
if (!pGroupElement->m_sDescription.empty())
{
m_oWriter.WriteString(std::wstring(L" descr=\""));
m_oWriter.WriteStringXML(pGroupElement->m_sDescription);
m_oWriter.WriteStringXML(XmlUtils::EncodeXmlStringExtend(pGroupElement->m_sDescription));
m_oWriter.WriteString(std::wstring(L"\""));
}
m_oWriter.WriteString(std::wstring(L">"));
@ -729,7 +729,7 @@ void PPT_FORMAT::CShapeWriter::WriteTableInfo()
if (!pGroupElement->m_sDescription.empty())
{
m_oWriter.WriteString(std::wstring(L" descr=\""));
m_oWriter.WriteStringXML(pGroupElement->m_sDescription);
m_oWriter.WriteStringXML(XmlUtils::EncodeXmlStringExtend(pGroupElement->m_sDescription));
m_oWriter.WriteString(std::wstring(L"\""));
}
m_oWriter.WriteString(std::wstring(L">"));
@ -782,7 +782,7 @@ void PPT_FORMAT::CShapeWriter::WriteShapeInfo()
if (!pShapeElement->m_sDescription.empty())
{
m_oWriter.WriteString(std::wstring(L" descr=\""));
m_oWriter.WriteStringXML(pShapeElement->m_sDescription);
m_oWriter.WriteStringXML(XmlUtils::EncodeXmlStringExtend(pShapeElement->m_sDescription, true));
m_oWriter.WriteString(std::wstring(L"\""));
}
m_oWriter.WriteString(std::wstring(L">"));
@ -1556,7 +1556,7 @@ void PPT_FORMAT::CShapeWriter::WriteHyperlink(const std::vector<CInteractiveInfo
&& actions[i].m_lType == II_NoAction)
continue;
if (actions[i].m_strHyperlink.empty())
if (actions[i].m_strHyperlink.empty() && actions[i].m_lType != LT_CustomShow)
continue;
PPTX::Logic::Hyperlink hlink;

View File

@ -2401,7 +2401,11 @@ void CPPTUserInfo::LoadExternal(CRecordExObjListContainer* pExObjects)
oInfo.m_type = CExFilesInfo::ExFilesType::eftSlide;
m_oExMedia.m_arSlides.push_back(oInfo);
wasSlide = true;
}
} /*else if (oInfo.isHTTPLink(recStr))
{
oInfo.m_type = CExFilesInfo::ExFilesType::eftHyperlink;
m_oExMedia.m_arSlides.push_back(oInfo);
}*/
}
if (pExHyperlink->m_targetAtom.IsInit())
@ -2483,6 +2487,9 @@ void CPPTUserInfo::LoadExAudio(CRecordsContainer* pExObject)
oInfo.m_bLoop = oArrayExMedia[0]->m_bLoop;
oInfo.m_fNarration = oArrayExMedia[0]->m_bNarration;
oInfo.m_fRewind = oArrayExMedia[0]->m_bRewind;
m_oExMedia.m_arAudios.push_back(oInfo);
}

View File

@ -82,32 +82,26 @@ public:
eftAudio = 2,
eftHyperlink = 3,
eftObject = 4,
eftSlide = 5/*,
eftFile = 6*/
eftSlide = 5,
eftFile = 6
};
ExFilesType m_type;
_UINT32 m_dwID;
std::wstring m_strFilePath;
ExFilesType m_type = eftNone;
_UINT32 m_dwID = 0;
std::wstring m_strFilePath = L"";
std::wstring m_name;
// clip
double m_dStartTime;
double m_dEndTime;
double m_dStartTime = 0.0;
double m_dEndTime = 1.0;
// loop
bool m_bLoop;
bool m_bLoop = false;
bool m_fNarration = false; // isNarration pptx
bool m_fRewind = false;
CExFilesInfo()
{
m_type = eftNone;
m_dwID = 0;
m_strFilePath = _T("");
m_dStartTime = 0.0;
m_dEndTime = -1.0;
m_bLoop = false;
}
CExFilesInfo(const CExFilesInfo& oSrc)
{

View File

@ -126,7 +126,7 @@ namespace PPT_FORMAT
if (value <= 0 || value > 255)
return false;
std::set<int> BLCharset = {128, 136};
std::set<int> BLCharset = {128, 136, 129};
return BLCharset.find(value) == BLCharset.end();
}

View File

@ -37,8 +37,8 @@ echo TOOLS_ROOT=${TOOLS_ROOT}
# openssl-1.1.0f has a configure bug
# openssl-1.1.1d has fix configure bug
LIB_VERSION="OpenSSL_1_1_1d"
LIB_NAME="openssl-1.1.1d"
LIB_VERSION="OpenSSL_1_1_1i"
LIB_NAME="openssl-1.1.1i"
echo "https://www.openssl.org/source/${LIB_NAME}.tar.gz"

View File

@ -99,8 +99,7 @@ namespace NSDoctRenderer
std::wstring m_sJsonParams;
int m_nLcid;
int m_nRendererParams;
bool m_bIsCachedScripts;
std::wstring m_sScriptsCacheDirectory;
std::vector<int> m_arThemesThumbnailsParams;
public:
@ -124,9 +123,7 @@ namespace NSDoctRenderer
m_nMailMergeIndexEnd = -1;
m_nLcid = -1;
m_bIsCachedScripts = true;
m_nRendererParams = 0;
m_sScriptsCacheDirectory = L"";
}
~CExecuteParams()
{
@ -180,9 +177,7 @@ namespace NSDoctRenderer
m_nLcid = oNode.ReadValueInt(L"Lcid", -1);
m_sJsonParams = oNode.ReadValueString(L"JsonParams");
m_nRendererParams = oNode.ReadValueInt(L"DoctParams", 0);
if (0x01 == (0x01 & m_nRendererParams))
m_bIsCachedScripts = false;
m_sScriptsCacheDirectory = oNode.ReadValueString(L"ScriptsCacheDirectory", L"");
m_arThemesThumbnailsParams.clear();
std::wstring sThemesThumbnailsParams = oNode.ReadValueString(L"ThemesThumbnailsParams");
@ -1099,22 +1094,32 @@ namespace NSDoctRenderer
std::string strScript = "";
for (size_t i = 0; i < m_pInternal->m_arrFiles.size(); ++i)
{
#if 0
if (m_arrFiles[i].find(L"AllFonts.js") != std::wstring::npos)
continue;
#endif
strScript += m_pInternal->ReadScriptFile(m_pInternal->m_arrFiles[i]);
strScript += "\n\n";
}
std::wstring sCachePath = L"";
if (NULL != arSdkFiles)
if (arSdkFiles && (0 < arSdkFiles->size()))
{
if (m_pInternal->m_oParams.m_bIsCachedScripts && (0 < arSdkFiles->size()))
if (m_pInternal->m_oParams.m_sScriptsCacheDirectory.empty())
{
sCachePath = NSFile::GetDirectoryName(*arSdkFiles->begin()) + L"/sdk-all.cache";
}
else if (m_pInternal->m_oParams.m_sScriptsCacheDirectory != L"empty")
{
sCachePath = m_pInternal->m_oParams.m_sScriptsCacheDirectory;
wchar_t lastSymbol = sCachePath.back();
if (lastSymbol != '\\' && lastSymbol != '/')
sCachePath += L"/";
wchar_t editorFirst = m_pInternal->m_strEditorType.at(0);
if (editorFirst == 'd')
sCachePath += L"word";
else if (editorFirst == 'p')
sCachePath += L"slide";
else
sCachePath += L"cell";
}
for (std::vector<std::wstring>::iterator i = arSdkFiles->begin(); i != arSdkFiles->end(); i++)
{
@ -1145,6 +1150,96 @@ namespace NSDoctRenderer
{
return m_pInternal->m_arImagesInChanges;
}
void CDoctrenderer::CreateCache(const std::wstring& sAllFontsPath, const std::wstring& sCacheDir)
{
#ifndef JS_ENGINE_JAVASCRIPTCORE
LoadConfig(NSFile::GetProcessDirectory(), sAllFontsPath);
std::wstring sCacheDirectory = sCacheDir;
if (sCacheDirectory.empty() && m_pInternal->m_arDoctSDK.size() > 0)
{
sCacheDirectory = NSFile::GetDirectoryName(m_pInternal->m_arDoctSDK[0]);
sCacheDirectory = NSFile::GetDirectoryName(sCacheDirectory);
}
if (sCacheDirectory.empty())
return;
std::string strScriptAll = "";
for (size_t i = 0; i < m_pInternal->m_arrFiles.size(); ++i)
{
strScriptAll += m_pInternal->ReadScriptFile(m_pInternal->m_arrFiles[i]);
strScriptAll += "\n\n";
}
for (int i = 0; i < 3; ++i)
{
std::string strScript = strScriptAll;
std::wstring sCachePath = sCacheDirectory;
std::vector<std::wstring>* arSdkFiles = NULL;
switch (i)
{
case 0:
{
arSdkFiles = &m_pInternal->m_arDoctSDK;
sCachePath += L"/word/sdk-all.cache";
break;
}
case 1:
{
arSdkFiles = &m_pInternal->m_arPpttSDK;
sCachePath += L"/slide/sdk-all.cache";
break;
}
case 2:
{
arSdkFiles = &m_pInternal->m_arXlstSDK;
sCachePath += L"/cell/sdk-all.cache";
break;
}
default:
break;
}
if (NSFile::CFileBinary::Exists(sCachePath))
NSFile::CFileBinary::Remove(sCachePath);
for (std::vector<std::wstring>::iterator i = arSdkFiles->begin(); i != arSdkFiles->end(); i++)
{
strScript += m_pInternal->ReadScriptFile(*i);
strScript += "\n\n";
}
if (2 == i)
strScript += "\n$.ready();";
JSSmart<CJSContext> context = new CJSContext();
context->Initialize();
if (true)
{
JSSmart<CJSIsolateScope> isolate_scope = context->CreateIsolateScope();
JSSmart<CJSLocalScope> handle_scope = context->CreateLocalScope();
context->CreateGlobalForContext();
CNativeControlEmbed::CreateObjectBuilderInContext("CreateNativeEngine", context);
CGraphicsEmbed::CreateObjectInContext("CreateNativeGraphics", context);
NSJSBase::CreateDefaults(context);
context->CreateContext();
JSSmart<CJSContextScope> context_scope = context->CreateContextScope();
JSSmart<CJSTryCatch> try_catch = context->GetExceptions();
context->runScript(strScript, try_catch, sCachePath);
}
context->Dispose();
}
#endif
}
}
bool Doct_renderer_SaveFile_ForBuilder(int nFormat, const std::wstring& strDstFile,

View File

@ -67,6 +67,7 @@ namespace NSDoctRenderer
public:
bool Execute(const std::wstring& strXml, std::wstring& strError);
std::vector<std::wstring> GetImagesInChanges();
void CreateCache(const std::wstring& sAllFontsPath, const std::wstring& sCacheDir);
private:
CDoctRenderer_Private* m_pInternal;

View File

@ -188,4 +188,8 @@ namespace NSDoctRenderer
std::vector<std::wstring> stub;
return stub;
}
void CDoctrenderer::CreateCache(const std::wstring& sAllFontsPath, const std::wstring& sCacheDir)
{
}
}

View File

@ -75,4 +75,6 @@ use_javascript_core {
LIBS += -framework JavaScriptCore
DEFINES += JS_ENGINE_JAVASCRIPTCORE
}

View File

@ -2,379 +2,446 @@
v8::Local<v8::String> CreateV8String(v8::Isolate* i, const char* str, const int& len)
{
return v8::String::NewFromUtf8(i, str, kV8NormalString, len).ToLocalChecked();
return v8::String::NewFromUtf8(i, str, kV8NormalString, len).ToLocalChecked();
}
v8::Local<v8::String> CreateV8String(v8::Isolate* i, const std::string& str)
{
return v8::String::NewFromUtf8(i, str.c_str(), kV8NormalString, (int)str.length()).ToLocalChecked();
return v8::String::NewFromUtf8(i, str.c_str(), kV8NormalString, (int)str.length()).ToLocalChecked();
}
std::wstring CV8Worker::m_sExternalDirectory = L"";
namespace NSJSBase
{
class CCacheDataScript
{
private:
BYTE* Data;
int Length;
class CCacheDataScript
{
private:
BYTE* Data;
int Length;
v8::ScriptCompiler::Source* Source;
v8::ScriptCompiler::CachedData* CachedData;
std::wstring Path;
std::wstring Path;
public:
CCacheDataScript(const std::wstring& sPath)
{
Data = NULL;
Length = 0;
public:
CCacheDataScript(const std::wstring& sPath)
{
Data = NULL;
Length = 0;
Path = sPath;
if (!sPath.empty())
{
BYTE* _data = NULL;
DWORD _data_length = 0;
if (NSFile::CFileBinary::ReadAllBytes(sPath, &_data, _data_length))
{
Data = _data;
Length = (int)_data_length;
}
}
Source = NULL;
CachedData = NULL;
Path = sPath;
}
~CCacheDataScript()
{
//RELEASEOBJECT(Source);
//RELEASEOBJECT(CachedData);
RELEASEARRAYOBJECTS(Data);
}
v8::Local<v8::Script> Compile(const v8::Local<v8::Context>& _context, const v8::Local<v8::String>& source)
{
v8::Local<v8::Script> script;
if (NULL == Data)
{
Source = new v8::ScriptCompiler::Source(source);
script = v8::ScriptCompiler::Compile(_context, Source, kV8ProduceCodeCache).ToLocalChecked();
const v8::ScriptCompiler::CachedData* _cachedData = Source->GetCachedData();
NSFile::CFileBinary oFileTest;
if (_cachedData && oFileTest.CreateFileW(Path))
{
oFileTest.WriteFile(_cachedData->data, (DWORD)_cachedData->length);
oFileTest.CloseFile();
}
}
else
{
CachedData = new v8::ScriptCompiler::CachedData(Data, Length);
Source = new v8::ScriptCompiler::Source(source, CachedData);
script = v8::ScriptCompiler::Compile(_context, Source, v8::ScriptCompiler::kConsumeCodeCache).ToLocalChecked();
}
return script;
}
bool IsInit()
{
return Data != NULL && Length > 0;
}
};
class CJSIsolateScopeV8 : public CJSIsolateScope
{
public:
v8::Isolate::Scope isolate_scope;
v8::Locker isolate_locker;
public:
CJSIsolateScopeV8(v8::Isolate* isolate) : CJSIsolateScope(),
isolate_scope(isolate),
isolate_locker(isolate)
{
}
virtual ~CJSIsolateScopeV8()
{
}
};
class CJSContextScopeV8 : public CJSContextScope
{
public:
v8::Context::Scope m_scope;
public:
CJSContextScopeV8(v8::Local<v8::Context> context) : m_scope(context)
{
}
virtual ~CJSContextScopeV8()
{
}
};
class CJSLocalScopeV8 : public CJSLocalScope
{
public:
v8::HandleScope m_scope;
public:
CJSLocalScopeV8() : m_scope(CV8Worker::GetCurrent())
{
}
virtual ~CJSLocalScopeV8()
{
}
};
CJSContext::CJSContext()
{
m_internal = new CJSContextPrivate();
}
CJSContext::~CJSContext()
{
RELEASEOBJECT(m_internal);
}
CJSTryCatch* CJSContext::GetExceptions()
{
return new CV8TryCatch();
}
void CJSContext::Initialize()
{
m_internal->m_isolate = CV8Worker::getInitializer().CreateNew();
}
void CJSContext::Dispose()
{
#ifdef V8_INSPECTOR
v8_debug::disposeInspector(m_internal->m_context);
#ifndef V8_VERSION_89_PLUS
if (!sPath.empty())
{
BYTE* _data = NULL;
DWORD _data_length = 0;
if (NSFile::CFileBinary::ReadAllBytes(sPath, &_data, _data_length))
{
Data = _data;
Length = (int)_data_length;
}
}
#endif
m_internal->m_isolate->Dispose();
m_internal->m_isolate = NULL;
}
}
~CCacheDataScript()
{
RELEASEARRAYOBJECTS(Data);
}
void CJSContext::CreateContext()
{
m_internal->m_context = v8::Context::New(CV8Worker::GetCurrent(), NULL, m_internal->m_global);
}
#ifdef V8_VERSION_89_PLUS
v8::Local<v8::Script> Compile(const v8::Local<v8::Context>& _context, const v8::Local<v8::String>& source)
{
v8::Local<v8::Script> script;
void CJSContext::CreateGlobalForContext()
{
m_internal->m_global = v8::ObjectTemplate::New(CV8Worker::GetCurrent());
}
if (Path.empty())
{
// no cache
v8::ScriptCompiler::Source oSource(source);
v8::MaybeLocal<v8::Script> sctiptMB = v8::ScriptCompiler::Compile(_context, &oSource, v8::ScriptCompiler::kNoCompileOptions);
if (!sctiptMB.IsEmpty())
script = sctiptMB.ToLocalChecked();
CJSObject* CJSContext::GetGlobal()
{
CJSObjectV8* ret = new CJSObjectV8();
ret->value = m_internal->m_context->Global();
return ret;
}
return script;
}
CJSIsolateScope* CJSContext::CreateIsolateScope()
{
return new CJSIsolateScopeV8(m_internal->m_isolate);
}
if (NSFile::CFileBinary::Exists(Path))
{
// load cache from file
BYTE* _data = NULL;
DWORD _data_length = 0;
if (NSFile::CFileBinary::ReadAllBytes(Path, &_data, _data_length))
{
Data = _data;
Length = (int)_data_length;
}
CJSContextScope* CJSContext::CreateContextScope()
{
CJSContextScope* pScope = new CJSContextScopeV8(m_internal->m_context);
// compile with cache
v8::ScriptCompiler::CachedData* pCacheData = new v8::ScriptCompiler::CachedData(Data, Length);
v8::ScriptCompiler::Source oSource(source, pCacheData);
JSSmart<CJSObject> global = GetCurrent()->GetGlobal();
global->set("window", global.GetPointer());
v8::MaybeLocal<v8::Script> sctiptMB = v8::ScriptCompiler::Compile(_context, &oSource, v8::ScriptCompiler::kConsumeCodeCache);
if (!sctiptMB.IsEmpty())
script = sctiptMB.ToLocalChecked();
}
else
{
v8::ScriptCompiler::CachedData* pCacheData = nullptr;
return pScope;
}
// save cache to file
NSFile::CFileBinary oFileTest;
if (oFileTest.CreateFileW(Path))
{
// create cache data
v8::ScriptCompiler::Source oSource(source);
v8::Local<v8::Script> pScriptCache = v8::ScriptCompiler::Compile(_context, &oSource, v8::ScriptCompiler::kNoCompileOptions).ToLocalChecked();
pCacheData = v8::ScriptCompiler::CreateCodeCache(pScriptCache->GetUnboundScript());
CJSLocalScope* CJSContext::CreateLocalScope()
{
return new CJSLocalScopeV8();
}
if (pCacheData)
{
// save cache to file
NSFile::CFileBinary oFileTest;
if (oFileTest.CreateFileW(Path))
{
oFileTest.WriteFile(pCacheData->data, (DWORD)pCacheData->length);
oFileTest.CloseFile();
}
}
}
CJSValue* CJSContext::createUndefined()
{
CJSValueV8* _value = new CJSValueV8();
_value->doUndefined();
return _value;
}
// compile with/without(if pCacheData === NULL) cache data
v8::ScriptCompiler::Source oSource2(source, pCacheData);
v8::ScriptCompiler::CompileOptions compileOptions = (nullptr == pCacheData) ? v8::ScriptCompiler::kNoCompileOptions : v8::ScriptCompiler::kConsumeCodeCache;
CJSValue* CJSContext::createNull()
{
CJSValueV8* _value = new CJSValueV8();
_value->doNull();
return _value;
}
v8::MaybeLocal<v8::Script> sctiptMB = v8::ScriptCompiler::Compile(_context, &oSource2, compileOptions);
if (!sctiptMB.IsEmpty())
script = sctiptMB.ToLocalChecked();
}
return script;
}
#else
v8::Local<v8::Script> Compile(const v8::Local<v8::Context>& _context, const v8::Local<v8::String>& source)
{
v8::Local<v8::Script> script;
if (NULL == Data)
{
v8::ScriptCompiler::Source oSource(source);
script = v8::ScriptCompiler::Compile(_context, &oSource, kV8ProduceCodeCache).ToLocalChecked();
CJSValue* CJSContext::createBool(const bool& value)
{
CJSValueV8* _value = new CJSValueV8();
_value->value = v8::Boolean::New(CV8Worker::GetCurrent(), value);
return _value;
}
CJSValue* CJSContext::createInt(const int& value)
{
CJSValueV8* _value = new CJSValueV8();
_value->value = v8::Integer::New(CV8Worker::GetCurrent(), value);
return _value;
}
CJSValue* CJSContext::createUInt(const unsigned int& value)
{
CJSValueV8* _value = new CJSValueV8();
_value->value = v8::Integer::NewFromUnsigned(CV8Worker::GetCurrent(), value);
return _value;
}
CJSValue* CJSContext::createDouble(const double& value)
{
CJSValueV8* _value = new CJSValueV8();
_value->value = v8::Number::New(CV8Worker::GetCurrent(), value);
return _value;
}
CJSValue* CJSContext::createString(const char* value, const int& length)
{
CJSValueV8* _value = new CJSValueV8();
_value->value = CreateV8String(CV8Worker::GetCurrent(), value, length);
return _value;
}
CJSValue* CJSContext::createString(const wchar_t* value, const int& length)
{
std::string sUtf8 = NSFile::CUtf8Converter::GetUtf8StringFromUnicode2(value, (length != -1) ? (LONG)length : (LONG)wcslen(value));
return createString((const char*)sUtf8.c_str(), (int)sUtf8.length());
}
CJSValue* CJSContext::createString(const std::string& value)
{
CJSValueV8* _value = new CJSValueV8();
_value->value = CreateV8String(CV8Worker::GetCurrent(), value.c_str(), (int)value.length());
return _value;
}
CJSValue* CJSContext::createString(const std::wstring& value)
{
std::string sReturn = NSFile::CUtf8Converter::GetUtf8StringFromUnicode(value);
return createString(sReturn);
}
CJSObject* CJSContext::createObject()
{
CJSObjectV8* _value = new CJSObjectV8();
_value->value = v8::Object::New(CV8Worker::GetCurrent());
return _value;
}
CJSArray* CJSContext::createArray(const int& count)
{
CJSArrayV8* _value = new CJSArrayV8();
_value->value = v8::Array::New(CV8Worker::GetCurrent(), count);
_value->m_count = count;
return _value;
}
CJSTypedArray* CJSContext::createUint8Array(BYTE* data, int count, const bool& isExternalize)
{
CJSTypedArrayV8* _value = new CJSTypedArrayV8(data, count, isExternalize);
return _value;
}
JSSmart<CJSValue> CJSContext::runScript(const std::string& script, JSSmart<CJSTryCatch> exception, const std::wstring& scriptPath)
{
#ifdef V8_INSPECTOR
v8_debug::before(m_internal->m_context, CV8Worker::getInitializer()->getPlatform(), "");
const v8::ScriptCompiler::CachedData* _cachedData = oSource.GetCachedData();
NSFile::CFileBinary oFileTest;
if (_cachedData && oFileTest.CreateFileW(Path))
{
oFileTest.WriteFile(_cachedData->data, (DWORD)_cachedData->length);
oFileTest.CloseFile();
}
}
else
{
v8::ScriptCompiler::CachedData* pCachedData = new v8::ScriptCompiler::CachedData(Data, Length);
v8::ScriptCompiler::Source oSource(source, pCachedData);
script = v8::ScriptCompiler::Compile(_context, &oSource, v8::ScriptCompiler::kConsumeCodeCache).ToLocalChecked();
}
return script;
}
#endif
LOGGER_START
v8::Local<v8::String> _source = CreateV8String(CV8Worker::GetCurrent(), script.c_str());
v8::Local<v8::Script> _script;
if(!scriptPath.empty())
{
std::wstring sCachePath = scriptPath.substr(0, scriptPath.rfind(L".")) + L".cache";
CCacheDataScript oCachedScript(sCachePath);
_script = oCachedScript.Compile(m_internal->m_context, _source);
}
else
{
v8::MaybeLocal<v8::Script> _scriptRetValue = v8::Script::Compile(V8ContextFirstArg _source);
if (!_scriptRetValue.IsEmpty())
_script = _scriptRetValue.ToLocalChecked();
}
bool IsInit()
{
return Data != NULL && Length > 0;
}
};
LOGGER_LAP("compile")
CJSValueV8* _return = new CJSValueV8();
v8::MaybeLocal<v8::Value> retValue;
if (exception.is_init())
{
if (!exception->Check())
retValue = _script->Run(V8ContextOneArg);
}
else
{
retValue = _script->Run(V8ContextOneArg);
}
class CJSIsolateScopeV8 : public CJSIsolateScope
{
public:
v8::Isolate::Scope isolate_scope;
v8::Locker isolate_locker;
if (!retValue.IsEmpty())
_return->value = retValue.ToLocalChecked();
public:
CJSIsolateScopeV8(v8::Isolate* isolate) : CJSIsolateScope(),
isolate_scope(isolate),
isolate_locker(isolate)
{
}
virtual ~CJSIsolateScopeV8()
{
}
};
LOGGER_LAP("run")
return _return;
}
class CJSContextScopeV8 : public CJSContextScope
{
public:
v8::Context::Scope m_scope;
CJSContext* CJSContext::GetCurrent()
{
CJSContext* ret = new CJSContext();
ret->m_internal->m_isolate = CV8Worker::GetCurrent();
ret->m_internal->m_context = ret->m_internal->m_isolate->GetCurrentContext();
// global???
return ret;
}
public:
CJSContextScopeV8(v8::Local<v8::Context> context) : m_scope(context)
{
}
virtual ~CJSContextScopeV8()
{
}
};
CJSValue* CJSContext::JSON_Parse(const char *sTmp)
{
CJSValueV8* _value = new CJSValueV8();
#ifndef V8_OS_XP
v8::MaybeLocal<v8::Value> retValue = v8::JSON::Parse(m_internal->m_context, CreateV8String(CV8Worker::GetCurrent(), sTmp));
if (!retValue.IsEmpty())
_value->value = retValue.ToLocalChecked();
else
_value->doUndefined();
#else
_value->value = v8::JSON::Parse(CreateV8String(CV8Worker::GetCurrent(), sTmp));
#endif
return _value;
}
class CJSLocalScopeV8 : public CJSLocalScope
{
public:
v8::HandleScope m_scope;
void CJSContext::MoveToThread(ASC_THREAD_ID* id)
{
// none
}
public:
CJSLocalScopeV8() : m_scope(CV8Worker::GetCurrent())
{
}
virtual ~CJSLocalScopeV8()
{
}
};
void CJSContext::ExternalInitialize(const std::wstring& sDirectory)
{
CV8Worker::m_sExternalDirectory = sDirectory;
}
void CJSContext::ExternalDispose()
{
CV8Worker::Dispose();
}
bool CJSContext::IsSupportNativeTypedArrays()
{
return true;
}
unsigned char* NSAllocator::Alloc(const size_t& size)
{
return (unsigned char*)CV8Worker::getInitializer().getAllocator()->AllocateUninitialized(size);
}
void NSAllocator::Free(unsigned char* data, const size_t& size)
{
CV8Worker::getInitializer().getAllocator()->Free(data, size);
}
CJSContext::CJSContext()
{
m_internal = new CJSContextPrivate();
}
CJSContext::~CJSContext()
{
RELEASEOBJECT(m_internal);
}
CJSTryCatch* CJSContext::GetExceptions()
{
return new CV8TryCatch();
}
void CJSContext::Initialize()
{
m_internal->m_isolate = CV8Worker::getInitializer().CreateNew();
}
void CJSContext::Dispose()
{
#ifdef V8_INSPECTOR
v8_debug::disposeInspector(m_internal->m_context);
#endif
m_internal->m_isolate->Dispose();
m_internal->m_isolate = NULL;
}
void CJSContext::CreateContext()
{
m_internal->m_context = v8::Context::New(CV8Worker::GetCurrent(), NULL, m_internal->m_global);
}
void CJSContext::CreateGlobalForContext()
{
m_internal->m_global = v8::ObjectTemplate::New(CV8Worker::GetCurrent());
}
CJSObject* CJSContext::GetGlobal()
{
CJSObjectV8* ret = new CJSObjectV8();
ret->value = m_internal->m_context->Global();
return ret;
}
CJSIsolateScope* CJSContext::CreateIsolateScope()
{
return new CJSIsolateScopeV8(m_internal->m_isolate);
}
CJSContextScope* CJSContext::CreateContextScope()
{
CJSContextScope* pScope = new CJSContextScopeV8(m_internal->m_context);
JSSmart<CJSObject> global = GetCurrent()->GetGlobal();
global->set("window", global.GetPointer());
return pScope;
}
CJSLocalScope* CJSContext::CreateLocalScope()
{
return new CJSLocalScopeV8();
}
CJSValue* CJSContext::createUndefined()
{
CJSValueV8* _value = new CJSValueV8();
_value->doUndefined();
return _value;
}
CJSValue* CJSContext::createNull()
{
CJSValueV8* _value = new CJSValueV8();
_value->doNull();
return _value;
}
CJSValue* CJSContext::createBool(const bool& value)
{
CJSValueV8* _value = new CJSValueV8();
_value->value = v8::Boolean::New(CV8Worker::GetCurrent(), value);
return _value;
}
CJSValue* CJSContext::createInt(const int& value)
{
CJSValueV8* _value = new CJSValueV8();
_value->value = v8::Integer::New(CV8Worker::GetCurrent(), value);
return _value;
}
CJSValue* CJSContext::createUInt(const unsigned int& value)
{
CJSValueV8* _value = new CJSValueV8();
_value->value = v8::Integer::NewFromUnsigned(CV8Worker::GetCurrent(), value);
return _value;
}
CJSValue* CJSContext::createDouble(const double& value)
{
CJSValueV8* _value = new CJSValueV8();
_value->value = v8::Number::New(CV8Worker::GetCurrent(), value);
return _value;
}
CJSValue* CJSContext::createString(const char* value, const int& length)
{
CJSValueV8* _value = new CJSValueV8();
_value->value = CreateV8String(CV8Worker::GetCurrent(), value, length);
return _value;
}
CJSValue* CJSContext::createString(const wchar_t* value, const int& length)
{
std::string sUtf8 = NSFile::CUtf8Converter::GetUtf8StringFromUnicode2(value, (length != -1) ? (LONG)length : (LONG)wcslen(value));
return createString((const char*)sUtf8.c_str(), (int)sUtf8.length());
}
CJSValue* CJSContext::createString(const std::string& value)
{
CJSValueV8* _value = new CJSValueV8();
_value->value = CreateV8String(CV8Worker::GetCurrent(), value.c_str(), (int)value.length());
return _value;
}
CJSValue* CJSContext::createString(const std::wstring& value)
{
std::string sReturn = NSFile::CUtf8Converter::GetUtf8StringFromUnicode(value);
return createString(sReturn);
}
CJSObject* CJSContext::createObject()
{
CJSObjectV8* _value = new CJSObjectV8();
_value->value = v8::Object::New(CV8Worker::GetCurrent());
return _value;
}
CJSArray* CJSContext::createArray(const int& count)
{
CJSArrayV8* _value = new CJSArrayV8();
_value->value = v8::Array::New(CV8Worker::GetCurrent(), count);
_value->m_count = count;
return _value;
}
CJSTypedArray* CJSContext::createUint8Array(BYTE* data, int count, const bool& isExternalize)
{
CJSTypedArrayV8* _value = new CJSTypedArrayV8(data, count, isExternalize);
return _value;
}
JSSmart<CJSValue> CJSContext::runScript(const std::string& script, JSSmart<CJSTryCatch> exception, const std::wstring& scriptPath)
{
#ifdef V8_INSPECTOR
v8_debug::before(m_internal->m_context, CV8Worker::getInitializer()->getPlatform(), "");
#endif
LOGGER_START
v8::Local<v8::String> _source = CreateV8String(CV8Worker::GetCurrent(), script.c_str());
v8::Local<v8::Script> _script;
if(!scriptPath.empty())
{
std::wstring sCachePath = scriptPath.substr(0, scriptPath.rfind(L".")) + L".cache";
CCacheDataScript oCachedScript(sCachePath);
_script = oCachedScript.Compile(m_internal->m_context, _source);
}
else
{
v8::MaybeLocal<v8::Script> _scriptRetValue = v8::Script::Compile(V8ContextFirstArg _source);
if (!_scriptRetValue.IsEmpty())
_script = _scriptRetValue.ToLocalChecked();
}
LOGGER_LAP("compile")
CJSValueV8* _return = new CJSValueV8();
v8::MaybeLocal<v8::Value> retValue;
if (exception.is_init())
{
if (!exception->Check())
retValue = _script->Run(V8ContextOneArg);
}
else
{
retValue = _script->Run(V8ContextOneArg);
}
if (!retValue.IsEmpty())
_return->value = retValue.ToLocalChecked();
LOGGER_LAP("run")
return _return;
}
CJSContext* CJSContext::GetCurrent()
{
CJSContext* ret = new CJSContext();
ret->m_internal->m_isolate = CV8Worker::GetCurrent();
ret->m_internal->m_context = ret->m_internal->m_isolate->GetCurrentContext();
// global???
return ret;
}
CJSValue* CJSContext::JSON_Parse(const char *sTmp)
{
CJSValueV8* _value = new CJSValueV8();
#ifndef V8_OS_XP
v8::MaybeLocal<v8::Value> retValue = v8::JSON::Parse(m_internal->m_context, CreateV8String(CV8Worker::GetCurrent(), sTmp));
if (!retValue.IsEmpty())
_value->value = retValue.ToLocalChecked();
else
_value->doUndefined();
#else
_value->value = v8::JSON::Parse(CreateV8String(CV8Worker::GetCurrent(), sTmp));
#endif
return _value;
}
void CJSContext::MoveToThread(ASC_THREAD_ID* id)
{
// none
}
void CJSContext::ExternalInitialize(const std::wstring& sDirectory)
{
CV8Worker::m_sExternalDirectory = sDirectory;
}
void CJSContext::ExternalDispose()
{
CV8Worker::Dispose();
}
bool CJSContext::IsSupportNativeTypedArrays()
{
return true;
}
unsigned char* NSAllocator::Alloc(const size_t& size)
{
return (unsigned char*)CV8Worker::getInitializer().getAllocator()->AllocateUninitialized(size);
}
void NSAllocator::Free(unsigned char* data, const size_t& size)
{
CV8Worker::getInitializer().getAllocator()->Free(data, size);
}
}

View File

@ -619,11 +619,12 @@ namespace Aggplus
if (!bIsUseIdentity)
{
agg::trans_affine* full_trans = &m_oFullTransform.m_internal->m_agg_mtx;
double dDet = full_trans->determinant();
if (full_trans->sx < 0.01 && full_trans->sy < 0.01)
if (fabs(dDet) < 0.0001)
{
path_copy.transform_all_paths(m_oFullTransform.m_internal->m_agg_mtx);
dWidth *= sqrt(full_trans->sx * full_trans->sy);
dWidth *= sqrt(dDet);
bIsUseIdentity = true;
}

View File

@ -841,6 +841,12 @@ namespace MetaFile
m_pRenderer->put_BrushTextureMode(c_BrushTextureModeTile);
m_pRenderer->put_BrushTexturePath(pBrush->GetDibPatterPath());
}
else if (BS_PATTERN == unBrushStyle)
{
m_pRenderer->put_BrushType(c_BrushTypePattern);
m_pRenderer->put_BrushTextureMode(c_BrushTextureModeTileCenter);
m_pRenderer->put_BrushTexturePath(pBrush->GetDibPatterPath());
}
else if (BS_HATCHED == unBrushStyle)
{
m_pRenderer->put_BrushType(c_BrushTypeHatch1);

View File

@ -507,7 +507,35 @@ namespace MetaFile
}
case BrushTypeTextureFill:
{
//TODO: реализовать
// TODO: так как на данный момент нельзя регулировать повторение заливки, то будет отрисовывать изображение при самой заливки
pEmfPlusBrush->Style = BS_PATTERN;
unsigned int unBrushDataFlags, unSkip = 16;
m_oStream >> unBrushDataFlags;
m_oStream.Skip(4); // WrapMode
if (unBrushDataFlags & BrushDataTransform)
{
m_oStream.Skip(24); // TransformMatrix
unSkip += 24;
}
if (m_ulRecordSize <= 28)
break;
m_ulRecordSize -= unSkip;
CEmfPlusImage oImage;
ReadImage(oImage);
std::wstring wsImagePath;
if (SaveImage(oImage, wsImagePath))
pEmfPlusBrush->DibPatterPath = wsImagePath;
m_ulRecordSize += unSkip;
break;
}
case BrushTypePathGradient:
@ -1264,6 +1292,36 @@ namespace MetaFile
oMatrix.Dy *= m_dUnitKoef;
}
bool CEmfPlusParser::SaveImage(const CEmfPlusImage &oEmfPlusImage, std::wstring &wsPathToImage)
{
if (ImageDataTypeBitmap != oEmfPlusImage.GetImageDataType())
return false;
BYTE* pBytes;
unsigned int unImageSize;
oEmfPlusImage.GetData(pBytes, unImageSize);
NSFile::CFileBinary oFile;
std::wstring wsTempPath = oFile.GetTempPath() + L"/Temp" + std::to_wstring(unImageSize) + L".tmp";
if (!oFile.CreateFileW(wsTempPath))
return false;
if (!oFile.WriteFile(pBytes, unImageSize))
{
oFile.CloseFile();
return false;
}
oFile.CloseFile();
wsPathToImage = wsTempPath;
return true;
}
BYTE* GetClipedImage(const BYTE* pBuffer, LONG lWidth, LONG lHeight, TRect& oNewRect)
{
if (NULL == pBuffer ||

View File

@ -84,6 +84,8 @@ namespace MetaFile
void UpdateMatrix(TEmfPlusXForm& oMatrix);
bool SaveImage(const CEmfPlusImage& oImage, std::wstring& wsPathToImage);
void Read_EMRPLUS_OFFSETCLIP();
void Read_EMRPLUS_RESETCLIP();
void Read_EMFPLUS_SETCLIPPATH(unsigned short unShFlags);

View File

@ -163,7 +163,12 @@ namespace MetaFile
{
public:
CEmfPlusBrush() : CEmfPlusObject(), Style(BS_SOLID), Hatch(0), Angle(0) {};
virtual ~CEmfPlusBrush() {};
virtual ~CEmfPlusBrush()
{
if (!DibPatterPath.empty() && NSFile::CFileBinary::Exists(DibPatterPath))
NSFile::CFileBinary::Remove(DibPatterPath);
};
virtual EEmfObjectType GetType() override
{
return EMF_OBJECT_BRUSH;
@ -211,7 +216,7 @@ namespace MetaFile
std::wstring GetDibPatterPath()
{
return std::wstring();
return DibPatterPath;
}
void GetBounds(double& left, double& top, double& width, double& height)
@ -228,6 +233,7 @@ namespace MetaFile
unsigned int Hatch;
TEmfPlusRectF RectF;
unsigned int Angle;
std::wstring DibPatterPath;
};
class CEmfPlusPen: public CEmfPlusObject, public IPen

View File

@ -54,9 +54,15 @@ bool CSVGTransformer::OpenFromFile(const std::wstring& file)
m_internal->m_oRender.SetWorkingDirectory(sDirectory);
m_internal->m_oStorage.SetWorkingDirectory(sDirectory);
if (0 == m_internal->m_oXmlParser.LoadFromFile(file, &m_internal->m_oStorage))
try
{
if (!m_internal->m_oXmlParser.LoadFromFile(file, &m_internal->m_oStorage))
return false;
}
catch(...)
{
return false;
}
return true;
}
bool CSVGTransformer::Load(const std::wstring& content)

View File

@ -3584,7 +3584,121 @@ namespace NExtractTools
}
return nRes;
}
_UINT32 PdfDjvuXpsToRenderer(IOfficeDrawingFile** ppReader, IRenderer* pRenderer, const std::wstring &sFrom, int nFormatFrom, const std::wstring &sTo, const std::wstring &sTemp, InputParams& params, NSFonts::IApplicationFonts* pApplicationFonts)
std::string checkPrintPages(InputParams& params)
{
if (NULL == params.m_sJsonParams)
return "";
std::wstring::size_type posNativeOptions = params.m_sJsonParams->find(L"\"nativeOptions\"");
if (std::wstring::npos == posNativeOptions)
return "";
std::wstring::size_type posNativePages = params.m_sJsonParams->find(L"\"pages\":\"", posNativeOptions);
if (std::wstring::npos == posNativePages)
return "";
posNativePages += 9;
std::wstring::size_type posNativePages2 = params.m_sJsonParams->find(L"\"", posNativePages);
if (std::wstring::npos == posNativePages2)
return "";
std::wstring sPages = params.m_sJsonParams->substr(posNativePages, posNativePages2 - posNativePages);
if (L"all" == sPages)
return "";
if (L"current" == sPages)
{
std::wstring::size_type posCurrentPage = params.m_sJsonParams->find(L"\"currentPage\":", posNativeOptions);
if (std::wstring::npos == posCurrentPage)
return "";
posCurrentPage += 14;
std::wstring::size_type posCurrentPage2 = params.m_sJsonParams->find(L",", posCurrentPage);
std::wstring::size_type posCurrentPage3 = params.m_sJsonParams->find(L"}", posCurrentPage);
if (std::wstring::npos == posCurrentPage2)
{
if (std::wstring::npos == posCurrentPage3)
return "";
posCurrentPage2 = posCurrentPage3;
}
else if (std::wstring::npos != posCurrentPage3 && posCurrentPage3 < posCurrentPage2)
posCurrentPage2 = posCurrentPage3;
if (std::wstring::npos == posCurrentPage2)
return "";
sPages = params.m_sJsonParams->substr(posCurrentPage, posCurrentPage2 - posCurrentPage);
}
return U_TO_UTF8(sPages);
}
std::vector<bool> getPrintPages(const std::string& sPages, int nPagesCount)
{
const char* buffer = sPages.c_str();
size_t nCur = 0;
size_t nLen = sPages.length();
std::vector<bool> arPages;
for (int i = 0; i < nPagesCount; ++i)
arPages.push_back(false);
while (nCur < nLen)
{
size_t cur = nCur;
while (cur < nLen && buffer[cur] != ',')
++cur;
int nStart = 0;
int nEnd = 0;
size_t curRec = nCur;
while (curRec < cur)
{
char c = buffer[curRec++];
if (c >= '0' && c <= '9')
nStart = 10 * nStart + (c - '0');
if (c == '-')
break;
}
if (nStart == 0)
nStart = 1;
if (curRec == cur)
nEnd = nStart;
else
{
while (curRec < cur)
{
char c = buffer[curRec++];
if (c >= '0' && c <= '9')
nEnd = 10 * nEnd + (c - '0');
if (c == '-')
break;
}
if (0 == nEnd || nEnd > nPagesCount)
nEnd = nPagesCount;
}
for (int i = nStart; i <= nEnd; ++i)
arPages[i - 1] = true;
nCur = cur;
if (nCur < nLen)
++nCur;
}
return arPages;
}
_UINT32 PdfDjvuXpsToRenderer(IOfficeDrawingFile** ppReader, IRenderer* pRenderer, const std::wstring &sFrom, int nFormatFrom, const std::wstring &sTo, const std::wstring &sTemp, InputParams& params, NSFonts::IApplicationFonts* pApplicationFonts, const std::string& sPages = "")
{
_UINT32 nRes = 0;
IOfficeDrawingFile* pReader = NULL;
@ -3613,8 +3727,17 @@ namespace NExtractTools
if(bResult)
{
int nPagesCount = pReader->GetPagesCount();
bool bIsUsePages = sPages.empty() ? false : true;
std::vector<bool> arPages;
if (bIsUsePages)
arPages = getPrintPages(sPages, nPagesCount);
for (int i = 0; i < nPagesCount; ++i)
{
if (bIsUsePages && !arPages[i])
continue;
pRenderer->NewPage();
pRenderer->BeginCommand(c_nPageType);
@ -4722,6 +4845,7 @@ namespace NExtractTools
}
return nRes;
}
_UINT32 fromCrossPlatform(const std::wstring &sFrom, int nFormatFrom, const std::wstring &sTo, int nFormatTo, const std::wstring &sTemp, const std::wstring &sThemeDir, bool bPaid, InputParams& params)
{
_UINT32 nRes = 0;
@ -4729,7 +4853,9 @@ namespace NExtractTools
initApplicationFonts(pApplicationFonts, params);
if(AVS_OFFICESTUDIO_FILE_CROSSPLATFORM_PDF == nFormatTo)
{
if(nFormatFrom == nFormatTo && !params.getIsPDFA() && params.getPassword() == params.getSavePassword())
std::string sPages = checkPrintPages(params);
if(nFormatFrom == nFormatTo && !params.getIsPDFA() && params.getPassword() == params.getSavePassword() && sPages.empty())
{
NSFile::CFileBinary::Copy(sFrom, sTo);
}
@ -4748,7 +4874,7 @@ namespace NExtractTools
pdfWriter.SetPassword(password);
IOfficeDrawingFile* pReader = NULL;
nRes = PdfDjvuXpsToRenderer(&pReader, &pdfWriter, sFrom, nFormatFrom, sTo, sTemp, params, pApplicationFonts);
nRes = PdfDjvuXpsToRenderer(&pReader, &pdfWriter, sFrom, nFormatFrom, sTo, sTemp, params, pApplicationFonts, sPages);
pdfWriter.SaveToFile(sTo);
RELEASEOBJECT(pReader);
}
@ -5611,7 +5737,7 @@ namespace NExtractTools
}
//clean up v8
NSDoctRenderer::CDocBuilder::Dispose();
NSDoctRenderer::CDocBuilder::Dispose();
if (SUCCEEDED_X2T(result) && oInputParams.m_bOutputConvertCorrupted)
{
return AVS_FILEUTILS_ERROR_CONVERT_CORRUPTED;
@ -5622,6 +5748,16 @@ namespace NExtractTools
}
}
void createJSCaches()
{
NSDoctRenderer::CDocBuilder::Initialize();
NSDoctRenderer::CDoctrenderer oDoctRenderer;
oDoctRenderer.CreateCache(L"", L"");
NSDoctRenderer::CDocBuilder::Dispose();
}
_UINT32 FromFile(const std::wstring& file)
{
InputParams oInputParams;

View File

@ -228,6 +228,8 @@ namespace NExtractTools
_UINT32 fromInputParams(InputParams& oInputParams);
_UINT32 detectMacroInFile(InputParams& oInputParams);
void createJSCaches();
X2T_DECL_EXPORT _UINT32 FromFile(const std::wstring& file);
X2T_DECL_EXPORT _UINT32 FromXml(const std::wstring& xml);

View File

@ -446,6 +446,12 @@ namespace NExtractTools
oBuilder.WriteEncodeXmlString(sJsonParams);
oBuilder.WriteString(_T("</JsonParams>"));
}
if (NULL != params.m_sScriptsCacheDirectory)
{
oBuilder.WriteString(_T("<ScriptsCacheDirectory>"));
oBuilder.WriteEncodeXmlString(*params.m_sScriptsCacheDirectory);
oBuilder.WriteString(_T("</ScriptsCacheDirectory>"));
}
oBuilder.WriteString(_T("<Changes TopItem=\""));
oBuilder.AddInt(nTopIndex);
oBuilder.WriteString(_T("\">"));

View File

@ -477,6 +477,7 @@ namespace NExtractTools
boost::unordered_map<int, std::vector<InputLimit>> m_mapInputLimits;
bool* m_bIsPDFA;
std::wstring* m_sConvertToOrigin;
std::wstring* m_sScriptsCacheDirectory;
//output params
mutable bool m_bOutputConvertCorrupted;
mutable bool m_bMacro;
@ -510,6 +511,7 @@ namespace NExtractTools
m_bIsNoBase64 = NULL;
m_bIsPDFA = NULL;
m_sConvertToOrigin = NULL;
m_sScriptsCacheDirectory = NULL;
m_bOutputConvertCorrupted = false;
m_bMacro = false;
@ -543,6 +545,7 @@ namespace NExtractTools
RELEASEOBJECT(m_bIsNoBase64);
RELEASEOBJECT(m_bIsPDFA);
RELEASEOBJECT(m_sConvertToOrigin);
RELEASEOBJECT(m_sScriptsCacheDirectory);
}
bool FromXmlFile(const std::wstring& sFilename)
@ -727,6 +730,11 @@ namespace NExtractTools
RELEASEOBJECT(m_sConvertToOrigin);
m_sConvertToOrigin = new std::wstring(sValue);
}
else if (_T("m_sScriptsCacheDirectory") == sName)
{
RELEASEOBJECT(m_sScriptsCacheDirectory);
m_sScriptsCacheDirectory = new std::wstring(sValue);
}
}
else if(_T("m_nCsvDelimiterChar") == sName)
{

View File

@ -173,6 +173,11 @@ static std::wstring utf8_to_unicode(const char *src)
result = NExtractTools::detectMacroInFile(oInputParams);
}
else if (sArg1 == L"-create-js-cache")
{
NExtractTools::createJSCaches();
return 0;
}
else
{
InputParams oInputParams;

View File

@ -634,6 +634,7 @@ void CSVWriter::Impl::WriteCell(OOX::Spreadsheet::CCell *pCell)
// sCellValue = *pCell->m_oCacheValue;
//}
//else
bool bString = false;
if (pCell->m_oValue.IsInit())
{
sCellValue = pCell->m_oValue->ToString();
@ -648,42 +649,47 @@ void CSVWriter::Impl::WriteCell(OOX::Spreadsheet::CCell *pCell)
if (NULL != pSi)
{
sCellValue = pSi->ToString();
bString = true;
}
}
}
std::wstring format_code;
if (pCell->m_oStyle.IsInit() && m_oXlsx.m_pStyles)
if (!bString)
{
OOX::Spreadsheet::CXfs* xfs = m_oXlsx.m_pStyles->m_oCellXfs->m_arrItems[*pCell->m_oStyle];
if (xfs)
std::wstring format_code;
if (pCell->m_oStyle.IsInit() && m_oXlsx.m_pStyles)
{
if ((xfs->m_oApplyNumberFormat.IsInit()) && (xfs->m_oApplyNumberFormat->ToBool()) || !xfs->m_oApplyNumberFormat.IsInit())
OOX::Spreadsheet::CXfs* xfs = m_oXlsx.m_pStyles->m_oCellXfs->m_arrItems[*pCell->m_oStyle];
if (xfs)
{
if ((xfs->m_oNumFmtId.IsInit()) /*&& (xfs->m_oNumFmtId->GetValue() != 0*/)
if ((xfs->m_oApplyNumberFormat.IsInit()) && (xfs->m_oApplyNumberFormat->ToBool()) || !xfs->m_oApplyNumberFormat.IsInit())
{
int numFmt = xfs->m_oNumFmtId->GetValue();
GetDefaultFormatCode(numFmt, format_code, format_type);
if (m_oXlsx.m_pStyles->m_oNumFmts.IsInit())
if ((xfs->m_oNumFmtId.IsInit()) /*&& (xfs->m_oNumFmtId->GetValue() != 0*/)
{
std::map<unsigned int, size_t>::iterator pFind = m_oXlsx.m_pStyles->m_oNumFmts->m_mapNumFmtIndex.find(numFmt);
if (pFind != m_oXlsx.m_pStyles->m_oNumFmts->m_mapNumFmtIndex.end())
int numFmt = xfs->m_oNumFmtId->GetValue();
GetDefaultFormatCode(numFmt, format_code, format_type);
if (m_oXlsx.m_pStyles->m_oNumFmts.IsInit())
{
OOX::Spreadsheet::CNumFmt *fmt = m_oXlsx.m_pStyles->m_oNumFmts->m_arrItems[pFind->second];
if (fmt)
std::map<unsigned int, size_t>::iterator pFind = m_oXlsx.m_pStyles->m_oNumFmts->m_mapNumFmtIndex.find(numFmt);
if (pFind != m_oXlsx.m_pStyles->m_oNumFmts->m_mapNumFmtIndex.end())
{
if (fmt->m_oFormatCode.IsInit())
format_code = *fmt->m_oFormatCode;
OOX::Spreadsheet::CNumFmt *fmt = m_oXlsx.m_pStyles->m_oNumFmts->m_arrItems[pFind->second];
if (fmt)
{
if (fmt->m_oFormatCode.IsInit())
format_code = *fmt->m_oFormatCode;
}
}
}
}
}
}
}
sCellValue = ConvertValueCellToString(sCellValue, format_type, format_code);
}
sCellValue = ConvertValueCellToString(sCellValue, format_type, format_code);
}
// Escape cell value
@ -837,10 +843,9 @@ std::wstring CSVWriter::Impl::ConvertValueCellToString(const std::wstring &value
try
{
std::wstring format_code_tmp;
double dValue = XmlUtils::GetDouble(value);
int count_d = 0;
bool bFloat = false, bStart = true, bEnd = false;
bool bFloat = false, bStart = true, bEnd = false, bPercent = false;
size_t pos_skip = format_code.rfind(L"#");
if (pos_skip == std::wstring::npos) pos_skip = 0;
@ -886,7 +891,7 @@ std::wstring CSVWriter::Impl::ConvertValueCellToString(const std::wstring &value
{
if (format_code[i] == L'%')
{
dValue *= 100.;
bPercent = true;
format_code_tmp += (std::wstring(L"%") + format_code[i]);
}
else
@ -906,10 +911,26 @@ std::wstring CSVWriter::Impl::ConvertValueCellToString(const std::wstring &value
bStart = false;
}
if (!bStart && !bEnd) format_code_tmp += bFloat ? L"f" : L"d";
else
format_code_tmp += L"%";
if (!bStart && !bEnd) format_code_tmp += bFloat ? L"f" : L"ld";
double dValue = XmlUtils::GetDouble(value);
if (bPercent)
dValue *= 100.;
std::wstringstream stream;
stream << boost::wformat(format_code_tmp) % dValue;
if (bFloat)
{
stream << boost::wformat(format_code_tmp) % dValue;
}
else
{
_INT64 iValue = dValue;
stream << boost::wformat(format_code_tmp) % iValue;
}
return stream.str();
}