mirror of
https://github.com/ONLYOFFICE/core.git
synced 2026-04-07 13:55:33 +08:00
Compare commits
43 Commits
| Author | SHA1 | Date | |
|---|---|---|---|
| 51ca6f0ef2 | |||
| 5d97b35ba4 | |||
| 2bdc1e4a6d | |||
| 787379808e | |||
| 9a658a2818 | |||
| 079d80adcb | |||
| 8ec5685786 | |||
| 769ab7b238 | |||
| 2a28ba7060 | |||
| eaabba0860 | |||
| f892022232 | |||
| dfa93c344c | |||
| adfc2ef30d | |||
| f8549eaa13 | |||
| fc280b1cd6 | |||
| fc8784c540 | |||
| 17fe15948a | |||
| 38f11a9f4a | |||
| ea43991901 | |||
| a469bad6e3 | |||
| 393baf5265 | |||
| aa6dd092f7 | |||
| 00e47257e1 | |||
| 01911afb0f | |||
| fe3e7357d5 | |||
| 541c90eacf | |||
| 4641c135e7 | |||
| 5c403b39eb | |||
| 1ba6c9b73f | |||
| 2ede1b0d65 | |||
| 3e5c005714 | |||
| 217c5157e1 | |||
| 6783e79c15 | |||
| 7f3a658611 | |||
| 25a10fb642 | |||
| b59980bd62 | |||
| 213b4ddf64 | |||
| fd08ef00c3 | |||
| 85d7b5063e | |||
| ce06cd0c4c | |||
| e5e30596f0 | |||
| 0af7c8b984 | |||
| e6c7efc0d5 |
@ -96,15 +96,13 @@ namespace DocFileFormat
|
||||
std::wstring sApplication = NSSystemUtils::GetEnvVariable(NSSystemUtils::gc_EnvApplicationName);
|
||||
if (sApplication.empty())
|
||||
sApplication = NSSystemUtils::gc_EnvApplicationNameDefault;
|
||||
pApp->SetApplication(sApplication);
|
||||
|
||||
#if defined(INTVER)
|
||||
pApp->SetAppVersion(VALUE2STR(INTVER));
|
||||
std::string s = VALUE2STR(INTVER);
|
||||
sApplication += L"/" + std::wstring(s.begin(), s.end());
|
||||
#endif
|
||||
pApp->SetDocSecurity(0);
|
||||
pApp->SetScaleCrop(false);
|
||||
pApp->SetLinksUpToDate(false);
|
||||
pApp->SetSharedDoc(false);
|
||||
pApp->SetHyperlinksChanged(false);
|
||||
pApp->m_sApplication = sApplication;
|
||||
pApp->SetDefaults();
|
||||
|
||||
pApp->write(pathDocProps + FILE_SEPARATOR_STR + L"app.xml", DocProps, oContentTypes);
|
||||
delete pApp;
|
||||
|
||||
@ -1581,7 +1581,7 @@ void Binary_pPrWriter::WritePageMargin(OOX::Logic::CSectionProperty* pSectPr)
|
||||
void Binary_pPrWriter::WriteHeaderFooter(OOX::Logic::CSectionProperty* pSectPr, std::vector<ComplexTypes::Word::CHdrFtrRef*>& aRefs, bool bHdr)
|
||||
{
|
||||
int nCurPos = 0;
|
||||
for(size_t i = 0, length = aRefs.size(); i < length; ++i)
|
||||
for (size_t i = 0, length = aRefs.size(); i < length; ++i)
|
||||
{
|
||||
const ComplexTypes::Word::CHdrFtrRef& oRef = *aRefs[i];
|
||||
if( oRef.m_oType.IsInit() && oRef.m_oId.IsInit())
|
||||
@ -1589,25 +1589,12 @@ void Binary_pPrWriter::WriteHeaderFooter(OOX::Logic::CSectionProperty* pSectPr,
|
||||
int nIndex = 0;
|
||||
OOX::CHdrFtr* pHdrFtr = NULL;
|
||||
|
||||
OOX::CDocxFlat *docx_flat = dynamic_cast<OOX::CDocxFlat*>(m_oBinaryHeaderFooterTableWriter->m_oParamsWriter.m_pMain);
|
||||
smart_ptr<OOX::File> oFile = m_oBinaryHeaderFooterTableWriter->m_oDocumentRelsWriter->Find(oRef.m_oId->GetValue());
|
||||
if (oFile.IsInit() && (OOX::FileTypes::Header == oFile->type() || OOX::FileTypes::Footer == oFile->type()))
|
||||
{
|
||||
pHdrFtr = (OOX::CHdrFtr*)oFile.GetPointer();
|
||||
}
|
||||
|
||||
if (docx_flat)
|
||||
{
|
||||
std::map<std::wstring, OOX::CHdrFtr*>::iterator pFind = docx_flat->m_mapHeadersFooters.find(oRef.m_oId->GetValue());
|
||||
if (pFind != docx_flat->m_mapHeadersFooters.end())
|
||||
{
|
||||
pHdrFtr = pFind->second;
|
||||
}
|
||||
}
|
||||
else
|
||||
{
|
||||
smart_ptr<OOX::File> oFile = m_oBinaryHeaderFooterTableWriter->m_oDocumentRelsWriter->Find(oRef.m_oId->GetValue());
|
||||
if (oFile.IsInit() && (OOX::FileTypes::Header == oFile->type() || OOX::FileTypes::Footer == oFile->type()))
|
||||
{
|
||||
pHdrFtr = (OOX::CHdrFtr*)oFile.GetPointer();
|
||||
}
|
||||
}
|
||||
|
||||
if (pHdrFtr)
|
||||
{
|
||||
if(bHdr)
|
||||
@ -9251,7 +9238,7 @@ void BinaryFileWriter::intoBindoc(const std::wstring& sDir)
|
||||
if ((pDocxFlat) && (pDocxFlat->m_pDocument.IsInit()))
|
||||
{
|
||||
pDocument = pDocxFlat->m_pDocument.GetPointer();
|
||||
pComments = &pDocxFlat->m_oComments;
|
||||
pComments = pDocxFlat->m_pComments.GetPointer();
|
||||
|
||||
m_oParamsWriter.m_pSettings = pDocxFlat->m_pSettings.GetPointer();
|
||||
m_oParamsWriter.m_pStyles = pDocxFlat->m_pStyles.GetPointer();
|
||||
@ -9378,7 +9365,7 @@ void BinaryFileWriter::intoBindoc(const std::wstring& sDir)
|
||||
}
|
||||
else if (pDocxFlat)
|
||||
{
|
||||
oBinaryDocumentTableWriter.pBackground = dynamic_cast<OOX::WritingElement*>(pDocxFlat->m_oBgPict.GetPointer());
|
||||
oBinaryDocumentTableWriter.pBackground = dynamic_cast<OOX::WritingElement*>(pDocxFlat->m_pBgPict.GetPointer());
|
||||
}
|
||||
|
||||
// Write content
|
||||
|
||||
@ -48,6 +48,8 @@
|
||||
#include "../../Common/DocxFormat/Source/DocxFormat/HeaderFooter.h"
|
||||
#include "../../Common/DocxFormat/Source/DocxFormat/App.h"
|
||||
#include "../../Common/DocxFormat/Source/DocxFormat/Core.h"
|
||||
#include "../../Common/DocxFormat/Source/DocxFormat/Footnote.h"
|
||||
#include "../../Common/DocxFormat/Source/DocxFormat/Endnote.h"
|
||||
|
||||
namespace NSBinPptxRW
|
||||
{
|
||||
|
||||
@ -48,6 +48,8 @@
|
||||
|
||||
#include "../../Common/DocxFormat/Source/DocxFormat/App.h"
|
||||
#include "../../Common/DocxFormat/Source/DocxFormat/Core.h"
|
||||
#include "../../Common/DocxFormat/Source/DocxFormat/Endnote.h"
|
||||
#include "../../Common/DocxFormat/Source/DocxFormat/Footnote.h"
|
||||
|
||||
int BinDocxRW::g_nCurFormatVersion = 0;
|
||||
|
||||
@ -610,3 +612,32 @@ bool BinDocxRW::CDocxSerializer::unpackageFile(const std::wstring& sSrcFileName,
|
||||
|
||||
return file.unpackage(sSrcFileName, sDstPath);
|
||||
}
|
||||
bool BinDocxRW::CDocxSerializer::convertFlat(const std::wstring& sSrcFileName, const std::wstring& sDstPath)
|
||||
{
|
||||
OOX::CDocxFlat docxflat(sSrcFileName);
|
||||
|
||||
if (false == docxflat.m_pDocument.IsInit())
|
||||
return false;
|
||||
|
||||
OOX::CDocx docx;
|
||||
|
||||
if (docxflat.m_pDocument.IsInit())
|
||||
{
|
||||
NSCommon::smart_ptr<OOX::File> file = docxflat.m_pDocument.GetPointer(); file.AddRef();
|
||||
docx.Add(file);
|
||||
docx.m_oMain.document = docxflat.m_pDocument.GetPointer();
|
||||
}
|
||||
if (docxflat.m_pApp.IsInit())
|
||||
{
|
||||
NSCommon::smart_ptr<OOX::File> file(docxflat.m_pApp.GetPointer()); file.AddRef();
|
||||
docx.Add(file);
|
||||
}
|
||||
if (docxflat.m_pCore.IsInit())
|
||||
{
|
||||
NSCommon::smart_ptr<OOX::File> file(docxflat.m_pCore.GetPointer()); file.AddRef();
|
||||
docx.Add(file);
|
||||
}
|
||||
//docxflat.m_oBgPict.GetPointer();
|
||||
|
||||
return docx.Write(sDstPath);
|
||||
}
|
||||
|
||||
@ -66,6 +66,7 @@ namespace BinDocxRW
|
||||
bool saveToFile (const std::wstring& sSrcFileName, const std::wstring& sDstPath, const std::wstring& sXMLOptions, const std::wstring& sTempPath);
|
||||
|
||||
bool unpackageFile(const std::wstring& sSrcFileName, const std::wstring& sDstPath);
|
||||
bool convertFlat(const std::wstring& sSrcFileName, const std::wstring& sDstPath);
|
||||
|
||||
bool CreateDocxFolders(std::wstring strDirectory, std::wstring& sThemePath, std::wstring& sMediaPath, std::wstring& sEmbedPath);
|
||||
|
||||
|
||||
@ -56,6 +56,7 @@
|
||||
#include "../../../Common/DocxFormat/Source/DocxFormat/Logic/Vml.h"
|
||||
#include "../../../Common/DocxFormat/Source/DocxFormat/Diagram/DiagramDrawing.h"
|
||||
#include "../../../Common/DocxFormat/Source/DocxFormat/Diagram/DiagramData.h"
|
||||
#include "../../../Common/DocxFormat/Source/DocxFormat/Math/oMathPara.h"
|
||||
|
||||
#include "../../../ASCOfficePPTXFile/PPTXFormat/Logic/Shape.h"
|
||||
#include "../../../ASCOfficePPTXFile/PPTXFormat/Logic/CxnSp.h"
|
||||
|
||||
@ -35,6 +35,8 @@
|
||||
#include "../../../Common/DocxFormat/Source/DocxFormat/Docx.h"
|
||||
#include "../../../Common/DocxFormat/Source/DocxFormat/DocxFlat.h"
|
||||
#include "../../../Common/DocxFormat/Source/DocxFormat/Document.h"
|
||||
#include "../../../Common/DocxFormat/Source/DocxFormat/Endnote.h"
|
||||
#include "../../../Common/DocxFormat/Source/DocxFormat/Footnote.h"
|
||||
#include "../../../Common/DocxFormat/Source/DocxFormat/FontTable.h"
|
||||
#include "../../../Common/DocxFormat/Source/DocxFormat/Numbering.h"
|
||||
#include "../../../Common/DocxFormat/Source/DocxFormat/Styles.h"
|
||||
@ -1972,7 +1974,7 @@ void DocxConverter::convert(OOX::Logic::CSectionProperty *oox_section_pr, bool b
|
||||
}
|
||||
else if (docx_flat_document)
|
||||
{
|
||||
convert(docx_flat_document->m_oBgPict.GetPointer(), 1);
|
||||
convert(docx_flat_document->m_pBgPict.GetPointer(), 1);
|
||||
}
|
||||
//nullable<ComplexTypes::Word::CTextDirection > m_oTextDirection;
|
||||
//nullable<ComplexTypes::Word::COnOff2<SimpleTypes::onoffTrue> > m_oRtlGutter;
|
||||
@ -4176,7 +4178,7 @@ void DocxConverter::convert_comment(int oox_comm_id)
|
||||
}
|
||||
else if (docx_flat_document)
|
||||
{
|
||||
pComments = &docx_flat_document->m_oComments;
|
||||
pComments = docx_flat_document->m_pComments.GetPointer();
|
||||
}
|
||||
|
||||
if (!pComments) return;
|
||||
@ -4221,7 +4223,7 @@ void DocxConverter::convert_footnote(int oox_ref_id)
|
||||
}
|
||||
else if (docx_flat_document)
|
||||
{
|
||||
oox_footnotes = &docx_flat_document->m_oFootnotes;
|
||||
oox_footnotes = docx_flat_document->m_pFootnotes.GetPointer();
|
||||
}
|
||||
if (oox_footnotes == NULL ) return;
|
||||
|
||||
@ -4259,7 +4261,7 @@ void DocxConverter::convert_endnote(int oox_ref_id)
|
||||
}
|
||||
else if (docx_flat_document)
|
||||
{
|
||||
oox_endnotes = &docx_flat_document->m_oEndnotes;
|
||||
oox_endnotes = docx_flat_document->m_pEndnotes.GetPointer();
|
||||
}
|
||||
if (oox_endnotes == NULL ) return;
|
||||
|
||||
@ -4297,11 +4299,7 @@ void DocxConverter::convert_hdr_ftr(std::wstring sId)
|
||||
}
|
||||
else if (docx_flat_document)
|
||||
{
|
||||
std::map<std::wstring, OOX::CHdrFtr*>::iterator pFind = docx_flat_document->m_mapHeadersFooters.find(sId);
|
||||
if (pFind != docx_flat_document->m_mapHeadersFooters.end())
|
||||
{
|
||||
oox_hdr_ftr = pFind->second;
|
||||
}
|
||||
oox_hdr_ftr = docx_flat_document->GetHeaderOrFooter(sId);
|
||||
}
|
||||
if (oox_hdr_ftr == NULL ) return;
|
||||
|
||||
|
||||
@ -1,17 +1,48 @@
|
||||
#include "Converter.h"
|
||||
/*
|
||||
* (c) Copyright Ascensio System SIA 2010-2019
|
||||
*
|
||||
* This program is a free software product. You can redistribute it and/or
|
||||
* modify it under the terms of the GNU Affero General Public License (AGPL)
|
||||
* version 3 as published by the Free Software Foundation. In accordance with
|
||||
* Section 7(a) of the GNU AGPL its Section 15 shall be amended to the effect
|
||||
* that Ascensio System SIA expressly excludes the warranty of non-infringement
|
||||
* of any third-party rights.
|
||||
*
|
||||
* This program is distributed WITHOUT ANY WARRANTY; without even the implied
|
||||
* warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. For
|
||||
* details, see the GNU AGPL at: http://www.gnu.org/licenses/agpl-3.0.html
|
||||
*
|
||||
* You can contact Ascensio System SIA at 20A-12 Ernesta Birznieka-Upisha
|
||||
* street, Riga, Latvia, EU, LV-1050.
|
||||
*
|
||||
* The interactive user interfaces in modified source and object code versions
|
||||
* of the Program must display Appropriate Legal Notices, as required under
|
||||
* Section 5 of the GNU AGPL version 3.
|
||||
*
|
||||
* Pursuant to Section 7(b) of the License you must retain the original Product
|
||||
* logo when distributing the program. Pursuant to Section 7(e) we decline to
|
||||
* grant you any rights under trademark law for use of our trademarks.
|
||||
*
|
||||
* All the Product's GUI elements, including illustrations and icon sets, as
|
||||
* well as technical writing content are licensed under the terms of the
|
||||
* Creative Commons Attribution-ShareAlike 4.0 International. See the License
|
||||
* terms at http://creativecommons.org/licenses/by-sa/4.0/legalcode
|
||||
*
|
||||
*/
|
||||
|
||||
//#include "../utils.h"
|
||||
#include "Converter.h"
|
||||
|
||||
#include "../../../Common/DocxFormat/Source/DocxFormat/DocxFlat.h"
|
||||
#include "../../../Common/DocxFormat/Source/DocxFormat/Math/oMathPara.h"
|
||||
|
||||
|
||||
#include "../OdfFormat/odf_conversion_context.h"
|
||||
#include "../../ASCOfficeOdfFileW/source/OdfFormat/math_layout_elements.h"
|
||||
#include "../../ASCOfficeOdfFileW/source/OdfFormat/math_limit_elements.h"
|
||||
#include "../../ASCOfficeOdfFileW/source/OdfFormat/math_token_elements.h"
|
||||
#include <set>
|
||||
#include <vector>
|
||||
#include <fstream>
|
||||
#include <string>
|
||||
|
||||
namespace Oox2Odf
|
||||
{
|
||||
std::vector<std::vector<std::wstring>>& OoxConverter::brackets()
|
||||
|
||||
@ -30,8 +30,6 @@
|
||||
*
|
||||
*/
|
||||
#pragma once
|
||||
#ifndef PPTX_APP_FILE_INCLUDE_H_
|
||||
#define PPTX_APP_FILE_INCLUDE_H_
|
||||
|
||||
#include "WrapperFile.h"
|
||||
#include "FileTypes.h"
|
||||
@ -366,5 +364,3 @@ namespace PPTX
|
||||
}
|
||||
};
|
||||
} // namespace PPTX
|
||||
|
||||
#endif // PPTX_APP_FILE_INCLUDE_H_
|
||||
|
||||
@ -30,8 +30,6 @@
|
||||
*
|
||||
*/
|
||||
#pragma once
|
||||
#ifndef PPTX_CORE_FILE_INCLUDE_H_
|
||||
#define PPTX_CORE_FILE_INCLUDE_H_
|
||||
|
||||
#include "WrapperFile.h"
|
||||
#include "../../Common/DocxFormat/Source/DocxFormat/WritingElement.h"
|
||||
@ -270,5 +268,3 @@ namespace PPTX
|
||||
nullable_string version;
|
||||
};
|
||||
} // namespace PPTX
|
||||
|
||||
#endif // PPTX_CORE_FILE_INCLUDE_H_
|
||||
|
||||
@ -49,30 +49,28 @@ public:
|
||||
|
||||
if(m_ooxApp->m_nTotalTime.IsInit())
|
||||
{
|
||||
oParam.oRtf->m_oInformation.m_nEndingTime = m_ooxApp->m_nTotalTime.get2();
|
||||
oParam.oRtf->m_oInformation.m_nEndingTime = m_ooxApp->m_nTotalTime.get();
|
||||
}
|
||||
if(m_ooxApp->m_nPages.IsInit())
|
||||
{
|
||||
oParam.oRtf->m_oInformation.m_nNumberOfPages = m_ooxApp->m_nPages.get2();
|
||||
oParam.oRtf->m_oInformation.m_nNumberOfPages = m_ooxApp->m_nPages.get();
|
||||
}
|
||||
if(m_ooxApp->m_nWords.IsInit())
|
||||
{
|
||||
oParam.oRtf->m_oInformation.m_nNumberOfWords = m_ooxApp->m_nWords.get2();
|
||||
oParam.oRtf->m_oInformation.m_nNumberOfWords = m_ooxApp->m_nWords.get();
|
||||
}
|
||||
if(m_ooxApp->m_nCharacters.IsInit())
|
||||
{
|
||||
oParam.oRtf->m_oInformation.m_nNumberOfCharactersWithoutSpace = m_ooxApp->m_nCharacters.get2();
|
||||
oParam.oRtf->m_oInformation.m_nNumberOfCharactersWithoutSpace = m_ooxApp->m_nCharacters.get();
|
||||
}
|
||||
if(m_ooxApp->m_nCharactersWithSpaces.IsInit())
|
||||
{
|
||||
oParam.oRtf->m_oInformation.m_nNumberOfCharactersWithSpace = m_ooxApp->m_nCharactersWithSpaces.get2();
|
||||
oParam.oRtf->m_oInformation.m_nNumberOfCharactersWithSpace = m_ooxApp->m_nCharactersWithSpaces.get();
|
||||
}
|
||||
|
||||
if (m_ooxApp->m_sApplication.IsInit())
|
||||
{
|
||||
oParam.oRtf->m_oInformation.m_sApplication = m_ooxApp->m_sApplication.get2();
|
||||
oParam.oRtf->m_oInformation.m_sApplication = m_ooxApp->m_sApplication.get();
|
||||
}
|
||||
|
||||
return true;
|
||||
}
|
||||
};
|
||||
|
||||
@ -49,23 +49,23 @@ public:
|
||||
|
||||
if (m_ooxCore->m_sTitle.IsInit())
|
||||
{
|
||||
oParam.oRtf->m_oInformation.m_sTitle = m_ooxCore->m_sTitle.get2();
|
||||
oParam.oRtf->m_oInformation.m_sTitle = m_ooxCore->m_sTitle.get();
|
||||
}
|
||||
if (m_ooxCore->m_sSubject.IsInit())
|
||||
{
|
||||
oParam.oRtf->m_oInformation.m_sSubject = m_ooxCore->m_sSubject.get2();
|
||||
oParam.oRtf->m_oInformation.m_sSubject = m_ooxCore->m_sSubject.get();
|
||||
}
|
||||
if (m_ooxCore->m_sCreator.IsInit())
|
||||
{
|
||||
oParam.oRtf->m_oInformation.m_sAuthor = m_ooxCore->m_sCreator.get2();
|
||||
oParam.oRtf->m_oInformation.m_sAuthor = m_ooxCore->m_sCreator.get();
|
||||
}
|
||||
if (m_ooxCore->m_sDescription.IsInit())
|
||||
{
|
||||
oParam.oRtf->m_oInformation.m_sComment = m_ooxCore->m_sDescription.get2();
|
||||
oParam.oRtf->m_oInformation.m_sComment = m_ooxCore->m_sDescription.get();
|
||||
}
|
||||
if (m_ooxCore->m_sKeywords.IsInit())
|
||||
{
|
||||
oParam.oRtf->m_oInformation.m_sKeywords = m_ooxCore->m_sKeywords.get2();
|
||||
oParam.oRtf->m_oInformation.m_sKeywords = m_ooxCore->m_sKeywords.get();
|
||||
}
|
||||
return true;
|
||||
}
|
||||
|
||||
@ -81,11 +81,7 @@ OOXWriter::OOXWriter( RtfDocument& oDocument, std::wstring sPath ) :
|
||||
|
||||
if (m_poDocPropsApp)
|
||||
{
|
||||
((OOX::CApp*)m_poDocPropsApp)->SetDocSecurity(0);
|
||||
((OOX::CApp*)m_poDocPropsApp)->SetScaleCrop(false);
|
||||
((OOX::CApp*)m_poDocPropsApp)->SetLinksUpToDate(false);
|
||||
((OOX::CApp*)m_poDocPropsApp)->SetSharedDoc(false);
|
||||
((OOX::CApp*)m_poDocPropsApp)->SetHyperlinksChanged(false);
|
||||
((OOX::CApp*)m_poDocPropsApp)->SetDefaults();
|
||||
}
|
||||
if (m_poDocPropsCore)
|
||||
{
|
||||
@ -170,10 +166,11 @@ bool OOXWriter::SaveByItemEnd()
|
||||
std::wstring sApplication = NSSystemUtils::GetEnvVariable(NSSystemUtils::gc_EnvApplicationName);
|
||||
if (sApplication.empty())
|
||||
sApplication = NSSystemUtils::gc_EnvApplicationNameDefault;
|
||||
((OOX::CApp*)m_poDocPropsApp)->SetApplication ( sApplication );
|
||||
#if defined(INTVER)
|
||||
((OOX::CApp*)m_poDocPropsApp)->SetAppVersion ( VALUE2STR(INTVER) );
|
||||
std::string s = VALUE2STR(INTVER);
|
||||
sApplication += L"/" + std::wstring(s.begin(), s.end());
|
||||
#endif
|
||||
((OOX::CApp*)m_poDocPropsApp)->m_sApplication = sApplication;
|
||||
((OOX::CApp*)m_poDocPropsApp)->write(pathDocProps + FILE_SEPARATOR_STR + L"app.xml", pathDocProps.GetDirectory(), oContentTypes);
|
||||
|
||||
m_oRels.AddRelationship( L"http://schemas.openxmlformats.org/officeDocument/2006/relationships/extended-properties", L"docProps/app.xml" );
|
||||
|
||||
@ -204,15 +204,12 @@ void CTxtXmlFile::CreateDocxEmpty(const std::wstring & _strDirectory, Writers::F
|
||||
std::wstring sApplication = NSSystemUtils::GetEnvVariable(NSSystemUtils::gc_EnvApplicationName);
|
||||
if (sApplication.empty())
|
||||
sApplication = NSSystemUtils::gc_EnvApplicationNameDefault;
|
||||
pApp->SetApplication(sApplication);
|
||||
#if defined(INTVER)
|
||||
pApp->SetAppVersion(VALUE2STR(INTVER));
|
||||
std::string s = VALUE2STR(INTVER);
|
||||
sApplication += L"/" + std::wstring(s.begin(), s.end());
|
||||
#endif
|
||||
pApp->SetDocSecurity(0);
|
||||
pApp->SetScaleCrop(false);
|
||||
pApp->SetLinksUpToDate(false);
|
||||
pApp->SetSharedDoc(false);
|
||||
pApp->SetHyperlinksChanged(false);
|
||||
pApp->m_sApplication = sApplication;
|
||||
pApp->SetDefaults();
|
||||
|
||||
pApp->write(pathDocProps + FILE_SEPARATOR_STR + _T("app.xml"), DocProps, oContentTypes);
|
||||
delete pApp;
|
||||
|
||||
@ -127,12 +127,10 @@ bool PropertyDTM::Read (XLS::CFStreamPtr stream)
|
||||
}
|
||||
std::wstring PropertyDTM::toString()
|
||||
{
|
||||
#ifdef _WIN32
|
||||
boost::winapi::FILETIME_ ft;
|
||||
ft.dwHighDateTime = dwHighDateTime;
|
||||
ft.dwLowDateTime = dwLowDateTime;
|
||||
_UINT64 temp = ((_UINT64)dwHighDateTime << 32) + dwLowDateTime;
|
||||
|
||||
boost::posix_time::ptime date_time_ = boost::posix_time::from_ftime<boost::posix_time::ptime>(ft);
|
||||
boost::posix_time::ptime daysFrom1601(boost::gregorian::date(1601, 1, 1));
|
||||
boost::posix_time::ptime date_time_ = daysFrom1601 + boost::posix_time::milliseconds(temp / 10000);
|
||||
|
||||
short Min = (short)date_time_.time_of_day().minutes();
|
||||
short Hour = (short)date_time_.time_of_day().hours();
|
||||
@ -151,9 +149,6 @@ std::wstring PropertyDTM::toString()
|
||||
value += (Hour < 10 ? L"0" : L"") + std::to_wstring(Hour) + L":" +
|
||||
(Min < 10 ? L"0" : L"") + std::to_wstring(Min) + L":00Z";
|
||||
return value;
|
||||
#else
|
||||
return L"";
|
||||
#endif
|
||||
}
|
||||
//-------------------------------------------------------------------
|
||||
bool PropertyInt::Read (XLS::CFStreamPtr stream)
|
||||
|
||||
@ -343,6 +343,7 @@ namespace OLEPS
|
||||
|
||||
std::wstringstream output;
|
||||
PropertyPtr prop;
|
||||
std::wstring value;
|
||||
|
||||
CP_XML_WRITER(output)
|
||||
{
|
||||
@ -355,110 +356,123 @@ namespace OLEPS
|
||||
CP_XML_ATTR(L"xmlns:xsi", L"http://www.w3.org/2001/XMLSchema-instance");
|
||||
|
||||
prop = GetProperty(TITLE);
|
||||
if (prop)
|
||||
value = prop ? prop->toString() : L"";
|
||||
if (!value.empty())
|
||||
{
|
||||
CP_XML_NODE(L"dc:title")
|
||||
{
|
||||
CP_XML_CONTENT(prop->toString());
|
||||
CP_XML_CONTENT(value);
|
||||
}
|
||||
}
|
||||
prop = GetProperty(SUBJECT);
|
||||
if (prop)
|
||||
value = prop ? prop->toString() : L"";
|
||||
if (!value.empty())
|
||||
{
|
||||
CP_XML_NODE(L"dc:subject")
|
||||
{
|
||||
CP_XML_CONTENT(prop->toString());
|
||||
CP_XML_CONTENT(value);
|
||||
}
|
||||
}
|
||||
prop = GetProperty(AUTHOR);
|
||||
if (prop)
|
||||
value = prop ? prop->toString() : L"";
|
||||
if (!value.empty())
|
||||
{
|
||||
CP_XML_NODE(L"dc:creator")
|
||||
{
|
||||
CP_XML_CONTENT(prop->toString());
|
||||
CP_XML_CONTENT(value);
|
||||
}
|
||||
}
|
||||
prop = GetProperty(KEYWORDS);
|
||||
if (prop)
|
||||
value = prop ? prop->toString() : L"";
|
||||
if (!value.empty())
|
||||
{
|
||||
CP_XML_NODE(L"cp:keywords")
|
||||
{
|
||||
CP_XML_CONTENT(prop->toString());
|
||||
CP_XML_CONTENT(value);
|
||||
}
|
||||
}
|
||||
prop = GetProperty(COMMENTS);
|
||||
if (prop)
|
||||
value = prop ? prop->toString() : L"";
|
||||
if (!value.empty())
|
||||
{
|
||||
CP_XML_NODE(L"dc:description")
|
||||
{
|
||||
CP_XML_CONTENT(prop->toString());
|
||||
CP_XML_CONTENT(value);
|
||||
}
|
||||
}
|
||||
prop = GetProperty(LANGUAGE);
|
||||
if (prop)
|
||||
value = prop ? prop->toString() : L"";
|
||||
if (!value.empty())
|
||||
{
|
||||
CP_XML_NODE(L"dc:language")
|
||||
{
|
||||
CP_XML_STREAM() << prop->toString();
|
||||
CP_XML_STREAM() << value;
|
||||
}
|
||||
}
|
||||
prop = GetProperty(VERSION);
|
||||
if (prop)
|
||||
value = prop ? prop->toString() : L"";
|
||||
if (!value.empty())
|
||||
{
|
||||
CP_XML_NODE(L"cp:version")
|
||||
{
|
||||
CP_XML_STREAM() << prop->toString();
|
||||
CP_XML_STREAM() << value;
|
||||
}
|
||||
}
|
||||
prop = GetProperty(LASTAUTHOR);
|
||||
if (prop)
|
||||
value = prop ? prop->toString() : L"";
|
||||
if (!value.empty())
|
||||
{
|
||||
CP_XML_NODE(L"cp:lastModifiedBy")
|
||||
{
|
||||
CP_XML_CONTENT(prop->toString());
|
||||
CP_XML_CONTENT(value);
|
||||
}
|
||||
}
|
||||
prop = GetProperty(REVNUMBER);
|
||||
if (prop)
|
||||
value = prop ? prop->toString() : L"";
|
||||
if (!value.empty())
|
||||
{
|
||||
unsigned int val = XmlUtils::GetUInteger(prop->toString());
|
||||
unsigned int val = XmlUtils::GetUInteger(value);
|
||||
CP_XML_NODE(L"cp:revision")
|
||||
{
|
||||
CP_XML_STREAM() << val;
|
||||
}
|
||||
}
|
||||
prop = GetProperty(CREATE_DTM);
|
||||
if (prop)
|
||||
value = prop ? prop->toString() : L"";
|
||||
if (!value.empty())
|
||||
{
|
||||
CP_XML_NODE(L"dcterms:created")
|
||||
{
|
||||
CP_XML_ATTR(L"xsi:type", L"dcterms:W3CDTF");
|
||||
CP_XML_STREAM() << prop->toString();
|
||||
CP_XML_STREAM() << value;
|
||||
}
|
||||
}
|
||||
prop = GetProperty(LASTSAVE_DTM);
|
||||
if (prop)
|
||||
value = prop ? prop->toString() : L"";
|
||||
if (!value.empty())
|
||||
{
|
||||
CP_XML_NODE(L"dcterms:modified")
|
||||
{
|
||||
CP_XML_ATTR(L"xsi:type", L"dcterms:W3CDTF");
|
||||
CP_XML_STREAM() << prop->toString();
|
||||
CP_XML_STREAM() << value;
|
||||
}
|
||||
}
|
||||
prop = GetProperty(CATEGORY);
|
||||
if (prop)
|
||||
value = prop ? prop->toString() : L"";
|
||||
if (!value.empty())
|
||||
{
|
||||
CP_XML_NODE(L"cp:category")
|
||||
{
|
||||
CP_XML_CONTENT(prop->toString());
|
||||
CP_XML_CONTENT(value);
|
||||
}
|
||||
}
|
||||
prop = GetProperty(CONTENTSTATUS);
|
||||
if (prop)
|
||||
value = prop ? prop->toString() : L"";
|
||||
if (!value.empty())
|
||||
{
|
||||
CP_XML_NODE(L"cp:contentStatus")
|
||||
{
|
||||
CP_XML_STREAM() << prop->toString();
|
||||
CP_XML_STREAM() << value;
|
||||
}
|
||||
}
|
||||
// BYTECOUNT = 0x1004,
|
||||
|
||||
@ -46,6 +46,7 @@ SOURCES += \
|
||||
../Source/DocxFormat/Logic/TableProperty.cpp \
|
||||
../Source/DocxFormat/Logic/Vml.cpp \
|
||||
../Source/DocxFormat/Logic/DocParts.cpp \
|
||||
../Source/DocxFormat/Logic/Pict.cpp \
|
||||
../Source/DocxFormat/Media/Media.cpp \
|
||||
../Source/DocxFormat/Media/VbaProject.cpp \
|
||||
../Source/DocxFormat/Media/JsaProject.cpp \
|
||||
|
||||
@ -48,6 +48,7 @@
|
||||
#include "../Source/DocxFormat/Logic/Table.cpp"
|
||||
#include "../Source/DocxFormat/Logic/TableProperty.cpp"
|
||||
#include "../Source/DocxFormat/Logic/Vml.cpp"
|
||||
#include "../Source/DocxFormat/Logic/Pict.cpp"
|
||||
#include "../Source/DocxFormat/Math/oMath.cpp"
|
||||
#include "../Source/DocxFormat/Math/oMathContent.cpp"
|
||||
#include "../Source/DocxFormat/Math/oMathPara.cpp"
|
||||
|
||||
@ -441,7 +441,7 @@
|
||||
<AdditionalOptions Condition="'$(Configuration)|$(Platform)'=='Debug|x64'">/bigobj %(AdditionalOptions)</AdditionalOptions>
|
||||
</ClCompile>
|
||||
<ClCompile Include="..\Source\DocxFormat\DocxFlat.cpp">
|
||||
<AdditionalOptions Condition="'$(Configuration)|$(Platform)'=='Debug|Win32'">/bigbj %(AdditionalOptions)</AdditionalOptions>
|
||||
<AdditionalOptions Condition="'$(Configuration)|$(Platform)'=='Debug|Win32'">/bigobj %(AdditionalOptions)</AdditionalOptions>
|
||||
<AdditionalOptions Condition="'$(Configuration)|$(Platform)'=='Debug|x64'">/bigobj %(AdditionalOptions)</AdditionalOptions>
|
||||
</ClCompile>
|
||||
<ClCompile Include="..\Source\DocxFormat\Drawing\DrawingExt.cpp" />
|
||||
@ -503,6 +503,7 @@
|
||||
<AdditionalOptions Condition="'$(Configuration)|$(Platform)'=='Release|x64'">/bigobj %(AdditionalOptions)</AdditionalOptions>
|
||||
<ObjectFileName Condition="'$(Configuration)|$(Platform)'=='Release|x64'">$(IntDir)</ObjectFileName>
|
||||
</ClCompile>
|
||||
<ClCompile Include="..\Source\DocxFormat\Logic\Pict.cpp" />
|
||||
<ClCompile Include="..\Source\DocxFormat\Logic\Run.cpp" />
|
||||
<ClCompile Include="..\Source\DocxFormat\Logic\RunProperty.cpp">
|
||||
<ObjectFileName Condition="'$(Configuration)|$(Platform)'=='Debug|Win32'">$(IntDir)%(Filename)1.obj</ObjectFileName>
|
||||
|
||||
@ -55,9 +55,6 @@
|
||||
<Filter Include="Logic\Paragraph and Runs\Run">
|
||||
<UniqueIdentifier>{cbb6ec77-d12a-43d6-b00a-2fda08d2fddf}</UniqueIdentifier>
|
||||
</Filter>
|
||||
<Filter Include="Logic\Paragraph and Runs\Run\Pict">
|
||||
<UniqueIdentifier>{8c368f54-4b99-4d0d-941a-5bfe81569746}</UniqueIdentifier>
|
||||
</Filter>
|
||||
<Filter Include="Logic\Annotations">
|
||||
<UniqueIdentifier>{1614473a-b1cf-48ef-a43e-ff606ee27c9d}</UniqueIdentifier>
|
||||
</Filter>
|
||||
@ -880,5 +877,8 @@
|
||||
<ClCompile Include="..\Source\XlsxFormat\Workbook\Workbook.cpp">
|
||||
<Filter>XlsxFormat\Workbook</Filter>
|
||||
</ClCompile>
|
||||
<ClCompile Include="..\Source\DocxFormat\Logic\Pict.cpp">
|
||||
<Filter>Logic\Drawing</Filter>
|
||||
</ClCompile>
|
||||
</ItemGroup>
|
||||
</Project>
|
||||
@ -30,8 +30,6 @@
|
||||
*
|
||||
*/
|
||||
#pragma once
|
||||
#ifndef OOX_APP_INCLUDE_H_
|
||||
#define OOX_APP_INCLUDE_H_
|
||||
|
||||
#include "Docx.h"
|
||||
#include "File.h"
|
||||
@ -70,112 +68,64 @@ namespace OOX
|
||||
m_sAppVersion = oItem.GetText();
|
||||
|
||||
if ( oProperties.GetNode( _T("Characters"), oItem ) )
|
||||
{
|
||||
SimpleTypes::CDecimalNumber<> oNum = oItem.GetText();
|
||||
m_nCharacters = oNum.GetValue();
|
||||
}
|
||||
m_nCharacters = oItem.GetText();
|
||||
|
||||
if ( oProperties.GetNode( _T("CharactersWithSpaces"), oItem ) )
|
||||
{
|
||||
SimpleTypes::CDecimalNumber<> oNum = oItem.GetText();
|
||||
m_nCharactersWithSpaces = oNum.GetValue();
|
||||
}
|
||||
m_nCharactersWithSpaces = oItem.GetText();
|
||||
|
||||
if ( oProperties.GetNode( _T("Company"), oItem ) )
|
||||
m_sCompany = oItem.GetText();
|
||||
|
||||
if ( oProperties.GetNode( _T("DocSecurity"), oItem ) )
|
||||
{
|
||||
SimpleTypes::CDecimalNumber<> oNum = oItem.GetText();
|
||||
m_nDocSecurity = oNum.GetValue();
|
||||
}
|
||||
m_nDocSecurity = oItem.GetText();
|
||||
|
||||
if ( oProperties.GetNode( _T("HiddenSlides"), oItem ) )
|
||||
{
|
||||
SimpleTypes::CDecimalNumber<> oNum = oItem.GetText();
|
||||
m_nHiddenSlides = oNum.GetValue();
|
||||
}
|
||||
m_nHiddenSlides = oItem.GetText();
|
||||
|
||||
if ( oProperties.GetNode( _T("HyperlinkBase"), oItem ) )
|
||||
m_sHyperlinkBase = oItem.GetText();
|
||||
|
||||
if ( oProperties.GetNode( _T("HyperlinksChanged"), oItem ) )
|
||||
{
|
||||
SimpleTypes::COnOff<> oBool = oItem.GetText();
|
||||
m_bHyperlinksChanged = (oBool.GetValue() == SimpleTypes::onoffTrue);
|
||||
}
|
||||
m_bHyperlinksChanged = oItem.GetText();
|
||||
|
||||
if ( oProperties.GetNode( _T("Lines"), oItem ) )
|
||||
{
|
||||
SimpleTypes::CDecimalNumber<> oNum = oItem.GetText();
|
||||
m_nLines = oNum.GetValue();
|
||||
}
|
||||
m_nLines = oItem.GetText();
|
||||
|
||||
if ( oProperties.GetNode( _T("LinksUpToDate"), oItem ) )
|
||||
{
|
||||
SimpleTypes::COnOff<> oBool = oItem.GetText();
|
||||
m_bLinksUpToDate = (oBool.GetValue() == SimpleTypes::onoffTrue);
|
||||
}
|
||||
m_bLinksUpToDate = oItem.GetText();
|
||||
|
||||
if ( oProperties.GetNode( _T("Manager"), oItem ) )
|
||||
m_sManager = oItem.GetText();
|
||||
|
||||
if ( oProperties.GetNode( _T("MMClips"), oItem ) )
|
||||
{
|
||||
SimpleTypes::CDecimalNumber<> oNum = oItem.GetText();
|
||||
m_nMMClips = oNum.GetValue();
|
||||
}
|
||||
m_nMMClips = oItem.GetText();
|
||||
|
||||
if ( oProperties.GetNode( _T("Notes"), oItem ) )
|
||||
{
|
||||
SimpleTypes::CDecimalNumber<> oNum = oItem.GetText();
|
||||
m_nNotes = oNum.GetValue();
|
||||
}
|
||||
m_nNotes = oItem.GetText();
|
||||
|
||||
if ( oProperties.GetNode( _T("Pages"), oItem ) )
|
||||
{
|
||||
SimpleTypes::CDecimalNumber<> oNum = oItem.GetText();
|
||||
m_nPages = oNum.GetValue();
|
||||
}
|
||||
m_nPages = oItem.GetText();
|
||||
|
||||
if ( oProperties.GetNode( _T("Paragraphs"), oItem ) )
|
||||
{
|
||||
SimpleTypes::CDecimalNumber<> oNum = oItem.GetText();
|
||||
m_nParagraphs = oNum.GetValue();
|
||||
}
|
||||
m_nParagraphs = oItem.GetText();
|
||||
|
||||
if ( oProperties.GetNode( _T("ScaleCrop"), oItem ) )
|
||||
{
|
||||
SimpleTypes::COnOff<> oBool = oItem.GetText();
|
||||
m_bScaleCrop = (oBool.GetValue() == SimpleTypes::onoffTrue);
|
||||
}
|
||||
m_bScaleCrop = oItem.GetText();
|
||||
|
||||
if ( oProperties.GetNode( _T("SharedDoc"), oItem ) )
|
||||
{
|
||||
SimpleTypes::COnOff<> oBool = oItem.GetText();
|
||||
m_bSharedDoc = (oBool.GetValue() == SimpleTypes::onoffTrue);
|
||||
}
|
||||
m_bSharedDoc = oItem.GetText();
|
||||
|
||||
if ( oProperties.GetNode( _T("Slides"), oItem ) )
|
||||
{
|
||||
SimpleTypes::CDecimalNumber<> oNum = oItem.GetText();
|
||||
m_nSlides = oNum.GetValue();
|
||||
}
|
||||
m_nSlides = oItem.GetText();
|
||||
|
||||
if ( oProperties.GetNode( _T("Template"), oItem ) )
|
||||
m_sTemplate = oItem.GetText();
|
||||
|
||||
|
||||
if ( oProperties.GetNode( _T("TotalTime"), oItem ) )
|
||||
{
|
||||
SimpleTypes::CDecimalNumber<> oNum = oItem.GetText();
|
||||
m_nTotalTime = oNum.GetValue();
|
||||
}
|
||||
m_nTotalTime = oItem.GetText();
|
||||
|
||||
if ( oProperties.GetNode( _T("Words"), oItem ) )
|
||||
{
|
||||
SimpleTypes::CDecimalNumber<> oNum = oItem.GetText();
|
||||
m_nWords = oNum.GetValue();
|
||||
}
|
||||
m_nWords = oItem.GetText();
|
||||
}
|
||||
}
|
||||
virtual void write(const CPath& oPath, const CPath& oDirectory, CContentTypes& oContent) const
|
||||
@ -204,21 +154,15 @@ namespace OOX
|
||||
|
||||
if ( m_nCharacters.IsInit() )
|
||||
{
|
||||
SimpleTypes::CDecimalNumber<> oNum;
|
||||
oNum.SetValue( m_nCharacters.get() );
|
||||
|
||||
sXml += _T("<Characters>");
|
||||
sXml += oNum.ToString();
|
||||
sXml += std::to_wstring(*m_nCharacters);
|
||||
sXml += _T("</Characters>");
|
||||
}
|
||||
|
||||
if ( m_nCharactersWithSpaces.IsInit() )
|
||||
{
|
||||
SimpleTypes::CDecimalNumber<> oNum;
|
||||
oNum.SetValue( m_nCharactersWithSpaces.get() );
|
||||
|
||||
sXml += _T("<CharactersWithSpaces>");
|
||||
sXml += oNum.ToString();
|
||||
sXml += std::to_wstring(*m_nCharactersWithSpaces);
|
||||
sXml += _T("</CharactersWithSpaces>");
|
||||
}
|
||||
|
||||
@ -231,21 +175,15 @@ namespace OOX
|
||||
|
||||
if ( m_nDocSecurity.IsInit() )
|
||||
{
|
||||
SimpleTypes::CDecimalNumber<> oNum;
|
||||
oNum.SetValue( m_nDocSecurity.get() );
|
||||
|
||||
sXml += _T("<DocSecurity>");
|
||||
sXml += oNum.ToString();
|
||||
sXml += std::to_wstring(*m_nDocSecurity);
|
||||
sXml += _T("</DocSecurity>");
|
||||
}
|
||||
|
||||
if ( m_nHiddenSlides.IsInit() )
|
||||
{
|
||||
SimpleTypes::CDecimalNumber<> oNum;
|
||||
oNum.SetValue( m_nHiddenSlides.get() );
|
||||
|
||||
sXml += _T("<HiddenSlides>");
|
||||
sXml += oNum.ToString();
|
||||
sXml += std::to_wstring(*m_nHiddenSlides);
|
||||
sXml += _T("</HiddenSlides>");
|
||||
}
|
||||
|
||||
@ -258,31 +196,22 @@ namespace OOX
|
||||
|
||||
if ( m_bHyperlinksChanged.IsInit() )
|
||||
{
|
||||
SimpleTypes::COnOff<> oBool;
|
||||
oBool.SetValue( m_bHyperlinksChanged.get() ? SimpleTypes::onoffTrue : SimpleTypes::onoffFalse );
|
||||
|
||||
sXml += _T("<HyperlinksChanged>");
|
||||
sXml += oBool.ToString();
|
||||
sXml += *m_bHyperlinksChanged ? L"true" : L"false";
|
||||
sXml += _T("</HyperlinksChanged>");
|
||||
}
|
||||
|
||||
if ( m_nLines.IsInit() )
|
||||
{
|
||||
SimpleTypes::CDecimalNumber<> oNum;
|
||||
oNum.SetValue( m_nLines.get() );
|
||||
|
||||
sXml += _T("<Lines>");
|
||||
sXml += oNum.ToString();
|
||||
sXml += std::to_wstring(*m_nLines);
|
||||
sXml += _T("</Lines>");
|
||||
}
|
||||
|
||||
if ( m_bLinksUpToDate.IsInit() )
|
||||
{
|
||||
SimpleTypes::COnOff<> oBool;
|
||||
oBool.SetValue( m_bLinksUpToDate.get() ? SimpleTypes::onoffTrue : SimpleTypes::onoffFalse );
|
||||
|
||||
sXml += _T("<LinksUpToDate>");
|
||||
sXml += oBool.ToString();
|
||||
sXml += *m_bLinksUpToDate ? L"true" : L"false";;
|
||||
sXml += _T("</LinksUpToDate>");
|
||||
}
|
||||
|
||||
@ -295,61 +224,43 @@ namespace OOX
|
||||
|
||||
if ( m_nMMClips.IsInit() )
|
||||
{
|
||||
SimpleTypes::CDecimalNumber<> oNum;
|
||||
oNum.SetValue( m_nMMClips.get() );
|
||||
|
||||
sXml += _T("<MMClips>");
|
||||
sXml += oNum.ToString();
|
||||
sXml += std::to_wstring(*m_nMMClips);
|
||||
sXml += _T("</MMClips>");
|
||||
}
|
||||
|
||||
if ( m_nNotes.IsInit() )
|
||||
{
|
||||
SimpleTypes::CDecimalNumber<> oNum;
|
||||
oNum.SetValue( m_nNotes.get() );
|
||||
|
||||
sXml += _T("<Notes>");
|
||||
sXml += oNum.ToString();
|
||||
sXml += std::to_wstring(*m_nNotes);
|
||||
sXml += _T("</Notes>");
|
||||
}
|
||||
|
||||
if ( m_nPages.IsInit() )
|
||||
{
|
||||
SimpleTypes::CDecimalNumber<> oNum;
|
||||
oNum.SetValue( m_nPages.get() );
|
||||
|
||||
sXml += _T("<Pages>");
|
||||
sXml += oNum.ToString();
|
||||
sXml += std::to_wstring(*m_nPages);
|
||||
sXml += _T("</Pages>");
|
||||
}
|
||||
|
||||
if ( m_nParagraphs.IsInit() )
|
||||
{
|
||||
SimpleTypes::CDecimalNumber<> oNum;
|
||||
oNum.SetValue( m_nParagraphs.get() );
|
||||
|
||||
sXml += _T("<Paragraphs>");
|
||||
sXml += oNum.ToString();
|
||||
sXml += std::to_wstring(*m_nParagraphs);
|
||||
sXml += _T("</Paragraphs>");
|
||||
}
|
||||
|
||||
if ( m_bScaleCrop.IsInit() )
|
||||
{
|
||||
SimpleTypes::COnOff<> oBool;
|
||||
oBool.SetValue( m_bScaleCrop.get() ? SimpleTypes::onoffTrue : SimpleTypes::onoffFalse );
|
||||
|
||||
sXml += _T("<ScaleCrop>");
|
||||
sXml += oBool.ToString();
|
||||
sXml += *m_bScaleCrop ? L"true" : L"false";;
|
||||
sXml += _T("</ScaleCrop>");
|
||||
}
|
||||
|
||||
if ( m_bSharedDoc.IsInit() )
|
||||
{
|
||||
SimpleTypes::COnOff<> oBool;
|
||||
oBool.SetValue( m_bSharedDoc.get() ? SimpleTypes::onoffTrue : SimpleTypes::onoffFalse );
|
||||
|
||||
sXml += _T("<SharedDoc>");
|
||||
sXml += oBool.ToString();
|
||||
sXml += *m_bSharedDoc ? L"true" : L"false";;
|
||||
sXml += _T("</SharedDoc>");
|
||||
}
|
||||
|
||||
@ -359,7 +270,7 @@ namespace OOX
|
||||
oNum.SetValue( m_nSlides.get() );
|
||||
|
||||
sXml += _T("<Slides>");
|
||||
sXml += oNum.ToString();
|
||||
sXml += std::to_wstring(*m_nSlides);
|
||||
sXml += _T("</Slides>");
|
||||
}
|
||||
|
||||
@ -372,21 +283,15 @@ namespace OOX
|
||||
|
||||
if ( m_nTotalTime.IsInit() )
|
||||
{
|
||||
SimpleTypes::CDecimalNumber<> oNum;
|
||||
oNum.SetValue( m_nTotalTime.get() );
|
||||
|
||||
sXml += _T("<TotalTime>");
|
||||
sXml += oNum.ToString();
|
||||
sXml += std::to_wstring(*m_nTotalTime);
|
||||
sXml += _T("</TotalTime>");
|
||||
}
|
||||
|
||||
if ( m_nWords.IsInit() )
|
||||
{
|
||||
SimpleTypes::CDecimalNumber<> oNum;
|
||||
oNum.SetValue( m_nWords.get() );
|
||||
|
||||
sXml += _T("<Words>");
|
||||
sXml += oNum.ToString();
|
||||
sXml += std::to_wstring(*m_nWords);
|
||||
sXml += _T("</Words>");
|
||||
}
|
||||
|
||||
@ -411,11 +316,12 @@ namespace OOX
|
||||
void SetDefaults()
|
||||
{
|
||||
SetRequiredDefaults();
|
||||
SetDocSecurity(0);
|
||||
SetScaleCrop(false);
|
||||
SetLinksUpToDate(false);
|
||||
SetSharedDoc(false);
|
||||
SetHyperlinksChanged(false);
|
||||
|
||||
m_nDocSecurity = 0;
|
||||
m_bScaleCrop = false;
|
||||
m_bLinksUpToDate = false;
|
||||
m_bSharedDoc = false;
|
||||
m_bHyperlinksChanged = false;
|
||||
}
|
||||
void SetRequiredDefaults()
|
||||
{
|
||||
@ -423,47 +329,13 @@ namespace OOX
|
||||
std::wstring sApplication = NSSystemUtils::GetEnvVariable(NSSystemUtils::gc_EnvApplicationName);
|
||||
if (sApplication.empty())
|
||||
sApplication = NSSystemUtils::gc_EnvApplicationNameDefault;
|
||||
SetApplication(sApplication);
|
||||
#if defined(INTVER)
|
||||
SetAppVersion(VALUE2STR(INTVER));
|
||||
std::string s = VALUE2STR(INTVER);
|
||||
sApplication += L"/" + std::wstring(s.begin(), s.end());
|
||||
#endif
|
||||
m_sApplication = sApplication;
|
||||
}
|
||||
void SetApplication(const std::wstring& sVal)
|
||||
{
|
||||
m_sApplication = sVal;
|
||||
}
|
||||
void SetAppVersion(const std::wstring& sVal)
|
||||
{
|
||||
m_sAppVersion = sVal;
|
||||
}
|
||||
void SetAppVersion(const std::string& sVal)
|
||||
{
|
||||
m_sAppVersion = std::wstring(sVal.begin(), sVal.end());
|
||||
}
|
||||
void SetDocSecurity(int nVal)
|
||||
{
|
||||
m_nDocSecurity = nVal;
|
||||
}
|
||||
void SetScaleCrop(bool bVal)
|
||||
{
|
||||
m_bScaleCrop = bVal;
|
||||
}
|
||||
void SetCompany(std::wstring sVal)
|
||||
{
|
||||
m_sCompany = sVal;
|
||||
}
|
||||
void SetLinksUpToDate(bool bVal)
|
||||
{
|
||||
m_bLinksUpToDate = bVal;
|
||||
}
|
||||
void SetSharedDoc(bool bVal)
|
||||
{
|
||||
m_bSharedDoc = bVal;
|
||||
}
|
||||
void SetHyperlinksChanged(bool bVal)
|
||||
{
|
||||
m_bHyperlinksChanged = bVal;
|
||||
}
|
||||
|
||||
PPTX::App* ToPptxApp();
|
||||
void FromPptxApp(PPTX::App* pApp);
|
||||
|
||||
@ -472,30 +344,29 @@ namespace OOX
|
||||
// HLinks
|
||||
// TitlesOfParts
|
||||
|
||||
nullable<std::wstring> m_sApplication;
|
||||
nullable<std::wstring> m_sAppVersion;
|
||||
nullable<int> m_nCharacters;
|
||||
nullable<int> m_nCharactersWithSpaces;
|
||||
nullable<std::wstring> m_sCompany;
|
||||
nullable<int> m_nDocSecurity;
|
||||
nullable<int> m_nHiddenSlides;
|
||||
nullable<std::wstring> m_sHyperlinkBase;
|
||||
nullable<bool> m_bHyperlinksChanged;
|
||||
nullable<int> m_nLines;
|
||||
nullable<bool> m_bLinksUpToDate;
|
||||
nullable<std::wstring> m_sManager;
|
||||
nullable<int> m_nMMClips;
|
||||
nullable<int> m_nNotes;
|
||||
nullable<int> m_nPages;
|
||||
nullable<int> m_nParagraphs;
|
||||
nullable<std::wstring> m_sPresentationForm;
|
||||
nullable<bool> m_bScaleCrop;
|
||||
nullable<bool> m_bSharedDoc;
|
||||
nullable<int> m_nSlides;
|
||||
nullable<std::wstring> m_sTemplate;
|
||||
nullable<int> m_nTotalTime;
|
||||
nullable<int> m_nWords;
|
||||
nullable_string m_sApplication;
|
||||
nullable_string m_sAppVersion;
|
||||
nullable_int m_nCharacters;
|
||||
nullable_int m_nCharactersWithSpaces;
|
||||
nullable_string m_sCompany;
|
||||
nullable_int m_nDocSecurity;
|
||||
nullable_int m_nHiddenSlides;
|
||||
nullable_string m_sHyperlinkBase;
|
||||
nullable_bool m_bHyperlinksChanged;
|
||||
nullable_int m_nLines;
|
||||
nullable_bool m_bLinksUpToDate;
|
||||
nullable_string m_sManager;
|
||||
nullable_int m_nMMClips;
|
||||
nullable_int m_nNotes;
|
||||
nullable_int m_nPages;
|
||||
nullable_int m_nParagraphs;
|
||||
nullable_string m_sPresentationForm;
|
||||
nullable_bool m_bScaleCrop;
|
||||
nullable_bool m_bSharedDoc;
|
||||
nullable_int m_nSlides;
|
||||
nullable_string m_sTemplate;
|
||||
nullable_int m_nTotalTime;
|
||||
nullable_int m_nWords;
|
||||
};
|
||||
} // namespace OOX
|
||||
|
||||
#endif // OOX_APP_INCLUDE_H_
|
||||
|
||||
@ -30,8 +30,6 @@
|
||||
*
|
||||
*/
|
||||
#pragma once
|
||||
#ifndef OOX_CORE_INCLUDE_H_
|
||||
#define OOX_CORE_INCLUDE_H_
|
||||
|
||||
#include "Docx.h"
|
||||
#include "File.h"
|
||||
@ -264,22 +262,20 @@ xmlns:xsi=\"http://www.w3.org/2001/XMLSchema-instance\">");
|
||||
PPTX::Core* ToPptxCore();
|
||||
void FromPptxCore(PPTX::Core* pCore);
|
||||
|
||||
nullable<std::wstring> m_sCategory;
|
||||
nullable<std::wstring> m_sContentStatus;
|
||||
nullable<std::wstring> m_sCreated;
|
||||
nullable<std::wstring> m_sCreator;
|
||||
nullable<std::wstring> m_sDescription;
|
||||
nullable<std::wstring> m_sIdentifier;
|
||||
nullable<std::wstring> m_sKeywords;
|
||||
nullable<std::wstring> m_sLanguage;
|
||||
nullable<std::wstring> m_sLastModifiedBy;
|
||||
nullable<std::wstring> m_sLastPrinted;
|
||||
nullable<std::wstring> m_sModified;
|
||||
nullable<std::wstring> m_sRevision;
|
||||
nullable<std::wstring> m_sSubject;
|
||||
nullable<std::wstring> m_sTitle;
|
||||
nullable<std::wstring> m_sVersion;
|
||||
nullable_string m_sCategory;
|
||||
nullable_string m_sContentStatus;
|
||||
nullable_string m_sCreated;
|
||||
nullable_string m_sCreator;
|
||||
nullable_string m_sDescription;
|
||||
nullable_string m_sIdentifier;
|
||||
nullable_string m_sKeywords;
|
||||
nullable_string m_sLanguage;
|
||||
nullable_string m_sLastModifiedBy;
|
||||
nullable_string m_sLastPrinted;
|
||||
nullable_string m_sModified;
|
||||
nullable_string m_sRevision;
|
||||
nullable_string m_sSubject;
|
||||
nullable_string m_sTitle;
|
||||
nullable_string m_sVersion;
|
||||
};
|
||||
} // namespace OOX
|
||||
|
||||
#endif // OOX_CORE_INCLUDE_H_
|
||||
|
||||
@ -150,7 +150,7 @@ namespace OOX
|
||||
WritingElement_ReadAttributes_Start(oReader)
|
||||
WritingElement_ReadAttributes_Read_if(oReader, L"w:bgcolor", m_oColor)
|
||||
WritingElement_ReadAttributes_Read_else_if(oReader, L"w:background", m_oBackgroundType)
|
||||
WritingElement_ReadAttributes_End(oReader)
|
||||
WritingElement_ReadAttributes_End(oReader)
|
||||
}
|
||||
}
|
||||
//------------------------------------------------------------------------------------------------------------------------
|
||||
@ -376,7 +376,7 @@ namespace OOX
|
||||
|
||||
CDirectory::SaveToFile( oPath.GetPath(), sXml );
|
||||
|
||||
oContent.Registration( type().OverrideType(), oDirectory, oPath );
|
||||
oContent.Registration( type().OverrideType(), oDirectory, oPath.GetFilename() );
|
||||
IFileContainer::Write( oPath, oDirectory, oContent );
|
||||
}
|
||||
|
||||
|
||||
@ -110,11 +110,6 @@ namespace OOX
|
||||
void FixAfterRead();
|
||||
bool Write(const CPath& oFilePath)
|
||||
{
|
||||
|
||||
// TO DO: Запись надо править. Она НЕ РАБОТАЕТ!!!! Проблемы в IFileContainer.
|
||||
|
||||
//return false;
|
||||
|
||||
// Создаем папку
|
||||
NSDirectory::CreateDirectory(oFilePath.GetPath());
|
||||
|
||||
|
||||
@ -32,35 +32,31 @@
|
||||
#pragma once
|
||||
|
||||
#include "DocxFlat.h"
|
||||
#include "App.h"
|
||||
#include "Core.h"
|
||||
|
||||
#include "HeaderFooter.h"
|
||||
#include "Document.h"
|
||||
#include "FontTable.h"
|
||||
#include "Numbering.h"
|
||||
#include "Styles.h"
|
||||
#include "Comments.h"
|
||||
#include "Footnote.h"
|
||||
#include "Endnote.h"
|
||||
#include "Settings/Settings.h"
|
||||
|
||||
namespace OOX
|
||||
{
|
||||
|
||||
CDocxFlat::CDocxFlat() : File(dynamic_cast<Document*>(this)), m_oComments(dynamic_cast<Document*>(this)),
|
||||
m_oEndnotes(dynamic_cast<Document*>(this)),
|
||||
m_oFootnotes(dynamic_cast<Document*>(this))
|
||||
CDocxFlat::CDocxFlat() : File(dynamic_cast<Document*>(this))
|
||||
{
|
||||
}
|
||||
CDocxFlat::CDocxFlat(const CPath& oFilePath) : File(this), m_oComments(dynamic_cast<Document*>(this)),
|
||||
m_oEndnotes(dynamic_cast<Document*>(this)),
|
||||
m_oFootnotes(dynamic_cast<Document*>(this))
|
||||
CDocxFlat::CDocxFlat(const CPath& oFilePath) : File(dynamic_cast<Document*>(this))
|
||||
{
|
||||
read( oFilePath );
|
||||
}
|
||||
CDocxFlat::~CDocxFlat()
|
||||
{
|
||||
for (std::map<std::wstring, OOX::CHdrFtr*>::iterator it = m_mapHeadersFooters.begin(); it != m_mapHeadersFooters.end(); ++it)
|
||||
{
|
||||
if (it->second) delete it->second; it->second = NULL;
|
||||
}
|
||||
m_mapHeadersFooters.clear();
|
||||
}
|
||||
void CDocxFlat::ReadAttributes(XmlUtils::CXmlLiteReader& oReader)
|
||||
{
|
||||
@ -75,6 +71,10 @@ namespace OOX
|
||||
if ( oReader.IsEmptyNode() )
|
||||
return;
|
||||
|
||||
m_pComments = new OOX::CComments(this);
|
||||
m_pFootnotes = new OOX::CFootnotes(this);
|
||||
m_pEndnotes = new OOX::CEndnotes(this);
|
||||
|
||||
int nDepth = oReader.GetDepth();
|
||||
while ( oReader.ReadNextSiblingNode(nDepth) )
|
||||
{
|
||||
@ -83,18 +83,32 @@ namespace OOX
|
||||
if ( L"w:body" == sName )
|
||||
{
|
||||
m_pDocument = new CDocument(dynamic_cast<Document*>(this));
|
||||
m_currentContainer = dynamic_cast<OOX::IFileContainer*>(m_pDocument.GetPointer());
|
||||
m_pDocument->fromXML(oReader);
|
||||
}
|
||||
else if ( L"w:fonts" == sName )
|
||||
m_pFontTable = oReader;
|
||||
else if ( L"w:lists" == sName )
|
||||
m_pNumbering = oReader;
|
||||
else if (L"w:lists" == sName)
|
||||
{
|
||||
m_pNumbering = new CNumbering(dynamic_cast<Document*>(this));
|
||||
m_pNumbering->fromXML(oReader);
|
||||
}
|
||||
else if ( L"w:styles" == sName )
|
||||
m_pStyles = oReader;
|
||||
else if ( L"w:docPr" == sName )
|
||||
m_pSettings = oReader;
|
||||
else if ( L"w:bgPict" == sName )
|
||||
m_oBgPict = oReader;
|
||||
else if (L"w:docPr" == sName)
|
||||
{
|
||||
m_pSettings = new CSettings(dynamic_cast<Document*>(this));
|
||||
m_pSettings->fromXML(oReader);
|
||||
}
|
||||
else if (L"w:bgPict" == sName)
|
||||
{
|
||||
m_pBgPict = new Logic::CBgPict(dynamic_cast<Document*>(this));
|
||||
m_pBgPict->fromXML(oReader);
|
||||
}
|
||||
else if (L"o:DocumentProperties" == sName)
|
||||
{
|
||||
ReadDocumentProperties(oReader);
|
||||
}
|
||||
}
|
||||
|
||||
if ((m_pFontTable.IsInit() && m_pStyles.IsInit()) && (m_pFontTable->m_oDefaultFonts.IsInit()))
|
||||
@ -107,5 +121,139 @@ namespace OOX
|
||||
if (!m_pStyles->m_oDocDefaults->m_oRunPr->m_oRFonts.IsInit())
|
||||
m_pStyles->m_oDocDefaults->m_oRunPr->m_oRFonts = m_pFontTable->m_oDefaultFonts;
|
||||
}
|
||||
if (m_pStyles.IsInit())
|
||||
{
|
||||
NSCommon::smart_ptr<OOX::File> file = NSCommon::smart_ptr<OOX::File>(m_pStyles.GetPointer()); file.AddRef();
|
||||
m_pDocument->Add(file);
|
||||
}
|
||||
if (m_pFontTable.IsInit())
|
||||
{
|
||||
NSCommon::smart_ptr<OOX::File> file = NSCommon::smart_ptr<OOX::File>(m_pFontTable.GetPointer()); file.AddRef();
|
||||
m_pDocument->Add(file);
|
||||
}
|
||||
if (m_pNumbering.IsInit())
|
||||
{
|
||||
NSCommon::smart_ptr<OOX::File> file = NSCommon::smart_ptr<OOX::File>(m_pNumbering.GetPointer()); file.AddRef();
|
||||
m_pDocument->Add(file);
|
||||
}
|
||||
if (m_pSettings.IsInit())
|
||||
{
|
||||
NSCommon::smart_ptr<OOX::File> file = NSCommon::smart_ptr<OOX::File>(m_pSettings.GetPointer()); file.AddRef();
|
||||
m_pDocument->Add(file);
|
||||
}
|
||||
if (m_pComments.IsInit())
|
||||
{
|
||||
NSCommon::smart_ptr<OOX::File> file = NSCommon::smart_ptr<OOX::File>(m_pComments.GetPointer()); file.AddRef();
|
||||
m_pDocument->Add(file);
|
||||
}
|
||||
if (m_pFootnotes.IsInit())
|
||||
{
|
||||
NSCommon::smart_ptr<OOX::File> file = NSCommon::smart_ptr<OOX::File>(m_pFootnotes.GetPointer()); file.AddRef();
|
||||
m_pDocument->Add(file);
|
||||
}
|
||||
if (m_pEndnotes.IsInit())
|
||||
{
|
||||
NSCommon::smart_ptr<OOX::File> file = NSCommon::smart_ptr<OOX::File>(m_pEndnotes.GetPointer()); file.AddRef();
|
||||
m_pDocument->Add(file);
|
||||
}
|
||||
}
|
||||
void CDocxFlat::ReadDocumentProperties(XmlUtils::CXmlLiteReader& oReader)
|
||||
{
|
||||
if (oReader.IsEmptyNode())
|
||||
return;
|
||||
|
||||
m_pApp = new OOX::CApp(this);
|
||||
m_pCore = new OOX::CCore(this);
|
||||
|
||||
int nDepth = oReader.GetDepth();
|
||||
while (oReader.ReadNextSiblingNode(nDepth))
|
||||
{
|
||||
std::wstring sName = oReader.GetNameNoNS();
|
||||
|
||||
if (L"Category" == sName)
|
||||
m_pCore->m_sCategory = oReader.GetText2();
|
||||
else if (L"ContentStatus" == sName)
|
||||
m_pCore->m_sContentStatus = oReader.GetText2();
|
||||
else if (L"Created" == sName)
|
||||
m_pCore->m_sCreated = oReader.GetText2();
|
||||
else if (L"Author" == sName)
|
||||
m_pCore->m_sCreator = oReader.GetText2();
|
||||
else if (L"Description" == sName)
|
||||
m_pCore->m_sDescription = oReader.GetText2();
|
||||
else if (L"Identifier" == sName)
|
||||
m_pCore->m_sIdentifier = oReader.GetText2();
|
||||
else if (L"Keywords" == sName)
|
||||
m_pCore->m_sKeywords = oReader.GetText2();
|
||||
else if (L"Language" == sName)
|
||||
m_pCore->m_sLanguage = oReader.GetText2();
|
||||
else if (L"LastAuthor" == sName)
|
||||
m_pCore->m_sLastModifiedBy = oReader.GetText2();
|
||||
else if (L"lastPrinted" == sName)
|
||||
m_pCore->m_sLastPrinted = oReader.GetText2();
|
||||
else if (L"LastSaved" == sName)
|
||||
m_pCore->m_sModified = oReader.GetText2();
|
||||
else if (L"Revision" == sName)
|
||||
m_pCore->m_sRevision = oReader.GetText2();
|
||||
else if (L"Subject" == sName)
|
||||
m_pCore->m_sSubject = oReader.GetText2();
|
||||
else if (L"Title" == sName)
|
||||
m_pCore->m_sTitle = oReader.GetText2();
|
||||
else if (L"Version" == sName)
|
||||
m_pCore->m_sVersion = oReader.GetText2();
|
||||
else if (L"Application" == sName)
|
||||
m_pApp->m_sApplication = oReader.GetText2();
|
||||
else if (L"AppVersion" == sName)
|
||||
m_pApp->m_sAppVersion = oReader.GetText2();
|
||||
else if (L"Characters" == sName)
|
||||
m_pApp->m_nCharacters = oReader.GetText2();
|
||||
else if (L"CharactersWithSpaces" == sName)
|
||||
m_pApp->m_nCharactersWithSpaces = oReader.GetText2();
|
||||
else if (L"Company" == sName)
|
||||
m_pApp->m_sCompany = oReader.GetText2();
|
||||
else if (L"DocSecurity" == sName)
|
||||
m_pApp->m_nDocSecurity = oReader.GetText2();
|
||||
else if (L"HiddenSlides" == sName)
|
||||
m_pApp->m_nHiddenSlides = oReader.GetText2();
|
||||
else if (L"HyperlinkBase" == sName)
|
||||
m_pApp->m_sHyperlinkBase = oReader.GetText2();
|
||||
else if (L"HyperlinksChanged" == sName)
|
||||
m_pApp->m_bHyperlinksChanged = oReader.GetText2();
|
||||
else if (L"Lines" == sName)
|
||||
m_pApp->m_nLines = oReader.GetText2();
|
||||
else if (L"LinksUpToDate" == sName)
|
||||
m_pApp->m_bLinksUpToDate = oReader.GetText2();
|
||||
else if (L"Manager" == sName)
|
||||
m_pApp->m_sManager = oReader.GetText2();
|
||||
else if (L"MMClips" == sName)
|
||||
m_pApp->m_nMMClips = oReader.GetText2();
|
||||
else if (L"Notes" == sName)
|
||||
m_pApp->m_nNotes = oReader.GetText2();
|
||||
else if (L"Pages" == sName)
|
||||
m_pApp->m_nPages = oReader.GetText2();
|
||||
else if (L"Paragraphs" == sName)
|
||||
m_pApp->m_nParagraphs = oReader.GetText2();
|
||||
else if (L"ScaleCrop" == sName)
|
||||
m_pApp->m_bScaleCrop = oReader.GetText2();
|
||||
else if (L"SharedDoc" == sName)
|
||||
m_pApp->m_bSharedDoc = oReader.GetText2();
|
||||
else if (L"Slides" == sName)
|
||||
m_pApp->m_nSlides = oReader.GetText2();
|
||||
else if (L"Template" == sName)
|
||||
m_pApp->m_sTemplate = oReader.GetText2();
|
||||
else if (L"TotalTime" == sName)
|
||||
m_pApp->m_nTotalTime = oReader.GetText2();
|
||||
else if (L"Words" == sName)
|
||||
m_pApp->m_nWords = oReader.GetText2();
|
||||
}
|
||||
}
|
||||
OOX::CHdrFtr *CDocxFlat::GetHeaderOrFooter(const OOX::RId& rId) const
|
||||
{
|
||||
OOX::IFileContainer* pDocumentContainer = (OOX::IFileContainer*)m_pDocument.GetPointer();
|
||||
|
||||
smart_ptr<OOX::File> pFile = pDocumentContainer->Find(rId);
|
||||
if (pFile.IsInit() && (OOX::FileTypes::Header == pFile->type() || OOX::FileTypes::Footer == pFile->type()))
|
||||
return (OOX::CHdrFtr*)pFile.GetPointer();
|
||||
else
|
||||
return NULL;
|
||||
}
|
||||
}
|
||||
|
||||
@ -32,9 +32,9 @@
|
||||
#pragma once
|
||||
|
||||
|
||||
#include "Comments.h"
|
||||
#include "Footnote.h"
|
||||
#include "Endnote.h"
|
||||
#include "IFileContainer.h"
|
||||
#include "FileTypes.h"
|
||||
#include "../Common/SimpleTypes_Word.h"
|
||||
|
||||
namespace OOX
|
||||
{
|
||||
@ -43,7 +43,13 @@ namespace OOX
|
||||
class CFontTable;
|
||||
class CNumbering;
|
||||
class CStyles;
|
||||
|
||||
class CEndnotes;
|
||||
class CFootnotes;
|
||||
class CComments;
|
||||
class CSettings;
|
||||
class CApp;
|
||||
class CCore;
|
||||
|
||||
namespace Logic
|
||||
{
|
||||
class CBgPict;
|
||||
@ -105,6 +111,8 @@ namespace OOX
|
||||
{
|
||||
return et_w_wordDocument;
|
||||
}
|
||||
OOX::CHdrFtr *GetHeaderOrFooter(const OOX::RId& rId) const;
|
||||
void ReadDocumentProperties(XmlUtils::CXmlLiteReader& oReader);
|
||||
//-----------------------------------------------------------------------
|
||||
nullable<SimpleTypes::CXmlSpace<>> m_oSpace;
|
||||
|
||||
@ -113,13 +121,17 @@ namespace OOX
|
||||
nullable<CFontTable> m_pFontTable;
|
||||
nullable<CNumbering> m_pNumbering;
|
||||
nullable<CSettings> m_pSettings;
|
||||
nullable<Logic::CBgPict> m_oBgPict;
|
||||
nullable<Logic::CBgPict> m_pBgPict;
|
||||
|
||||
CComments m_oComments;
|
||||
OOX::CFootnotes m_oFootnotes;
|
||||
OOX::CEndnotes m_oEndnotes;
|
||||
std::map<std::wstring, OOX::CHdrFtr*> m_mapHeadersFooters;
|
||||
|
||||
nullable<CComments> m_pComments;
|
||||
nullable<CFootnotes> m_pFootnotes;
|
||||
nullable<CEndnotes> m_pEndnotes;
|
||||
nullable<CApp> m_pApp;
|
||||
nullable<CCore> m_pCore;
|
||||
//-----------------------------------------------------------
|
||||
std::map<std::wstring, std::wstring> m_mapImagesId;
|
||||
|
||||
OOX::IFileContainer *m_currentContainer = NULL;
|
||||
};
|
||||
|
||||
|
||||
|
||||
@ -153,7 +153,7 @@ mc:Ignorable=\"w14 w15 wp14\">");
|
||||
sXml += _T("</w:endnotes>");
|
||||
CDirectory::SaveToFile( oPath.GetPath(), sXml );
|
||||
|
||||
oContent.Registration( type().OverrideType(), oDirectory, oPath );
|
||||
oContent.Registration( type().OverrideType(), oDirectory, oPath.GetFilename() );
|
||||
IFileContainer::Write( oPath, oDirectory, oContent );
|
||||
}
|
||||
virtual const OOX::FileType type() const
|
||||
|
||||
@ -102,11 +102,11 @@ namespace OOX
|
||||
|
||||
const FileType Header (L"", L"header.xml",
|
||||
L"application/vnd.openxmlformats-officedocument.wordprocessingml.header+xml",
|
||||
L"http://schemas.openxmlformats.org/officeDocument/2006/relationships/header");
|
||||
L"http://schemas.openxmlformats.org/officeDocument/2006/relationships/header", L"header", true);
|
||||
|
||||
const FileType Footer (L"", L"footer.xml",
|
||||
L"application/vnd.openxmlformats-officedocument.wordprocessingml.footer+xml",
|
||||
L"http://schemas.openxmlformats.org/officeDocument/2006/relationships/footer");
|
||||
L"http://schemas.openxmlformats.org/officeDocument/2006/relationships/footer", L"footer", true);
|
||||
|
||||
const FileType Numbering (L"", L"numbering.xml",
|
||||
L"application/vnd.openxmlformats-officedocument.wordprocessingml.numbering+xml",
|
||||
@ -172,19 +172,19 @@ namespace OOX
|
||||
|
||||
const FileType Image (L"media", L"image",
|
||||
L"",
|
||||
L"http://schemas.openxmlformats.org/officeDocument/2006/relationships/image");
|
||||
L"http://schemas.openxmlformats.org/officeDocument/2006/relationships/image", L"image", true, true);
|
||||
|
||||
const FileType Audio (L"media", L"audio",
|
||||
L"",
|
||||
L"http://schemas.openxmlformats.org/officeDocument/2006/relationships/audio");
|
||||
L"http://schemas.openxmlformats.org/officeDocument/2006/relationships/audio", L"audio", true, true);
|
||||
|
||||
const FileType Video (L"media", L"video",
|
||||
L"",
|
||||
L"http://schemas.openxmlformats.org/officeDocument/2006/relationships/video");
|
||||
L"http://schemas.openxmlformats.org/officeDocument/2006/relationships/video", L"video", true, true);
|
||||
|
||||
const FileType Media (L"media", L"media",
|
||||
L"",
|
||||
L"http://schemas.openxmlformats.org/officeDocument/2006/relationships/media");
|
||||
L"http://schemas.openxmlformats.org/officeDocument/2006/relationships/media", L"media", true, true);
|
||||
|
||||
const FileType DiagramData (L"diagrams", L"data.xml",
|
||||
L"application/vnd.openxmlformats-officedocument.drawingml.diagramData+xml",
|
||||
|
||||
@ -127,11 +127,13 @@ namespace OOX
|
||||
fromXML(oReader);
|
||||
}
|
||||
}
|
||||
virtual void write(const CPath &oFilePath, const CPath &oDirectoryPath, CContentTypes& content) const
|
||||
virtual void write(const CPath &oFilePath, const CPath &oDirectory, CContentTypes& oContent) const
|
||||
{
|
||||
std::wstring sXml = toXML();
|
||||
|
||||
CDirectory::SaveToFile( oFilePath.GetPath(), sXml );
|
||||
|
||||
oContent.Registration(type().OverrideType(), oDirectory, oFilePath.GetFilename());
|
||||
}
|
||||
virtual const FileType type() const
|
||||
{
|
||||
|
||||
@ -132,7 +132,7 @@ namespace OOX
|
||||
sXml += _T("</w:footnotes>");
|
||||
CDirectory::SaveToFile( oPath.GetPath(), sXml );
|
||||
|
||||
oContent.Registration( type().OverrideType(), oDirectory, oPath );
|
||||
oContent.Registration( type().OverrideType(), oDirectory, oPath.GetFilename() );
|
||||
IFileContainer::Write( oPath, oDirectory, oContent );
|
||||
}
|
||||
virtual const OOX::FileType type() const
|
||||
|
||||
@ -30,8 +30,6 @@
|
||||
*
|
||||
*/
|
||||
#pragma once
|
||||
#ifndef OOX_HEADER_FOOTER_INCLUDE_H_
|
||||
#define OOX_HEADER_FOOTER_INCLUDE_H_
|
||||
|
||||
#include "File.h"
|
||||
#include "../Base/Nullable.h"
|
||||
@ -260,7 +258,7 @@ mc:Ignorable=\"w14 w15 wp14\">");
|
||||
|
||||
CDirectory::SaveToFile( oFilePath.GetPath(), sXml );
|
||||
|
||||
oContent.Registration( type().OverrideType(), oDirectory, oFilePath );
|
||||
oContent.Registration( type().OverrideType(), oDirectory, oFilePath.GetFilename() );
|
||||
IFileContainer::Write( oFilePath, oDirectory, oContent );
|
||||
}
|
||||
virtual const OOX::FileType type() const
|
||||
@ -307,5 +305,3 @@ mc:Ignorable=\"w14 w15 wp14\">");
|
||||
};
|
||||
|
||||
} // namespace OOX
|
||||
|
||||
#endif // OOX_HEADER_FOOTER_INCLUDE_H_
|
||||
|
||||
@ -29,6 +29,7 @@
|
||||
* terms at http://creativecommons.org/licenses/by-sa/4.0/legalcode
|
||||
*
|
||||
*/
|
||||
#include "../DocxFlat.h"
|
||||
#include "Hyperlink.h"
|
||||
#include "Paragraph.h"
|
||||
#include "Annotations.h"
|
||||
@ -155,8 +156,31 @@ namespace OOX
|
||||
}
|
||||
}
|
||||
}
|
||||
void CHyperlink::ReadAttributes(XmlUtils::CXmlLiteReader& oReader)
|
||||
{
|
||||
WritingElement_ReadAttributes_Start(oReader)
|
||||
WritingElement_ReadAttributes_Read_if(oReader, _T("w:anchor"), m_sAnchor)
|
||||
WritingElement_ReadAttributes_Read_if(oReader, _T("w:bookmark"), m_sAnchor) //for Word 2003 XML
|
||||
WritingElement_ReadAttributes_Read_else_if(oReader, _T("w:dest"), m_sDestinition) //for Word 2003 XML
|
||||
WritingElement_ReadAttributes_Read_else_if(oReader, _T("w:docLocation"), m_sDocLocation)
|
||||
WritingElement_ReadAttributes_Read_else_if(oReader, _T("w:history"), m_oHistory)
|
||||
WritingElement_ReadAttributes_Read_else_if(oReader, _T("r:id"), m_oId)
|
||||
WritingElement_ReadAttributes_Read_else_if(oReader, _T("relationships:id"), m_oId)
|
||||
WritingElement_ReadAttributes_Read_else_if(oReader, _T("w:tgtFrame"), m_sTgtFrame)
|
||||
WritingElement_ReadAttributes_Read_else_if(oReader, _T("w:tooltip"), m_sTooltip)
|
||||
WritingElement_ReadAttributes_End(oReader)
|
||||
|
||||
|
||||
if (m_sDestinition.IsInit())
|
||||
{
|
||||
CDocxFlat* docx_flat = dynamic_cast<CDocxFlat*>(m_pMainDocument);
|
||||
if (docx_flat)
|
||||
{
|
||||
smart_ptr<OOX::File> oHyperlinkFile = smart_ptr<OOX::File>(new OOX::HyperLink(m_pMainDocument, OOX::CPath(*m_sDestinition, false)));
|
||||
const OOX::RId rId = docx_flat->m_currentContainer->Add(oHyperlinkFile);
|
||||
m_oId = new SimpleTypes::CRelationshipId(rId.get());
|
||||
}
|
||||
}
|
||||
}
|
||||
void CHyperlink::fromXML(XmlUtils::CXmlLiteReader& oReader)
|
||||
{
|
||||
ReadAttributes( oReader );
|
||||
@ -281,7 +305,7 @@ namespace OOX
|
||||
|
||||
if ( m_sTooltip.IsInit() )
|
||||
{
|
||||
sResult += L" w:tooltip=\"" + (*m_sTooltip) + L"\"";
|
||||
sResult += L" w:tooltip=\"" + XmlUtils::EncodeXmlString(*m_sTooltip) + L"\"";
|
||||
}
|
||||
|
||||
sResult += L">";
|
||||
|
||||
@ -76,7 +76,6 @@ namespace OOX
|
||||
fromXML( (XmlUtils::CXmlLiteReader&)oReader );
|
||||
return *this;
|
||||
}
|
||||
|
||||
virtual void ClearItems()
|
||||
{
|
||||
m_sAnchor.reset();
|
||||
@ -97,26 +96,9 @@ namespace OOX
|
||||
{
|
||||
return et_w_hyperlink;
|
||||
}
|
||||
|
||||
private:
|
||||
|
||||
void ReadAttributes(XmlUtils::CXmlLiteReader& oReader)
|
||||
{
|
||||
WritingElement_ReadAttributes_Start( oReader )
|
||||
WritingElement_ReadAttributes_Read_if ( oReader, _T("w:anchor"), m_sAnchor )
|
||||
WritingElement_ReadAttributes_Read_if ( oReader, _T("w:bookmark"), m_sAnchor ) //for Word 2003 XML
|
||||
WritingElement_ReadAttributes_Read_else_if( oReader, _T("w:dest"), m_sDestinition ) //for Word 2003 XML
|
||||
WritingElement_ReadAttributes_Read_else_if( oReader, _T("w:docLocation"), m_sDocLocation )
|
||||
WritingElement_ReadAttributes_Read_else_if( oReader, _T("w:history"), m_oHistory )
|
||||
WritingElement_ReadAttributes_Read_else_if( oReader, _T("r:id"), m_oId )
|
||||
WritingElement_ReadAttributes_Read_else_if( oReader, _T("relationships:id"),m_oId )
|
||||
WritingElement_ReadAttributes_Read_else_if( oReader, _T("w:tgtFrame"), m_sTgtFrame )
|
||||
WritingElement_ReadAttributes_Read_else_if( oReader, _T("w:tooltip"), m_sTooltip )
|
||||
WritingElement_ReadAttributes_End( oReader )
|
||||
}
|
||||
|
||||
void ReadAttributes(XmlUtils::CXmlLiteReader& oReader);
|
||||
public:
|
||||
|
||||
nullable_string m_sAnchor;
|
||||
nullable_string m_sDestinition;
|
||||
nullable_string m_sDocLocation;
|
||||
|
||||
@ -230,9 +230,9 @@ namespace OOX
|
||||
CComment* pComment = dynamic_cast<CComment*>(pItem);
|
||||
if ((pComment) && (pComment->m_oId.IsInit()))
|
||||
{
|
||||
docx_flat->m_oComments.m_mapComments.insert( std::make_pair( pComment->m_oId->GetValue(), docx_flat->m_oComments.m_arrComments.size()));
|
||||
docx_flat->m_pComments->m_mapComments.insert( std::make_pair( pComment->m_oId->GetValue(), docx_flat->m_pComments->m_arrComments.size()));
|
||||
}
|
||||
docx_flat->m_oComments.m_arrComments.push_back( pComment );
|
||||
docx_flat->m_pComments->m_arrComments.push_back( pComment );
|
||||
|
||||
pItem = NULL;
|
||||
}
|
||||
@ -319,7 +319,16 @@ namespace OOX
|
||||
int nDepthChild = oReader.GetDepth();
|
||||
fromXML(nDepthChild, oReader);
|
||||
}
|
||||
|
||||
else if (L"wx:sect" == sName && !oReader.IsEmptyNode())
|
||||
{
|
||||
int nWxSectDepth = oReader.GetDepth();
|
||||
fromXML(nWxSectDepth, oReader);
|
||||
}
|
||||
else if (L"wx:sub-section" == sName && !oReader.IsEmptyNode())
|
||||
{
|
||||
int nWxSubSectDepth = oReader.GetDepth();
|
||||
fromXML(nWxSubSectDepth, oReader);
|
||||
}
|
||||
if ( pItem )
|
||||
{
|
||||
m_arrItems.push_back( pItem );
|
||||
|
||||
581
Common/DocxFormat/Source/DocxFormat/Logic/Pict.cpp
Normal file
581
Common/DocxFormat/Source/DocxFormat/Logic/Pict.cpp
Normal file
@ -0,0 +1,581 @@
|
||||
/*
|
||||
* (c) Copyright Ascensio System SIA 2010-2019
|
||||
*
|
||||
* This program is a free software product. You can redistribute it and/or
|
||||
* modify it under the terms of the GNU Affero General Public License (AGPL)
|
||||
* version 3 as published by the Free Software Foundation. In accordance with
|
||||
* Section 7(a) of the GNU AGPL its Section 15 shall be amended to the effect
|
||||
* that Ascensio System SIA expressly excludes the warranty of non-infringement
|
||||
* of any third-party rights.
|
||||
*
|
||||
* This program is distributed WITHOUT ANY WARRANTY; without even the implied
|
||||
* warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. For
|
||||
* details, see the GNU AGPL at: http://www.gnu.org/licenses/agpl-3.0.html
|
||||
*
|
||||
* You can contact Ascensio System SIA at 20A-12 Ernesta Birznieka-Upisha
|
||||
* street, Riga, Latvia, EU, LV-1050.
|
||||
*
|
||||
* The interactive user interfaces in modified source and object code versions
|
||||
* of the Program must display Appropriate Legal Notices, as required under
|
||||
* Section 5 of the GNU AGPL version 3.
|
||||
*
|
||||
* Pursuant to Section 7(b) of the License you must retain the original Product
|
||||
* logo when distributing the program. Pursuant to Section 7(e) we decline to
|
||||
* grant you any rights under trademark law for use of our trademarks.
|
||||
*
|
||||
* All the Product's GUI elements, including illustrations and icon sets, as
|
||||
* well as technical writing content are licensed under the terms of the
|
||||
* Creative Commons Attribution-ShareAlike 4.0 International. See the License
|
||||
* terms at http://creativecommons.org/licenses/by-sa/4.0/legalcode
|
||||
*
|
||||
*/
|
||||
#pragma once
|
||||
#include "../DocxFlat.h"
|
||||
#include "../Document.h"
|
||||
|
||||
#include "Pict.h"
|
||||
#include "../../../../../DesktopEditor/raster/ImageFileFormatChecker.h"
|
||||
|
||||
namespace OOX
|
||||
{
|
||||
namespace Logic
|
||||
{
|
||||
void CPicture::fromXML(XmlUtils::CXmlNode &oNode)
|
||||
{
|
||||
if (oNode.IsValid() == false)
|
||||
return;
|
||||
|
||||
m_sXml.Init();
|
||||
*m_sXml = oNode.GetXml(); //для pptx dll
|
||||
|
||||
fromStringXML(m_sXml.get());
|
||||
}
|
||||
|
||||
void CPicture::fromXML(XmlUtils::CXmlLiteReader& oReader)
|
||||
{
|
||||
if (oReader.IsEmptyNode())
|
||||
return;
|
||||
|
||||
m_sXml.Init();
|
||||
*m_sXml = oReader.GetOuterXml(); //для pptx dll
|
||||
|
||||
fromStringXML(m_sXml.get());
|
||||
}
|
||||
void CPicture::fromStringXML(const std::wstring & xml_string)
|
||||
{
|
||||
std::wstring sBegin(L"<root xmlns:wpc=\"http://schemas.microsoft.com/office/word/2010/wordprocessingCanvas\" xmlns:mc=\"http://schemas.openxmlformats.org/markup-compatibility/2006\" xmlns:o=\"urn:schemas-microsoft-com:office:office\" xmlns:r=\"http://schemas.openxmlformats.org/officeDocument/2006/relationships\" xmlns:m=\"http://schemas.openxmlformats.org/officeDocument/2006/math\" xmlns:v=\"urn:schemas-microsoft-com:vml\" xmlns:wp14=\"http://schemas.microsoft.com/office/word/2010/wordprocessingDrawing\" xmlns:wp=\"http://schemas.openxmlformats.org/drawingml/2006/wordprocessingDrawing\" xmlns:w10=\"urn:schemas-microsoft-com:office:word\" xmlns:w=\"http://schemas.openxmlformats.org/wordprocessingml/2006/main\" xmlns:w14=\"http://schemas.microsoft.com/office/word/2010/wordml\" xmlns:wpg=\"http://schemas.microsoft.com/office/word/2010/wordprocessingGroup\" xmlns:wpi=\"http://schemas.microsoft.com/office/word/2010/wordprocessingInk\" xmlns:wne=\"http://schemas.microsoft.com/office/word/2006/wordml\" xmlns:wps=\"http://schemas.microsoft.com/office/word/2010/wordprocessingShape\">");
|
||||
|
||||
std::wstring sEnd(L"</root>");
|
||||
std::wstring sXml = sBegin + xml_string + sEnd;
|
||||
|
||||
XmlUtils::CXmlLiteReader oSubReader;
|
||||
|
||||
oSubReader.FromString(sXml);
|
||||
oSubReader.ReadNextNode();//root
|
||||
oSubReader.ReadNextNode();//pict
|
||||
|
||||
OOX::Vml::CImageData *pImageData = NULL;
|
||||
|
||||
int nCurDepth = oSubReader.GetDepth();
|
||||
while (oSubReader.ReadNextSiblingNode(nCurDepth))
|
||||
{
|
||||
std::wstring sName = oSubReader.GetName();
|
||||
|
||||
WritingElement* pItem = NULL;
|
||||
|
||||
wchar_t wChar0 = sName[0];
|
||||
switch (wChar0)
|
||||
{
|
||||
case 'o':
|
||||
{
|
||||
wchar_t wChar2 = sName[2]; // o:_
|
||||
switch (wChar2)
|
||||
{
|
||||
case 'b':
|
||||
if (_T("o:bottom") == sName)
|
||||
pItem = new OOX::VmlOffice::CStrokeChild(m_pMainDocument);
|
||||
|
||||
break;
|
||||
|
||||
case 'c':
|
||||
if (_T("o:callout") == sName)
|
||||
pItem = new OOX::VmlOffice::CCallout(m_pMainDocument);
|
||||
else if (_T("o:clippath") == sName)
|
||||
pItem = new OOX::VmlOffice::CClipPath(m_pMainDocument);
|
||||
else if (_T("o:column") == sName)
|
||||
pItem = new OOX::VmlOffice::CStrokeChild(m_pMainDocument);
|
||||
else if (_T("o:complex") == sName)
|
||||
pItem = new OOX::VmlOffice::CComplex(m_pMainDocument);
|
||||
|
||||
break;
|
||||
|
||||
case 'd':
|
||||
if (_T("o:diagram") == sName)
|
||||
pItem = new OOX::VmlOffice::CDiagram(m_pMainDocument);
|
||||
|
||||
break;
|
||||
|
||||
case 'e':
|
||||
if (_T("o:equationxml") == sName)
|
||||
pItem = new OOX::VmlOffice::CEquationXml(m_pMainDocument);
|
||||
else if (_T("o:extrusion") == sName)
|
||||
pItem = new OOX::VmlOffice::CExtrusion(m_pMainDocument);
|
||||
|
||||
break;
|
||||
|
||||
case 'f':
|
||||
if (_T("o:fill") == sName)
|
||||
pItem = new OOX::VmlOffice::CFill(m_pMainDocument);
|
||||
|
||||
break;
|
||||
|
||||
case 'i':
|
||||
if (_T("o:ink") == sName)
|
||||
pItem = new OOX::VmlOffice::CInk(m_pMainDocument);
|
||||
|
||||
break;
|
||||
|
||||
case 'l':
|
||||
if (_T("o:left") == sName)
|
||||
pItem = new OOX::VmlOffice::CStrokeChild(m_pMainDocument);
|
||||
else if (_T("o:lock") == sName)
|
||||
pItem = new OOX::VmlOffice::CLock(m_pMainDocument);
|
||||
|
||||
break;
|
||||
|
||||
case 'O':
|
||||
if (_T("o:OLEObject") == sName)
|
||||
pItem = new OOX::VmlOffice::COLEObject(m_pMainDocument);
|
||||
|
||||
break;
|
||||
|
||||
case 'r':
|
||||
if (_T("o:right") == sName)
|
||||
pItem = new OOX::VmlOffice::CStrokeChild(m_pMainDocument);
|
||||
|
||||
break;
|
||||
|
||||
case 's':
|
||||
if (_T("o:shapedefaults") == sName)
|
||||
pItem = new OOX::VmlOffice::CShapeDefaults(m_pMainDocument);
|
||||
else if (_T("o:shapelayout") == sName)
|
||||
pItem = new OOX::VmlOffice::CShapeLayout(m_pMainDocument);
|
||||
else if (_T("o:signatureline") == sName)
|
||||
pItem = new OOX::VmlOffice::CSignatureLine(m_pMainDocument);
|
||||
else if (_T("o:skew") == sName)
|
||||
pItem = new OOX::VmlOffice::CSkew(m_pMainDocument);
|
||||
|
||||
break;
|
||||
|
||||
case 't':
|
||||
if (_T("o:top") == sName)
|
||||
pItem = new OOX::VmlOffice::CStrokeChild(m_pMainDocument);
|
||||
|
||||
break;
|
||||
}
|
||||
|
||||
break;
|
||||
}
|
||||
|
||||
case 'v':
|
||||
{
|
||||
wchar_t wChar2 = sName[2]; // v:_
|
||||
switch (wChar2)
|
||||
{
|
||||
case 'a':
|
||||
if (_T("v:arc") == sName)
|
||||
{
|
||||
m_oShapeElement = new OOX::Vml::CArc(m_pMainDocument);
|
||||
m_oShapeElement->fromXML(oSubReader);
|
||||
}break;
|
||||
|
||||
case 'b':
|
||||
if (_T("v:background") == sName)
|
||||
pItem = new OOX::Vml::CBackground(m_pMainDocument);
|
||||
|
||||
break;
|
||||
|
||||
case 'c':
|
||||
if (_T("v:curve") == sName)
|
||||
{
|
||||
m_oShapeElement = new OOX::Vml::CCurve(m_pMainDocument);//???
|
||||
m_oShapeElement->fromXML(oSubReader);
|
||||
}break;
|
||||
case 'f':
|
||||
if (_T("v:fill") == sName)
|
||||
pItem = new OOX::Vml::CFill(m_pMainDocument);
|
||||
else if (_T("v:formulas") == sName)
|
||||
pItem = new OOX::Vml::CFormulas(m_pMainDocument);
|
||||
|
||||
break;
|
||||
|
||||
case 'g':
|
||||
if (_T("v:group") == sName)
|
||||
{
|
||||
m_oShapeElement = new OOX::Vml::CGroup(m_pMainDocument);
|
||||
m_oShapeElement->fromXML(oSubReader);
|
||||
}break;
|
||||
|
||||
case 'h':
|
||||
if (_T("v:handles") == sName)
|
||||
pItem = new OOX::Vml::CHandles(m_pMainDocument);
|
||||
|
||||
break;
|
||||
|
||||
case 'i':
|
||||
if (_T("v:image") == sName)
|
||||
{
|
||||
m_oShapeElement = new OOX::Vml::CImage(m_pMainDocument);
|
||||
m_oShapeElement->fromXML(oSubReader);
|
||||
}
|
||||
else if (_T("v:imagedata") == sName)
|
||||
{
|
||||
pItem = pImageData = new OOX::Vml::CImageData(m_pMainDocument);
|
||||
}
|
||||
break;
|
||||
|
||||
case 'l':
|
||||
if (_T("v:line") == sName)
|
||||
{
|
||||
m_oShapeElement = new OOX::Vml::CLine(m_pMainDocument);
|
||||
m_oShapeElement->fromXML(oSubReader);
|
||||
}
|
||||
break;
|
||||
|
||||
case 'o':
|
||||
if (_T("v:oval") == sName)
|
||||
{
|
||||
m_oShapeElement = new OOX::Vml::COval(m_pMainDocument);
|
||||
m_oShapeElement->fromXML(oSubReader);
|
||||
}
|
||||
break;
|
||||
|
||||
case 'p':
|
||||
if (_T("v:path") == sName)
|
||||
pItem = new OOX::Vml::CPath(m_pMainDocument);
|
||||
else if (_T("v:polyline") == sName)
|
||||
{
|
||||
m_oShapeElement = new OOX::Vml::CPolyLine(m_pMainDocument);
|
||||
m_oShapeElement->fromXML(oSubReader);
|
||||
}
|
||||
|
||||
break;
|
||||
|
||||
case 'r':
|
||||
if (_T("v:rect") == sName)
|
||||
{
|
||||
m_oShapeElement = new OOX::Vml::CRect(m_pMainDocument);
|
||||
m_oShapeElement->fromXML(oSubReader);
|
||||
}
|
||||
else if (_T("v:roundrect") == sName)
|
||||
{
|
||||
m_oShapeElement = new OOX::Vml::CRoundRect(m_pMainDocument);
|
||||
m_oShapeElement->fromXML(oSubReader);
|
||||
}
|
||||
break;
|
||||
|
||||
case 's':
|
||||
if (_T("v:shadow") == sName)
|
||||
pItem = new OOX::Vml::CShadow(m_pMainDocument);
|
||||
else if (_T("v:shape") == sName)
|
||||
{
|
||||
m_oShapeElement = new OOX::Vml::CShape(m_pMainDocument);
|
||||
m_oShapeElement->fromXML(oSubReader);
|
||||
}
|
||||
else if (_T("v:shapetype") == sName)
|
||||
{
|
||||
m_oShapeType = new OOX::Vml::CShapeType(m_pMainDocument);
|
||||
m_oShapeType->fromXML(oSubReader);
|
||||
}
|
||||
else if (_T("v:stroke") == sName)
|
||||
pItem = new OOX::Vml::CStroke(m_pMainDocument);
|
||||
|
||||
break;
|
||||
|
||||
case 't':
|
||||
if (_T("v:textbox") == sName)
|
||||
pItem = new OOX::Vml::CTextbox(m_pMainDocument);
|
||||
else if (_T("v:textpath") == sName)
|
||||
pItem = new OOX::Vml::CTextPath(m_pMainDocument);
|
||||
|
||||
break;
|
||||
}
|
||||
break;
|
||||
}
|
||||
case 'w':
|
||||
if (L"w:control" == sName)
|
||||
{
|
||||
m_oControl = new OOX::Logic::CControl(m_pMainDocument);
|
||||
m_oControl->fromXML(oSubReader);
|
||||
}
|
||||
else if (L"w:binData" == sName)
|
||||
{
|
||||
m_oBinData = new OOX::Logic::CBinData(m_pMainDocument);
|
||||
m_oBinData->fromXML(oSubReader);
|
||||
|
||||
if (m_oBinData->m_sData.IsInit())
|
||||
{
|
||||
OOX::CDocxFlat* docx_flat = dynamic_cast<OOX::CDocxFlat*>(m_pMainDocument);
|
||||
if (docx_flat)
|
||||
{
|
||||
smart_ptr<OOX::Image> pImageFile = smart_ptr<OOX::Image>(new OOX::Image(m_pMainDocument, true));
|
||||
|
||||
int dstLen = Base64::Base64DecodeGetRequiredLength((int)m_oBinData->m_sData->size());
|
||||
pImageFile->m_Data.resize(dstLen);
|
||||
Base64::Base64Decode(m_oBinData->m_sData->c_str(), (int)m_oBinData->m_sData->size(), pImageFile->m_Data.data(), &dstLen);
|
||||
pImageFile->m_Data.resize(dstLen);
|
||||
|
||||
CImageFileFormatChecker fileChecker;
|
||||
std::wstring ext = fileChecker.DetectFormatByData(pImageFile->m_Data.data(), dstLen);
|
||||
if (false == ext.empty())
|
||||
{
|
||||
OOX::CPath filename(L"image." + ext);
|
||||
pImageFile->set_filename(filename, false, true);
|
||||
|
||||
NSCommon::smart_ptr<OOX::File> file = pImageFile.smart_dynamic_cast<OOX::File>();
|
||||
const OOX::RId rId = docx_flat->m_currentContainer->Add(file);
|
||||
|
||||
if (m_oBinData->m_sName.IsInit())
|
||||
{
|
||||
docx_flat->m_mapImagesId[*m_oBinData->m_sName] = rId.get();
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
break;
|
||||
}
|
||||
|
||||
if (pItem)
|
||||
{
|
||||
m_arrItems.push_back(pItem);
|
||||
pItem->fromXML(oSubReader);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
std::wstring CPicture::toXML() const
|
||||
{
|
||||
std::wstring sResult = _T("<w:pict>");
|
||||
|
||||
for (size_t i = 0; i < m_arrItems.size(); ++i)
|
||||
{
|
||||
if (m_arrItems[i])
|
||||
{
|
||||
sResult += m_arrItems[i]->toXML();
|
||||
}
|
||||
}
|
||||
if (m_oShapeType.IsInit())
|
||||
sResult += m_oShapeType->toXML();
|
||||
|
||||
if (m_oShapeElement.IsInit())
|
||||
sResult += m_oShapeElement->toXML();
|
||||
|
||||
if (m_oControl.IsInit())
|
||||
sResult += m_oControl->toXML();
|
||||
|
||||
//if (m_oBinData.IsInit())
|
||||
// sResult += m_oBinData->toXML();
|
||||
|
||||
sResult += _T("</w:pict>");
|
||||
|
||||
return sResult;
|
||||
}
|
||||
|
||||
void CObject::fromXML(XmlUtils::CXmlLiteReader& oReader)
|
||||
{
|
||||
if (oReader.IsEmptyNode())
|
||||
return;
|
||||
|
||||
m_sXml.Init();
|
||||
*m_sXml = oReader.GetOuterXml(); //для pptx dll
|
||||
|
||||
//альтернатива pptx
|
||||
std::wstring sXml; //??? + ole наверно что то (лень ...)
|
||||
sXml += _T("<root xmlns:wpc=\"http://schemas.microsoft.com/office/word/2010/wordprocessingCanvas\" xmlns:mc=\"http://schemas.openxmlformats.org/markup-compatibility/2006\" xmlns:o=\"urn:schemas-microsoft-com:office:office\" xmlns:r=\"http://schemas.openxmlformats.org/officeDocument/2006/relationships\" xmlns:m=\"http://schemas.openxmlformats.org/officeDocument/2006/math\" xmlns:v=\"urn:schemas-microsoft-com:vml\" xmlns:wp14=\"http://schemas.microsoft.com/office/word/2010/wordprocessingDrawing\" xmlns:wp=\"http://schemas.openxmlformats.org/drawingml/2006/wordprocessingDrawing\" xmlns:w10=\"urn:schemas-microsoft-com:office:word\" xmlns:w=\"http://schemas.openxmlformats.org/wordprocessingml/2006/main\" xmlns:w14=\"http://schemas.microsoft.com/office/word/2010/wordml\" xmlns:wpg=\"http://schemas.microsoft.com/office/word/2010/wordprocessingGroup\" xmlns:wpi=\"http://schemas.microsoft.com/office/word/2010/wordprocessingInk\" xmlns:wne=\"http://schemas.microsoft.com/office/word/2006/wordml\" xmlns:wps=\"http://schemas.microsoft.com/office/word/2010/wordprocessingShape\">");
|
||||
sXml += m_sXml.get();
|
||||
sXml += _T("</root>");
|
||||
|
||||
XmlUtils::CXmlLiteReader oSubReader;
|
||||
oSubReader.FromString(sXml);
|
||||
oSubReader.ReadNextNode();//root
|
||||
oSubReader.ReadNextNode();//pict
|
||||
|
||||
ReadAttributes(oSubReader);
|
||||
|
||||
int nCurDepth = oSubReader.GetDepth();
|
||||
while (oSubReader.ReadNextSiblingNode(nCurDepth))
|
||||
{
|
||||
std::wstring sName = oSubReader.GetName();
|
||||
|
||||
WritingElement* pItem = NULL;
|
||||
|
||||
wchar_t wChar0 = sName[0];
|
||||
switch (wChar0)
|
||||
{
|
||||
case 'o':
|
||||
{
|
||||
wchar_t wChar2 = sName[2]; // o:_
|
||||
switch (wChar2)
|
||||
{
|
||||
case 'b':
|
||||
if (_T("o:bottom") == sName)
|
||||
pItem = new OOX::VmlOffice::CStrokeChild(oSubReader);
|
||||
break;
|
||||
|
||||
case 'c':
|
||||
if (_T("o:callout") == sName)
|
||||
pItem = new OOX::VmlOffice::CCallout(oSubReader);
|
||||
else if (_T("o:clippath") == sName)
|
||||
pItem = new OOX::VmlOffice::CClipPath(oSubReader);
|
||||
else if (_T("o:column") == sName)
|
||||
pItem = new OOX::VmlOffice::CStrokeChild(oSubReader);
|
||||
else if (_T("o:complex") == sName)
|
||||
pItem = new OOX::VmlOffice::CComplex(oSubReader);
|
||||
|
||||
break;
|
||||
|
||||
case 'd':
|
||||
if (_T("o:diagram") == sName)
|
||||
pItem = new OOX::VmlOffice::CDiagram(oSubReader);
|
||||
|
||||
break;
|
||||
|
||||
case 'e':
|
||||
if (_T("o:equationxml") == sName)
|
||||
pItem = new OOX::VmlOffice::CEquationXml(oSubReader);
|
||||
else if (_T("o:extrusion") == sName)
|
||||
pItem = new OOX::VmlOffice::CExtrusion(oSubReader);
|
||||
|
||||
break;
|
||||
|
||||
case 'f':
|
||||
if (_T("o:fill") == sName)
|
||||
pItem = new OOX::VmlOffice::CFill(oSubReader);
|
||||
|
||||
break;
|
||||
|
||||
case 'i':
|
||||
if (_T("o:ink") == sName)
|
||||
pItem = new OOX::VmlOffice::CInk(oSubReader);
|
||||
|
||||
break;
|
||||
|
||||
case 'l':
|
||||
if (_T("o:left") == sName)
|
||||
pItem = new OOX::VmlOffice::CStrokeChild(oSubReader);
|
||||
else if (_T("o:lock") == sName)
|
||||
pItem = new OOX::VmlOffice::CLock(oSubReader);
|
||||
|
||||
break;
|
||||
|
||||
case 'O':// собственно это и есть самый главный под-объект
|
||||
if (_T("o:OLEObject") == sName)
|
||||
m_oOleObject = oSubReader;
|
||||
break;
|
||||
|
||||
case 'r':
|
||||
if (_T("o:right") == sName)
|
||||
pItem = new OOX::VmlOffice::CStrokeChild(oSubReader);
|
||||
break;
|
||||
|
||||
case 's':
|
||||
if (_T("o:shapedefaults") == sName)
|
||||
pItem = new OOX::VmlOffice::CShapeDefaults(oSubReader);
|
||||
else if (_T("o:shapelayout") == sName)
|
||||
pItem = new OOX::VmlOffice::CShapeLayout(oSubReader);
|
||||
else if (_T("o:signatureline") == sName)
|
||||
pItem = new OOX::VmlOffice::CSignatureLine(oSubReader);
|
||||
else if (_T("o:skew") == sName)
|
||||
pItem = new OOX::VmlOffice::CSkew(oSubReader);
|
||||
break;
|
||||
|
||||
case 't':
|
||||
if (_T("o:top") == sName)
|
||||
pItem = new OOX::VmlOffice::CStrokeChild(oSubReader);
|
||||
break;
|
||||
}
|
||||
|
||||
break;
|
||||
}
|
||||
|
||||
case 'v':
|
||||
{
|
||||
wchar_t wChar2 = sName[2]; // v:_
|
||||
switch (wChar2)
|
||||
{
|
||||
case 'b':
|
||||
if (_T("v:background") == sName)
|
||||
pItem = new OOX::Vml::CBackground(oSubReader);
|
||||
break;
|
||||
|
||||
case 'f':
|
||||
if (_T("v:fill") == sName)
|
||||
pItem = new OOX::Vml::CFill(oSubReader);
|
||||
else if (_T("v:formulas") == sName)
|
||||
pItem = new OOX::Vml::CFormulas(oSubReader);
|
||||
break;
|
||||
|
||||
case 'h':
|
||||
if (_T("v:handles") == sName)
|
||||
pItem = new OOX::Vml::CHandles(oSubReader);
|
||||
break;
|
||||
|
||||
case 'i':
|
||||
if (_T("v:image") == sName)
|
||||
pItem = new OOX::Vml::CImage(oSubReader);
|
||||
else if (_T("v:imagedata") == sName)
|
||||
pItem = new OOX::Vml::CImageData(oSubReader);
|
||||
break;
|
||||
case 'p':
|
||||
if (_T("v:path") == sName)
|
||||
pItem = new OOX::Vml::CPath(oSubReader);
|
||||
break;
|
||||
case 'r':
|
||||
if (_T("v:rect") == sName)
|
||||
m_oShape = oSubReader;
|
||||
break;
|
||||
case 's':
|
||||
if (_T("v:shadow") == sName)
|
||||
pItem = new OOX::Vml::CShadow(oSubReader);
|
||||
else if (_T("v:shape") == sName)
|
||||
m_oShape = oSubReader;
|
||||
else if (_T("v:shapetype") == sName)
|
||||
m_oShapeType = oSubReader;
|
||||
else if (_T("v:stroke") == sName)
|
||||
pItem = new OOX::Vml::CStroke(oSubReader);
|
||||
break;
|
||||
|
||||
case 't':
|
||||
if (_T("v:textbox") == sName)
|
||||
pItem = new OOX::Vml::CTextbox(oSubReader);
|
||||
else if (_T("v:textpath") == sName)
|
||||
pItem = new OOX::Vml::CTextPath(oSubReader);
|
||||
break;
|
||||
}
|
||||
break;
|
||||
}
|
||||
case 'w':
|
||||
if (L"w:control" == sName)
|
||||
m_oControl = oSubReader;
|
||||
else if (L"w:objectEmbed" == sName)
|
||||
m_oOleObject = oSubReader;
|
||||
else if (L"w:drawing" == sName)
|
||||
m_oDrawing = oSubReader;
|
||||
|
||||
break;
|
||||
}
|
||||
|
||||
if (pItem)
|
||||
{
|
||||
m_arrItems.push_back(pItem);
|
||||
}
|
||||
}
|
||||
}
|
||||
std::wstring CObject::toXML() const
|
||||
{
|
||||
return _T("<w:object/>");
|
||||
}
|
||||
} // namespace Logic
|
||||
} // namespace OOX
|
||||
@ -73,7 +73,6 @@ namespace OOX
|
||||
if (m_sData.IsInit())
|
||||
{
|
||||
}
|
||||
|
||||
sResult += _T("</w:binData>");
|
||||
|
||||
return sResult;
|
||||
@ -194,316 +193,11 @@ namespace OOX
|
||||
{
|
||||
}
|
||||
|
||||
virtual void fromXML(XmlUtils::CXmlNode &oNode)
|
||||
{
|
||||
if ( oNode.IsValid() == false)
|
||||
return;
|
||||
virtual void fromXML(XmlUtils::CXmlNode &oNode);
|
||||
virtual void fromXML(XmlUtils::CXmlLiteReader& oReader);
|
||||
void fromStringXML(const std::wstring & xml_string);
|
||||
|
||||
m_sXml.Init();
|
||||
*m_sXml = oNode.GetXml(); //для pptx dll
|
||||
|
||||
fromStringXML(m_sXml.get());
|
||||
}
|
||||
|
||||
virtual void fromXML(XmlUtils::CXmlLiteReader& oReader)
|
||||
{
|
||||
if ( oReader.IsEmptyNode() )
|
||||
return;
|
||||
|
||||
m_sXml.Init();
|
||||
*m_sXml = oReader.GetOuterXml(); //для pptx dll
|
||||
|
||||
fromStringXML(m_sXml.get());
|
||||
}
|
||||
void fromStringXML(const std::wstring & xml_string)
|
||||
{
|
||||
std::wstring sBegin(L"<root xmlns:wpc=\"http://schemas.microsoft.com/office/word/2010/wordprocessingCanvas\" xmlns:mc=\"http://schemas.openxmlformats.org/markup-compatibility/2006\" xmlns:o=\"urn:schemas-microsoft-com:office:office\" xmlns:r=\"http://schemas.openxmlformats.org/officeDocument/2006/relationships\" xmlns:m=\"http://schemas.openxmlformats.org/officeDocument/2006/math\" xmlns:v=\"urn:schemas-microsoft-com:vml\" xmlns:wp14=\"http://schemas.microsoft.com/office/word/2010/wordprocessingDrawing\" xmlns:wp=\"http://schemas.openxmlformats.org/drawingml/2006/wordprocessingDrawing\" xmlns:w10=\"urn:schemas-microsoft-com:office:word\" xmlns:w=\"http://schemas.openxmlformats.org/wordprocessingml/2006/main\" xmlns:w14=\"http://schemas.microsoft.com/office/word/2010/wordml\" xmlns:wpg=\"http://schemas.microsoft.com/office/word/2010/wordprocessingGroup\" xmlns:wpi=\"http://schemas.microsoft.com/office/word/2010/wordprocessingInk\" xmlns:wne=\"http://schemas.microsoft.com/office/word/2006/wordml\" xmlns:wps=\"http://schemas.microsoft.com/office/word/2010/wordprocessingShape\">");
|
||||
|
||||
std::wstring sEnd(L"</root>");
|
||||
std::wstring sXml = sBegin + xml_string + sEnd;
|
||||
|
||||
XmlUtils::CXmlLiteReader oSubReader;
|
||||
|
||||
oSubReader.FromString(sXml);
|
||||
oSubReader.ReadNextNode();//root
|
||||
oSubReader.ReadNextNode();//pict
|
||||
|
||||
int nCurDepth = oSubReader.GetDepth();
|
||||
while ( oSubReader.ReadNextSiblingNode( nCurDepth ) )
|
||||
{
|
||||
std::wstring sName = oSubReader.GetName();
|
||||
|
||||
WritingElement* pItem = NULL;
|
||||
|
||||
wchar_t wChar0 = sName[0];
|
||||
switch (wChar0)
|
||||
{
|
||||
case 'o':
|
||||
{
|
||||
wchar_t wChar2 = sName[2]; // o:_
|
||||
switch ( wChar2 )
|
||||
{
|
||||
case 'b':
|
||||
if ( _T("o:bottom") == sName )
|
||||
pItem = new OOX::VmlOffice::CStrokeChild( m_pMainDocument );
|
||||
|
||||
break;
|
||||
|
||||
case 'c':
|
||||
if ( _T("o:callout") == sName )
|
||||
pItem = new OOX::VmlOffice::CCallout( m_pMainDocument );
|
||||
else if ( _T("o:clippath") == sName )
|
||||
pItem = new OOX::VmlOffice::CClipPath( m_pMainDocument );
|
||||
else if ( _T("o:column") == sName )
|
||||
pItem = new OOX::VmlOffice::CStrokeChild( m_pMainDocument );
|
||||
else if ( _T("o:complex") == sName )
|
||||
pItem = new OOX::VmlOffice::CComplex( m_pMainDocument );
|
||||
|
||||
break;
|
||||
|
||||
case 'd':
|
||||
if ( _T("o:diagram") == sName )
|
||||
pItem = new OOX::VmlOffice::CDiagram( m_pMainDocument );
|
||||
|
||||
break;
|
||||
|
||||
case 'e':
|
||||
if ( _T("o:equationxml") == sName )
|
||||
pItem = new OOX::VmlOffice::CEquationXml( m_pMainDocument );
|
||||
else if ( _T("o:extrusion") == sName )
|
||||
pItem = new OOX::VmlOffice::CExtrusion( m_pMainDocument );
|
||||
|
||||
break;
|
||||
|
||||
case 'f':
|
||||
if ( _T("o:fill") == sName )
|
||||
pItem = new OOX::VmlOffice::CFill( m_pMainDocument );
|
||||
|
||||
break;
|
||||
|
||||
case 'i':
|
||||
if ( _T("o:ink") == sName )
|
||||
pItem = new OOX::VmlOffice::CInk( m_pMainDocument );
|
||||
|
||||
break;
|
||||
|
||||
case 'l':
|
||||
if ( _T("o:left") == sName )
|
||||
pItem = new OOX::VmlOffice::CStrokeChild( m_pMainDocument );
|
||||
else if ( _T("o:lock") == sName )
|
||||
pItem = new OOX::VmlOffice::CLock( m_pMainDocument );
|
||||
|
||||
break;
|
||||
|
||||
case 'O':
|
||||
if ( _T("o:OLEObject") == sName )
|
||||
pItem = new OOX::VmlOffice::COLEObject( m_pMainDocument );
|
||||
|
||||
break;
|
||||
|
||||
case 'r':
|
||||
if ( _T("o:right") == sName )
|
||||
pItem = new OOX::VmlOffice::CStrokeChild( m_pMainDocument );
|
||||
|
||||
break;
|
||||
|
||||
case 's':
|
||||
if ( _T("o:shapedefaults") == sName )
|
||||
pItem = new OOX::VmlOffice::CShapeDefaults( m_pMainDocument );
|
||||
else if ( _T("o:shapelayout") == sName )
|
||||
pItem = new OOX::VmlOffice::CShapeLayout( m_pMainDocument );
|
||||
else if ( _T("o:signatureline") == sName )
|
||||
pItem = new OOX::VmlOffice::CSignatureLine( m_pMainDocument );
|
||||
else if ( _T("o:skew") == sName )
|
||||
pItem = new OOX::VmlOffice::CSkew( m_pMainDocument );
|
||||
|
||||
break;
|
||||
|
||||
case 't':
|
||||
if ( _T("o:top") == sName )
|
||||
pItem = new OOX::VmlOffice::CStrokeChild( m_pMainDocument );
|
||||
|
||||
break;
|
||||
}
|
||||
|
||||
break;
|
||||
}
|
||||
|
||||
case 'v':
|
||||
{
|
||||
wchar_t wChar2 = sName[2]; // v:_
|
||||
switch ( wChar2 )
|
||||
{
|
||||
case 'a':
|
||||
if ( _T("v:arc") == sName )
|
||||
{
|
||||
m_oShapeElement = new OOX::Vml::CArc(m_pMainDocument);
|
||||
m_oShapeElement->fromXML(oSubReader );
|
||||
}break;
|
||||
|
||||
case 'b':
|
||||
if ( _T("v:background") == sName )
|
||||
pItem = new OOX::Vml::CBackground( m_pMainDocument );
|
||||
|
||||
break;
|
||||
|
||||
case 'c':
|
||||
if ( _T("v:curve") == sName )
|
||||
{
|
||||
m_oShapeElement = new OOX::Vml::CCurve(m_pMainDocument);//???
|
||||
m_oShapeElement->fromXML(oSubReader );
|
||||
}break;
|
||||
case 'f':
|
||||
if ( _T("v:fill") == sName )
|
||||
pItem = new OOX::Vml::CFill( m_pMainDocument );
|
||||
else if ( _T("v:formulas") == sName )
|
||||
pItem = new OOX::Vml::CFormulas( m_pMainDocument );
|
||||
|
||||
break;
|
||||
|
||||
case 'g':
|
||||
if ( _T("v:group") == sName )
|
||||
{
|
||||
m_oShapeElement = new OOX::Vml::CGroup(m_pMainDocument);
|
||||
m_oShapeElement->fromXML(oSubReader );
|
||||
}break;
|
||||
|
||||
case 'h':
|
||||
if ( _T("v:handles") == sName )
|
||||
pItem = new OOX::Vml::CHandles( m_pMainDocument );
|
||||
|
||||
break;
|
||||
|
||||
case 'i':
|
||||
if ( _T("v:image") == sName )
|
||||
{
|
||||
m_oShapeElement = new OOX::Vml::CImage(m_pMainDocument);
|
||||
m_oShapeElement->fromXML(oSubReader );
|
||||
}
|
||||
else if ( _T("v:imagedata") == sName )
|
||||
{
|
||||
pItem = new OOX::Vml::CImageData( m_pMainDocument );
|
||||
}
|
||||
break;
|
||||
|
||||
case 'l':
|
||||
if ( _T("v:line") == sName )
|
||||
{
|
||||
m_oShapeElement = new OOX::Vml::CLine( m_pMainDocument );
|
||||
m_oShapeElement->fromXML(oSubReader );
|
||||
}
|
||||
break;
|
||||
|
||||
case 'o':
|
||||
if ( _T("v:oval") == sName )
|
||||
{
|
||||
m_oShapeElement = new OOX::Vml::COval( m_pMainDocument );
|
||||
m_oShapeElement->fromXML(oSubReader );
|
||||
}
|
||||
break;
|
||||
|
||||
case 'p':
|
||||
if ( _T("v:path") == sName )
|
||||
pItem = new OOX::Vml::CPath( m_pMainDocument );
|
||||
else if ( _T("v:polyline") == sName )
|
||||
{
|
||||
m_oShapeElement = new OOX::Vml::CPolyLine( m_pMainDocument );
|
||||
m_oShapeElement->fromXML(oSubReader );
|
||||
}
|
||||
|
||||
break;
|
||||
|
||||
case 'r':
|
||||
if ( _T("v:rect") == sName )
|
||||
{
|
||||
m_oShapeElement = new OOX::Vml::CRect( m_pMainDocument );
|
||||
m_oShapeElement->fromXML(oSubReader );
|
||||
}
|
||||
else if ( _T("v:roundrect") == sName )
|
||||
{
|
||||
m_oShapeElement = new OOX::Vml::CRoundRect( m_pMainDocument );
|
||||
m_oShapeElement->fromXML(oSubReader );
|
||||
}
|
||||
break;
|
||||
|
||||
case 's':
|
||||
if ( _T("v:shadow") == sName )
|
||||
pItem = new OOX::Vml::CShadow( m_pMainDocument );
|
||||
else if ( _T("v:shape") == sName )
|
||||
{
|
||||
m_oShapeElement = new OOX::Vml::CShape( m_pMainDocument );
|
||||
m_oShapeElement->fromXML(oSubReader );
|
||||
}
|
||||
else if ( _T("v:shapetype") == sName )
|
||||
{
|
||||
m_oShapeType = new OOX::Vml::CShapeType( m_pMainDocument );
|
||||
m_oShapeType->fromXML(oSubReader );
|
||||
}
|
||||
else if ( _T("v:stroke") == sName )
|
||||
pItem = new OOX::Vml::CStroke( m_pMainDocument );
|
||||
|
||||
break;
|
||||
|
||||
case 't':
|
||||
if ( _T("v:textbox") == sName )
|
||||
pItem = new OOX::Vml::CTextbox( m_pMainDocument );
|
||||
else if ( _T("v:textpath") == sName )
|
||||
pItem = new OOX::Vml::CTextPath( m_pMainDocument );
|
||||
|
||||
break;
|
||||
}
|
||||
break;
|
||||
}
|
||||
case 'w':
|
||||
if ( L"w:control" == sName )
|
||||
{
|
||||
m_oControl = new OOX::Logic::CControl( m_pMainDocument );
|
||||
m_oControl->fromXML(oSubReader );
|
||||
}
|
||||
else if ( L"w:binData" == sName )
|
||||
{
|
||||
m_oBinData = new OOX::Logic::CBinData( m_pMainDocument );
|
||||
m_oBinData->fromXML(oSubReader );
|
||||
}
|
||||
|
||||
break;
|
||||
}
|
||||
|
||||
if ( pItem )
|
||||
{
|
||||
m_arrItems.push_back( pItem );
|
||||
pItem->fromXML(oSubReader );
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
virtual std::wstring toXML() const
|
||||
{
|
||||
std::wstring sResult = _T("<w:pict>");
|
||||
|
||||
for ( size_t i = 0; i < m_arrItems.size(); ++i)
|
||||
{
|
||||
if ( m_arrItems[i] )
|
||||
{
|
||||
sResult += m_arrItems[i]->toXML();
|
||||
}
|
||||
}
|
||||
if (m_oShapeType.IsInit())
|
||||
sResult += m_oShapeType->toXML();
|
||||
|
||||
if (m_oShapeElement.IsInit())
|
||||
sResult += m_oShapeElement->toXML();
|
||||
|
||||
if ( m_oControl.IsInit() )
|
||||
sResult += m_oControl->toXML();
|
||||
|
||||
if (m_oBinData.IsInit())
|
||||
sResult += m_oBinData->toXML();
|
||||
|
||||
sResult += _T("</w:pict>");
|
||||
|
||||
return sResult;
|
||||
}
|
||||
virtual std::wstring toXML() const;
|
||||
|
||||
virtual EElementType getType() const
|
||||
{
|
||||
@ -536,200 +230,8 @@ namespace OOX
|
||||
virtual void fromXML(XmlUtils::CXmlNode& oNode)
|
||||
{
|
||||
}
|
||||
virtual void fromXML(XmlUtils::CXmlLiteReader& oReader)
|
||||
{
|
||||
if ( oReader.IsEmptyNode() )
|
||||
return;
|
||||
|
||||
m_sXml.Init();
|
||||
*m_sXml = oReader.GetOuterXml(); //для pptx dll
|
||||
|
||||
//альтернатива pptx
|
||||
std::wstring sXml; //??? + ole наверно что то (лень ...)
|
||||
sXml += _T("<root xmlns:wpc=\"http://schemas.microsoft.com/office/word/2010/wordprocessingCanvas\" xmlns:mc=\"http://schemas.openxmlformats.org/markup-compatibility/2006\" xmlns:o=\"urn:schemas-microsoft-com:office:office\" xmlns:r=\"http://schemas.openxmlformats.org/officeDocument/2006/relationships\" xmlns:m=\"http://schemas.openxmlformats.org/officeDocument/2006/math\" xmlns:v=\"urn:schemas-microsoft-com:vml\" xmlns:wp14=\"http://schemas.microsoft.com/office/word/2010/wordprocessingDrawing\" xmlns:wp=\"http://schemas.openxmlformats.org/drawingml/2006/wordprocessingDrawing\" xmlns:w10=\"urn:schemas-microsoft-com:office:word\" xmlns:w=\"http://schemas.openxmlformats.org/wordprocessingml/2006/main\" xmlns:w14=\"http://schemas.microsoft.com/office/word/2010/wordml\" xmlns:wpg=\"http://schemas.microsoft.com/office/word/2010/wordprocessingGroup\" xmlns:wpi=\"http://schemas.microsoft.com/office/word/2010/wordprocessingInk\" xmlns:wne=\"http://schemas.microsoft.com/office/word/2006/wordml\" xmlns:wps=\"http://schemas.microsoft.com/office/word/2010/wordprocessingShape\">");
|
||||
sXml += m_sXml.get();
|
||||
sXml += _T("</root>");
|
||||
|
||||
XmlUtils::CXmlLiteReader oSubReader;
|
||||
oSubReader.FromString(sXml);
|
||||
oSubReader.ReadNextNode();//root
|
||||
oSubReader.ReadNextNode();//pict
|
||||
|
||||
ReadAttributes(oSubReader);
|
||||
|
||||
int nCurDepth = oSubReader.GetDepth();
|
||||
while ( oSubReader.ReadNextSiblingNode( nCurDepth ) )
|
||||
{
|
||||
std::wstring sName = oSubReader.GetName();
|
||||
|
||||
WritingElement* pItem = NULL;
|
||||
|
||||
wchar_t wChar0 = sName[0];
|
||||
switch (wChar0)
|
||||
{
|
||||
case 'o':
|
||||
{
|
||||
wchar_t wChar2 = sName[2]; // o:_
|
||||
switch ( wChar2 )
|
||||
{
|
||||
case 'b':
|
||||
if ( _T("o:bottom") == sName )
|
||||
pItem = new OOX::VmlOffice::CStrokeChild( oSubReader );
|
||||
break;
|
||||
|
||||
case 'c':
|
||||
if ( _T("o:callout") == sName )
|
||||
pItem = new OOX::VmlOffice::CCallout( oSubReader );
|
||||
else if ( _T("o:clippath") == sName )
|
||||
pItem = new OOX::VmlOffice::CClipPath( oSubReader );
|
||||
else if ( _T("o:column") == sName )
|
||||
pItem = new OOX::VmlOffice::CStrokeChild( oSubReader );
|
||||
else if ( _T("o:complex") == sName )
|
||||
pItem = new OOX::VmlOffice::CComplex( oSubReader );
|
||||
|
||||
break;
|
||||
|
||||
case 'd':
|
||||
if ( _T("o:diagram") == sName )
|
||||
pItem = new OOX::VmlOffice::CDiagram( oSubReader );
|
||||
|
||||
break;
|
||||
|
||||
case 'e':
|
||||
if ( _T("o:equationxml") == sName )
|
||||
pItem = new OOX::VmlOffice::CEquationXml( oSubReader );
|
||||
else if ( _T("o:extrusion") == sName )
|
||||
pItem = new OOX::VmlOffice::CExtrusion( oSubReader );
|
||||
|
||||
break;
|
||||
|
||||
case 'f':
|
||||
if ( _T("o:fill") == sName )
|
||||
pItem = new OOX::VmlOffice::CFill( oSubReader );
|
||||
|
||||
break;
|
||||
|
||||
case 'i':
|
||||
if ( _T("o:ink") == sName )
|
||||
pItem = new OOX::VmlOffice::CInk( oSubReader );
|
||||
|
||||
break;
|
||||
|
||||
case 'l':
|
||||
if ( _T("o:left") == sName )
|
||||
pItem = new OOX::VmlOffice::CStrokeChild( oSubReader );
|
||||
else if ( _T("o:lock") == sName )
|
||||
pItem = new OOX::VmlOffice::CLock( oSubReader );
|
||||
|
||||
break;
|
||||
|
||||
case 'O':// собственно это и есть самый главный под-объект
|
||||
if ( _T("o:OLEObject") == sName )
|
||||
m_oOleObject = oSubReader ;
|
||||
break;
|
||||
|
||||
case 'r':
|
||||
if ( _T("o:right") == sName )
|
||||
pItem = new OOX::VmlOffice::CStrokeChild( oSubReader );
|
||||
break;
|
||||
|
||||
case 's':
|
||||
if ( _T("o:shapedefaults") == sName )
|
||||
pItem = new OOX::VmlOffice::CShapeDefaults( oSubReader );
|
||||
else if ( _T("o:shapelayout") == sName )
|
||||
pItem = new OOX::VmlOffice::CShapeLayout( oSubReader );
|
||||
else if ( _T("o:signatureline") == sName )
|
||||
pItem = new OOX::VmlOffice::CSignatureLine( oSubReader );
|
||||
else if ( _T("o:skew") == sName )
|
||||
pItem = new OOX::VmlOffice::CSkew( oSubReader );
|
||||
break;
|
||||
|
||||
case 't':
|
||||
if ( _T("o:top") == sName )
|
||||
pItem = new OOX::VmlOffice::CStrokeChild( oSubReader );
|
||||
break;
|
||||
}
|
||||
|
||||
break;
|
||||
}
|
||||
|
||||
case 'v':
|
||||
{
|
||||
wchar_t wChar2 = sName[2]; // v:_
|
||||
switch ( wChar2 )
|
||||
{
|
||||
case 'b':
|
||||
if ( _T("v:background") == sName )
|
||||
pItem = new OOX::Vml::CBackground( oSubReader );
|
||||
break;
|
||||
|
||||
case 'f':
|
||||
if ( _T("v:fill") == sName )
|
||||
pItem = new OOX::Vml::CFill( oSubReader );
|
||||
else if ( _T("v:formulas") == sName )
|
||||
pItem = new OOX::Vml::CFormulas( oSubReader );
|
||||
break;
|
||||
|
||||
case 'h':
|
||||
if ( _T("v:handles") == sName )
|
||||
pItem = new OOX::Vml::CHandles( oSubReader );
|
||||
break;
|
||||
|
||||
case 'i':
|
||||
if ( _T("v:image") == sName )
|
||||
pItem = new OOX::Vml::CImage( oSubReader );
|
||||
else if ( _T("v:imagedata") == sName )
|
||||
pItem = new OOX::Vml::CImageData( oSubReader );
|
||||
break;
|
||||
case 'p':
|
||||
if ( _T("v:path") == sName )
|
||||
pItem = new OOX::Vml::CPath( oSubReader );
|
||||
break;
|
||||
case 'r':
|
||||
if ( _T("v:rect") == sName )
|
||||
m_oShape = oSubReader;
|
||||
break;
|
||||
case 's':
|
||||
if ( _T("v:shadow") == sName )
|
||||
pItem = new OOX::Vml::CShadow( oSubReader );
|
||||
else if ( _T("v:shape") == sName )
|
||||
m_oShape = oSubReader;
|
||||
else if ( _T("v:shapetype") == sName )
|
||||
m_oShapeType = oSubReader;
|
||||
else if ( _T("v:stroke") == sName )
|
||||
pItem = new OOX::Vml::CStroke( oSubReader );
|
||||
break;
|
||||
|
||||
case 't':
|
||||
if ( _T("v:textbox") == sName )
|
||||
pItem = new OOX::Vml::CTextbox( oSubReader );
|
||||
else if ( _T("v:textpath") == sName )
|
||||
pItem = new OOX::Vml::CTextPath( oSubReader );
|
||||
break;
|
||||
}
|
||||
break;
|
||||
}
|
||||
case 'w':
|
||||
if (L"w:control" == sName )
|
||||
m_oControl = oSubReader;
|
||||
else if (L"w:objectEmbed" == sName)
|
||||
m_oOleObject = oSubReader;
|
||||
else if (L"w:drawing" == sName)
|
||||
m_oDrawing = oSubReader;
|
||||
|
||||
break;
|
||||
}
|
||||
|
||||
if ( pItem )
|
||||
{
|
||||
m_arrItems.push_back( pItem );
|
||||
}
|
||||
}
|
||||
}
|
||||
virtual std::wstring toXML() const
|
||||
{
|
||||
return _T("<w:object/>");
|
||||
}
|
||||
virtual void fromXML(XmlUtils::CXmlLiteReader& oReader);
|
||||
virtual std::wstring toXML() const;
|
||||
|
||||
virtual EElementType getType() const
|
||||
{
|
||||
|
||||
@ -32,6 +32,10 @@
|
||||
#include "../DocxFlat.h"
|
||||
#include "../Docx.h"
|
||||
#include "../Document.h"
|
||||
#include "../Endnote.h"
|
||||
#include "../Footnote.h"
|
||||
#include "../Comments.h"
|
||||
#include "../Settings/Settings.h"
|
||||
|
||||
#include "Run.h"
|
||||
|
||||
@ -243,19 +247,26 @@ namespace OOX
|
||||
else if ( _T("w:endnote") == sName )
|
||||
{
|
||||
CEndnoteReference *pEndRef = new CEndnoteReference(document);
|
||||
CFtnEdn *pEnd = new CFtnEdn( document );
|
||||
|
||||
pEnd->fromXML(oReader);
|
||||
CFtnEdn *pEndnote = new CFtnEdn( document );
|
||||
pEndnote->fromXML(oReader);
|
||||
|
||||
CDocxFlat* docx_flat = dynamic_cast<CDocxFlat*>(document);
|
||||
if (docx_flat)
|
||||
{
|
||||
pEnd->m_oId.Init();
|
||||
pEnd->m_oId->SetValue((int)(docx_flat->m_oEndnotes.m_arrEndnote.size() + 1));
|
||||
pEndRef->m_oId = pEnd->m_oId;
|
||||
pEndnote->m_oId.Init();
|
||||
pEndnote->m_oId->SetValue((int)(docx_flat->m_pEndnotes->m_arrEndnote.size() + 1));
|
||||
|
||||
docx_flat->m_oEndnotes.m_arrEndnote.push_back(pEnd);
|
||||
docx_flat->m_oEndnotes.m_mapEndnote.insert(std::make_pair(pEnd->m_oId->GetValue(), pEnd));
|
||||
pEndRef->m_oId = pEndnote->m_oId;
|
||||
|
||||
docx_flat->m_pEndnotes->m_arrEndnote.push_back(pEndnote);
|
||||
docx_flat->m_pEndnotes->m_mapEndnote.insert(std::make_pair(pEndnote->m_oId->GetValue(), pEndnote));
|
||||
|
||||
if (!docx_flat->m_pSettings->m_oEndnotePr.Init())
|
||||
docx_flat->m_pSettings->m_oEndnotePr.Init();
|
||||
|
||||
docx_flat->m_pSettings->m_oEndnotePr->m_arrEndnote.push_back(new CFtnEdnSepRef());
|
||||
docx_flat->m_pSettings->m_oEndnotePr->m_arrEndnote.back()->m_oId = pEndnote->m_oId;
|
||||
docx_flat->m_pSettings->m_oEndnotePr->m_arrEndnote.back()->m_eType = OOX::et_w_endnote;
|
||||
}
|
||||
pItem = pEndRef;
|
||||
}
|
||||
@ -268,19 +279,24 @@ namespace OOX
|
||||
else if ( _T("w:footnote") == sName )
|
||||
{
|
||||
CFootnoteReference *pFootRef = new CFootnoteReference(document);
|
||||
CFtnEdn *pFoot = new CFtnEdn( document );
|
||||
|
||||
pFoot->fromXML(oReader);
|
||||
CFtnEdn *pFootnote = new CFtnEdn( document );
|
||||
pFootnote->m_eType = OOX::et_w_footnote;
|
||||
|
||||
pFootnote->fromXML(oReader);
|
||||
|
||||
CDocxFlat* docx_flat = dynamic_cast<CDocxFlat*>(document);
|
||||
if (docx_flat)
|
||||
{
|
||||
pFoot->m_oId.Init();
|
||||
pFoot->m_oId->SetValue((int)(docx_flat->m_oFootnotes.m_arrFootnote.size() + 1));
|
||||
pFootRef->m_oId = pFoot->m_oId;
|
||||
pFootnote->m_oId.Init();
|
||||
pFootnote->m_oId->SetValue((int)(docx_flat->m_pFootnotes->m_arrFootnote.size() + 1));
|
||||
pFootRef->m_oId = pFootnote->m_oId;
|
||||
|
||||
docx_flat->m_oFootnotes.m_arrFootnote.push_back(pFoot);
|
||||
docx_flat->m_oFootnotes.m_mapFootnote.insert(std::make_pair(pFoot->m_oId->GetValue(), pFoot));
|
||||
docx_flat->m_pFootnotes->m_arrFootnote.push_back(pFootnote);
|
||||
docx_flat->m_pFootnotes->m_mapFootnote.insert(std::make_pair(pFootnote->m_oId->GetValue(), pFootnote));
|
||||
|
||||
docx_flat->m_pSettings->m_oFootnotePr->m_arrFootnote.push_back(new CFtnEdnSepRef());
|
||||
docx_flat->m_pSettings->m_oFootnotePr->m_arrFootnote.back()->m_oId = pFootnote->m_oId;
|
||||
docx_flat->m_pSettings->m_oFootnotePr->m_arrFootnote.back()->m_eType = OOX::et_w_footnote;
|
||||
}
|
||||
pItem = pFootRef;
|
||||
}
|
||||
@ -362,9 +378,9 @@ namespace OOX
|
||||
CComment* pComment = dynamic_cast<CComment*>(pItem);
|
||||
if ((pComment) && (pComment->m_oId.IsInit()))
|
||||
{
|
||||
docx_flat->m_oComments.m_mapComments.insert( std::make_pair( pComment->m_oId->GetValue(), docx_flat->m_oComments.m_arrComments.size()));
|
||||
docx_flat->m_pComments->m_mapComments.insert( std::make_pair( pComment->m_oId->GetValue(), docx_flat->m_pComments->m_arrComments.size()));
|
||||
}
|
||||
docx_flat->m_oComments.m_arrComments.push_back( pComment );
|
||||
docx_flat->m_pComments->m_arrComments.push_back( pComment );
|
||||
|
||||
pItem = NULL;
|
||||
}
|
||||
|
||||
@ -759,7 +759,7 @@ namespace OOX
|
||||
else
|
||||
sResult = _T("<w:t>");
|
||||
|
||||
sResult += m_sText;
|
||||
sResult += XmlUtils::EncodeXmlString(m_sText);
|
||||
sResult += _T("</w:t>");
|
||||
|
||||
return sResult;
|
||||
|
||||
@ -318,41 +318,51 @@ namespace OOX
|
||||
m_oVAlign = oReader;
|
||||
else if ( L"w:hdr" == sName )
|
||||
{
|
||||
ComplexTypes::Word::CHdrFtrRef *pHeaderRef = new ComplexTypes::Word::CHdrFtrRef();
|
||||
OOX::CHdrFtr* pHeader = new OOX::CHdrFtr(document);
|
||||
if (pHeaderRef && pHeader)
|
||||
CDocxFlat* docx_flat = dynamic_cast<CDocxFlat*>(document);
|
||||
if (docx_flat)
|
||||
{
|
||||
pHeader->fromXML(oReader);
|
||||
ComplexTypes::Word::CHdrFtrRef *pHeaderRef = new ComplexTypes::Word::CHdrFtrRef();
|
||||
NSCommon::smart_ptr<OOX::CHdrFtr> pHeader = new OOX::CHdrFtr(document);
|
||||
|
||||
pHeaderRef->m_oId = L"hdrId" + std::to_wstring(m_arrHeaderReference.size() + 1);
|
||||
pHeaderRef->m_oType = pHeader->m_oType;
|
||||
|
||||
m_arrHeaderReference.push_back( pHeaderRef );
|
||||
|
||||
CDocxFlat* docx_flat = dynamic_cast<CDocxFlat*>(document);
|
||||
if (docx_flat)
|
||||
if (pHeaderRef && pHeader.IsInit())
|
||||
{
|
||||
docx_flat->m_mapHeadersFooters.insert(std::make_pair(pHeaderRef->m_oId->ToString(), pHeader));
|
||||
OOX::IFileContainer* oldContainer = docx_flat->m_currentContainer;
|
||||
docx_flat->m_currentContainer = dynamic_cast<OOX::IFileContainer*>(pHeader.GetPointer());
|
||||
pHeader->fromXML(oReader);
|
||||
docx_flat->m_currentContainer = oldContainer;
|
||||
|
||||
NSCommon::smart_ptr<OOX::File> file = pHeader.smart_dynamic_cast<OOX::File>();
|
||||
OOX::RId rId = docx_flat->m_currentContainer->Add(file);
|
||||
|
||||
pHeaderRef->m_oId = rId.get();
|
||||
pHeaderRef->m_oType = pHeader->m_oType;
|
||||
|
||||
m_arrHeaderReference.push_back(pHeaderRef);
|
||||
}
|
||||
}
|
||||
}
|
||||
else if ( L"w:ftr" == sName )
|
||||
{
|
||||
ComplexTypes::Word::CHdrFtrRef *pFooterRef = new ComplexTypes::Word::CHdrFtrRef();
|
||||
OOX::CHdrFtr* pFooter = new OOX::CHdrFtr(document);
|
||||
if (pFooter && pFooterRef)
|
||||
CDocxFlat* docx_flat = dynamic_cast<CDocxFlat*>(document);
|
||||
if (docx_flat)
|
||||
{
|
||||
pFooter->fromXML(oReader);
|
||||
ComplexTypes::Word::CHdrFtrRef *pFooterRef = new ComplexTypes::Word::CHdrFtrRef();
|
||||
NSCommon::smart_ptr<OOX::CHdrFtr> pFooter = new OOX::CHdrFtr(document);
|
||||
|
||||
pFooterRef->m_oId = L"ftrId" + std::to_wstring(m_arrFooterReference.size() + 1);
|
||||
pFooterRef->m_oType = pFooter->m_oType;
|
||||
|
||||
m_arrFooterReference.push_back( pFooterRef );
|
||||
|
||||
CDocxFlat* docx_flat = dynamic_cast<CDocxFlat*>(document);
|
||||
if (docx_flat)
|
||||
if (pFooter.IsInit() && pFooterRef)
|
||||
{
|
||||
docx_flat->m_mapHeadersFooters.insert(std::make_pair(pFooterRef->m_oId->ToString(), pFooter));
|
||||
OOX::IFileContainer* oldContainer = docx_flat->m_currentContainer;
|
||||
docx_flat->m_currentContainer = dynamic_cast<OOX::IFileContainer*>(pFooter.GetPointer());
|
||||
pFooter->fromXML(oReader);
|
||||
docx_flat->m_currentContainer = oldContainer;
|
||||
|
||||
NSCommon::smart_ptr<OOX::File> file = pFooter.smart_dynamic_cast<OOX::File>();
|
||||
OOX::RId rId = docx_flat->m_currentContainer->Add(file);
|
||||
|
||||
pFooterRef->m_oId = rId.get();
|
||||
pFooterRef->m_oType = pFooter->m_oType;
|
||||
|
||||
m_arrFooterReference.push_back(pFooterRef);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
@ -600,11 +600,15 @@ namespace OOX
|
||||
if ( oReader.IsEmptyNode() )
|
||||
return;
|
||||
|
||||
OOX::Document* document = WritingElement::m_pMainDocument;
|
||||
|
||||
int nParentDepth = oReader.GetDepth();
|
||||
CreateElements(oReader, nParentDepth);
|
||||
}
|
||||
void CTr::CreateElements(XmlUtils::CXmlLiteReader &oReader, int nDepth)
|
||||
{
|
||||
OOX::Document* document = WritingElement::m_pMainDocument;
|
||||
int nNumCol = 0;
|
||||
while( oReader.ReadNextSiblingNode( nParentDepth ) )
|
||||
|
||||
while( oReader.ReadNextSiblingNode(nDepth) )
|
||||
{
|
||||
std::wstring sName = oReader.GetName();
|
||||
WritingElement *pItem = NULL;
|
||||
@ -698,6 +702,16 @@ namespace OOX
|
||||
}
|
||||
m_pTableRowProperties->fromXML(oReader);
|
||||
}
|
||||
else if (L"wx:sect" == sName && !oReader.IsEmptyNode())
|
||||
{
|
||||
int nWxSectDepth = oReader.GetDepth();
|
||||
CreateElements(oReader, nWxSectDepth);
|
||||
}
|
||||
else if (L"wx:sub-section" == sName && !oReader.IsEmptyNode())
|
||||
{
|
||||
int nWxSubSectDepth = oReader.GetDepth();
|
||||
CreateElements(oReader, nWxSubSectDepth);
|
||||
}
|
||||
|
||||
if ( pItem )
|
||||
{
|
||||
@ -845,10 +859,14 @@ namespace OOX
|
||||
if ( oReader.IsEmptyNode() )
|
||||
return;
|
||||
|
||||
int nParentDepth = oReader.GetDepth();
|
||||
CreateElements(oReader, nParentDepth);
|
||||
}
|
||||
void CTc::CreateElements(XmlUtils::CXmlLiteReader &oReader, int nDepth)
|
||||
{
|
||||
OOX::Document* document = WritingElement::m_pMainDocument;
|
||||
|
||||
int nParentDepth = oReader.GetDepth();
|
||||
while( oReader.ReadNextSiblingNode( nParentDepth ) )
|
||||
while( oReader.ReadNextSiblingNode(nDepth) )
|
||||
{
|
||||
std::wstring sName = oReader.GetName();
|
||||
WritingElement *pItem = NULL;
|
||||
@ -923,7 +941,16 @@ namespace OOX
|
||||
|
||||
m_pTableCellProperties->fromXML(oReader);
|
||||
}
|
||||
|
||||
else if (L"wx:sect" == sName && !oReader.IsEmptyNode())
|
||||
{
|
||||
int nWxSectDepth = oReader.GetDepth();
|
||||
CreateElements(oReader, nWxSectDepth);
|
||||
}
|
||||
else if (L"wx:sub-section" == sName && !oReader.IsEmptyNode())
|
||||
{
|
||||
int nWxSubSectDepth = oReader.GetDepth();
|
||||
CreateElements(oReader, nWxSubSectDepth);
|
||||
}
|
||||
if ( pItem )
|
||||
{
|
||||
m_arrItems.push_back( pItem );
|
||||
|
||||
@ -521,13 +521,12 @@ namespace OOX
|
||||
}
|
||||
|
||||
private:
|
||||
|
||||
void CreateElements(XmlUtils::CXmlLiteReader &oReader, int Depth);
|
||||
void ReadAttributes(XmlUtils::CXmlLiteReader& oReader);
|
||||
|
||||
public:
|
||||
int m_nCountCell;
|
||||
|
||||
// Attributes
|
||||
nullable<SimpleTypes::CLongHexNumber<> > m_oRsidDel;
|
||||
nullable<SimpleTypes::CLongHexNumber<> > m_oRsidR;
|
||||
nullable<SimpleTypes::CLongHexNumber<> > m_oRsidRPr;
|
||||
@ -595,14 +594,12 @@ namespace OOX
|
||||
}
|
||||
|
||||
private:
|
||||
|
||||
void CreateElements(XmlUtils::CXmlLiteReader &oReader, int Depth);
|
||||
void ReadAttributes(XmlUtils::CXmlLiteReader& oReader);
|
||||
|
||||
public:
|
||||
int m_nNumCol; // Номер колонки
|
||||
// Attributes
|
||||
nullable<std::wstring > m_sId;
|
||||
// Childs
|
||||
OOX::Logic::CTableCellProperties* m_pTableCellProperties; //todooo - выкинуть из m_arrItems, переделать на nullable<>
|
||||
};
|
||||
|
||||
|
||||
@ -29,6 +29,7 @@
|
||||
* terms at http://creativecommons.org/licenses/by-sa/4.0/legalcode
|
||||
*
|
||||
*/
|
||||
#include "../DocxFlat.h"
|
||||
#include "Vml.h"
|
||||
#include "VmlOfficeDrawing.h"
|
||||
|
||||
@ -1675,12 +1676,6 @@ namespace OOX
|
||||
}
|
||||
void CImageData::ReadAttributes(XmlUtils::CXmlLiteReader& oReader)
|
||||
{
|
||||
// Выставляем значения по умолчанию
|
||||
m_oBlackLevel.SetValue( 0.0 );
|
||||
m_oGain.SetValue( 1.0 );
|
||||
m_oGamma.SetValue( 1.0 );
|
||||
|
||||
// Читаем атрибуты
|
||||
if ( oReader.GetAttributesCount() <= 0 )
|
||||
return;
|
||||
|
||||
@ -1770,6 +1765,17 @@ namespace OOX
|
||||
wsName = oReader.GetName();
|
||||
}
|
||||
oReader.MoveToElement();
|
||||
|
||||
CDocxFlat* document = dynamic_cast<CDocxFlat*>(m_pMainDocument);
|
||||
if (document && m_sSrc.IsInit() && !m_oId.IsInit() && !m_rId.IsInit())
|
||||
{
|
||||
std::map<std::wstring, std::wstring>::iterator pFind = document->m_mapImagesId.find(*m_sSrc);
|
||||
if (pFind != document->m_mapImagesId.end())
|
||||
{
|
||||
m_oId = pFind->second;
|
||||
m_rId = pFind->second;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
@ -1780,8 +1786,8 @@ namespace OOX
|
||||
|
||||
ComplexTypes_WriteAttribute3(L"id=\"", m_oId );
|
||||
|
||||
if ( (L"") != m_sSrc )
|
||||
sResult += L"src=\"" + m_sSrc + L"\" ";
|
||||
if (m_sSrc.IsInit())
|
||||
sResult += L"src=\"" + *m_sSrc + L"\" ";
|
||||
|
||||
ComplexTypes_WriteAttribute(L"cropleft=\"", m_oCropLeft);
|
||||
ComplexTypes_WriteAttribute(L"croptop=\"", m_oCropTop);
|
||||
|
||||
@ -730,16 +730,14 @@ namespace OOX
|
||||
private:
|
||||
void ReadAttributes(XmlUtils::CXmlLiteReader& oReader);
|
||||
public:
|
||||
|
||||
// Attributes
|
||||
std::wstring m_sSrc;
|
||||
SimpleTypes::Vml::CVml_1_65536 m_oCropLeft;
|
||||
SimpleTypes::Vml::CVml_1_65536 m_oCropTop;
|
||||
SimpleTypes::Vml::CVml_1_65536 m_oCropRight;
|
||||
SimpleTypes::Vml::CVml_1_65536 m_oCropBottom;
|
||||
SimpleTypes::CDouble m_oGain;
|
||||
SimpleTypes::CDouble m_oBlackLevel;
|
||||
SimpleTypes::CDouble m_oGamma;
|
||||
std::wstring m_sSrc;
|
||||
SimpleTypes::Vml::CVml_1_65536 m_oCropLeft;
|
||||
SimpleTypes::Vml::CVml_1_65536 m_oCropTop;
|
||||
SimpleTypes::Vml::CVml_1_65536 m_oCropRight;
|
||||
SimpleTypes::Vml::CVml_1_65536 m_oCropBottom;
|
||||
SimpleTypes::CDouble m_oGain;
|
||||
SimpleTypes::CDouble m_oBlackLevel;
|
||||
SimpleTypes::CDouble m_oGamma;
|
||||
SimpleTypes::CTrueFalse<SimpleTypes::booleanFalse> m_oGrayscale;
|
||||
SimpleTypes::CTrueFalse<SimpleTypes::booleanFalse> m_oBiLevel;
|
||||
};
|
||||
@ -777,8 +775,6 @@ namespace OOX
|
||||
|
||||
void ReadAttributes(XmlUtils::CXmlLiteReader& oReader);
|
||||
public:
|
||||
|
||||
// Attributes
|
||||
nullable_string m_sAltHref;
|
||||
SimpleTypes::CTrueFalse<SimpleTypes::booleanFalse> m_oBiLevel;
|
||||
SimpleTypes::CDouble m_oBlackLevel;
|
||||
@ -801,7 +797,7 @@ namespace OOX
|
||||
nullable<SimpleTypes::CRelationshipId> m_rPict;
|
||||
nullable<SimpleTypes::CColorType<>> m_oRecolorTarget;
|
||||
nullable<SimpleTypes::CRelationshipId> m_oRelId;
|
||||
std::wstring m_sSrc;
|
||||
nullable_string m_sSrc;
|
||||
nullable_string m_sTitle;
|
||||
};
|
||||
//--------------------------------------------------------------------------------
|
||||
|
||||
@ -30,9 +30,6 @@
|
||||
*
|
||||
*/
|
||||
#pragma once
|
||||
#ifndef OOX_IMAGE_INCLUDE_H_
|
||||
#define OOX_IMAGE_INCLUDE_H_
|
||||
|
||||
#include "Media.h"
|
||||
|
||||
namespace OOX
|
||||
@ -64,5 +61,3 @@ namespace OOX
|
||||
}
|
||||
};
|
||||
} // namespace OOX
|
||||
|
||||
#endif // OOX_IMAGE_INCLUDE_H_
|
||||
|
||||
@ -37,7 +37,7 @@ namespace OOX
|
||||
{
|
||||
Media::Media(OOX::Document *pMain, bool bDocument) : File(pMain)
|
||||
{
|
||||
m_bExist = false;
|
||||
m_bExist = false;
|
||||
m_bExternal = false;
|
||||
m_bDocument = bDocument;
|
||||
}
|
||||
@ -45,8 +45,8 @@ namespace OOX
|
||||
{
|
||||
m_bExist = false;
|
||||
m_bDocument = (NULL != dynamic_cast<OOX::CDocument*>(pMain));
|
||||
m_bExternal = bExternal;
|
||||
|
||||
m_bExternal = bExternal;
|
||||
|
||||
read(filename);
|
||||
}
|
||||
void Media::read(const CPath& filename)
|
||||
@ -60,11 +60,23 @@ namespace OOX
|
||||
|
||||
std::wstring newFilename = filename.GetFilename();
|
||||
CPath newFilePath = filename.GetDirectory();
|
||||
|
||||
XmlUtils::replace_all(newFilename, L" ", L"_");
|
||||
if (CSystemUtility::IsFileExist(m_filename) && !CSystemUtility::IsFileExist(newFilePath / newFilename))
|
||||
|
||||
if (!CSystemUtility::IsFileExist(newFilePath / newFilename))
|
||||
{
|
||||
copy_to(newFilePath);
|
||||
if (false == m_Data.empty())
|
||||
{
|
||||
NSFile::CFileBinary file;
|
||||
if (file.CreateFileW((newFilePath / newFilename).GetPath()))
|
||||
{
|
||||
file.WriteFile(m_Data.data(), m_Data.size());
|
||||
file.CloseFile();
|
||||
}
|
||||
}
|
||||
else if (CSystemUtility::IsFileExist(m_filename))
|
||||
{
|
||||
copy_to(newFilePath);
|
||||
}
|
||||
}
|
||||
}
|
||||
void Media::set_filename(const std::wstring & file_path, bool bExternal)
|
||||
@ -74,11 +86,13 @@ namespace OOX
|
||||
m_bExternal = bExternal;
|
||||
m_sOutputFilename = m_filename.GetFilename();
|
||||
}
|
||||
void Media::set_filename(CPath & file_path, bool bExternal)
|
||||
void Media::set_filename(CPath & file_path, bool bExternal, bool bDefault)
|
||||
{
|
||||
m_bExternal = bExternal;
|
||||
m_filename = file_path;
|
||||
m_sOutputFilename = file_path.GetFilename();
|
||||
m_bExternal = bExternal;
|
||||
m_filename = file_path;
|
||||
|
||||
if (!bDefault) m_sOutputFilename = m_filename.GetFilename();
|
||||
|
||||
m_bExist = NSFile::CFileBinary::Exists(m_filename.GetPath());
|
||||
}
|
||||
void Media::copy_to(const CPath& path) const
|
||||
|
||||
@ -54,7 +54,7 @@ namespace OOX
|
||||
virtual void write(const CPath& filename, const CPath& directory, CContentTypes& content) const;
|
||||
|
||||
void set_filename(const std::wstring & file_path, bool bExternal);
|
||||
void set_filename(CPath & file_path, bool bExternal);
|
||||
void set_filename(CPath & file_path, bool bExternal, bool bDefault = false);
|
||||
|
||||
bool IsExist()
|
||||
{
|
||||
@ -78,6 +78,7 @@ namespace OOX
|
||||
{
|
||||
return m_filename.GetFilename();
|
||||
}
|
||||
std::vector<BYTE> m_Data;
|
||||
protected:
|
||||
CPath m_filename;
|
||||
bool m_bExist;
|
||||
|
||||
@ -971,6 +971,8 @@ namespace OOX
|
||||
{
|
||||
std::wstring sXml = toXML();
|
||||
CDirectory::SaveToFile( oFilePath.GetPath(), sXml );
|
||||
|
||||
oContent.Registration(type().OverrideType(), oDirectory, oFilePath.GetFilename());
|
||||
}
|
||||
virtual void fromXML(XmlUtils::CXmlNode& oNode)
|
||||
{
|
||||
|
||||
@ -29,7 +29,10 @@
|
||||
* terms at http://creativecommons.org/licenses/by-sa/4.0/legalcode
|
||||
*
|
||||
*/
|
||||
#include "../DocxFlat.h"
|
||||
#include "Settings.h"
|
||||
#include "../Endnote.h"
|
||||
#include "../Footnote.h"
|
||||
|
||||
namespace OOX
|
||||
{
|
||||
@ -1101,8 +1104,24 @@ namespace Settings
|
||||
m_oPos = oReader;
|
||||
else if ( L"w:endnote" == sName )
|
||||
{
|
||||
OOX::CFtnEdnSepRef *oFE = new OOX::CFtnEdnSepRef(oReader);
|
||||
if (oFE) m_arrEndnote.push_back( oFE );
|
||||
CDocxFlat* docx_flat = dynamic_cast<CDocxFlat*>(WritingElement::m_pMainDocument);
|
||||
if (docx_flat)
|
||||
{
|
||||
CFtnEdn *pEndnote = new CFtnEdn(WritingElement::m_pMainDocument);
|
||||
pEndnote->fromXML(oReader);
|
||||
|
||||
pEndnote->m_oId.Init();
|
||||
pEndnote->m_oId->SetValue((int)(docx_flat->m_pEndnotes->m_arrEndnote.size() + 1));
|
||||
|
||||
docx_flat->m_pSettings->m_oEndnotePr->m_arrEndnote.push_back(new CFtnEdnSepRef());
|
||||
docx_flat->m_pSettings->m_oEndnotePr->m_arrEndnote.back()->m_oId = pEndnote->m_oId;
|
||||
docx_flat->m_pSettings->m_oEndnotePr->m_arrEndnote.back()->m_eType = OOX::et_w_endnote;
|
||||
}
|
||||
else
|
||||
{
|
||||
OOX::CFtnEdnSepRef *oFE = new OOX::CFtnEdnSepRef(oReader);
|
||||
if (oFE) m_arrEndnote.push_back(oFE);
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
@ -1163,8 +1182,25 @@ namespace Settings
|
||||
m_oPos = oReader;
|
||||
else if ( L"w:footnote" == sName )
|
||||
{
|
||||
OOX::CFtnEdnSepRef *oFE = new OOX::CFtnEdnSepRef(oReader);
|
||||
if (oFE) m_arrFootnote.push_back( oFE );
|
||||
CDocxFlat* docx_flat = dynamic_cast<CDocxFlat*>(WritingElement::m_pMainDocument);
|
||||
if (docx_flat)
|
||||
{
|
||||
CFtnEdn *pFootnote = new CFtnEdn(WritingElement::m_pMainDocument);
|
||||
pFootnote->fromXML(oReader);
|
||||
|
||||
pFootnote->m_oId.Init();
|
||||
pFootnote->m_oId->SetValue((int)(docx_flat->m_pEndnotes->m_arrEndnote.size() + 1));
|
||||
|
||||
docx_flat->m_pSettings->m_oFootnotePr->m_arrFootnote.push_back(new CFtnEdnSepRef());
|
||||
docx_flat->m_pSettings->m_oFootnotePr->m_arrFootnote.back()->m_oId = pFootnote->m_oId;
|
||||
docx_flat->m_pSettings->m_oFootnotePr->m_arrFootnote.back()->m_eType = OOX::et_w_footnote;
|
||||
|
||||
}
|
||||
else
|
||||
{
|
||||
OOX::CFtnEdnSepRef *oFE = new OOX::CFtnEdnSepRef(oReader);
|
||||
if (oFE) m_arrFootnote.push_back(oFE);
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
@ -1346,11 +1382,19 @@ namespace Settings
|
||||
case 'e':
|
||||
if ( L"w:embedSystemFonts" == sName ) m_oEmbedSystemFonts = oReader;
|
||||
else if ( L"w:embedTrueTypeFonts" == sName ) m_oEmbedTrueTypeFonts = oReader;
|
||||
else if ( L"w:endnotePr" == sName ) m_oEndnotePr = oReader;
|
||||
else if (L"w:endnotePr" == sName)
|
||||
{
|
||||
m_oEndnotePr = new Settings::CEdnDocProps(WritingElement::m_pMainDocument);
|
||||
m_oEndnotePr->fromXML(oReader);
|
||||
}
|
||||
else if ( L"w:evenAndOddHeaders" == sName ) m_oEvenAndOddHeaders = oReader;
|
||||
break;
|
||||
case 'f':
|
||||
if ( L"w:footnotePr" == sName ) m_oFootnotePr = oReader;
|
||||
if (L"w:footnotePr" == sName)
|
||||
{
|
||||
m_oFootnotePr = new Settings::CFtnDocProps(WritingElement::m_pMainDocument);
|
||||
m_oFootnotePr->fromXML(oReader);
|
||||
}
|
||||
else if ( L"w:forceUpgrade" == sName ) m_oForceUpgrade = oReader;
|
||||
else if ( L"w:formsDesign" == sName ) m_oFormsDesign = oReader;
|
||||
break;
|
||||
@ -1452,7 +1496,7 @@ namespace Settings
|
||||
sXml += toXML();
|
||||
|
||||
CDirectory::SaveToFile( oFilePath.GetPath(), sXml );
|
||||
oContent.Registration( type().OverrideType(), oDirectory, oFilePath );
|
||||
oContent.Registration( type().OverrideType(), oDirectory, oFilePath.GetFilename() );
|
||||
}
|
||||
std::wstring CSettings::toXML() const
|
||||
{
|
||||
|
||||
@ -1325,7 +1325,7 @@ namespace OOX
|
||||
{
|
||||
public:
|
||||
WritingElement_AdditionConstructors(CEdnDocProps)
|
||||
CEdnDocProps()
|
||||
CEdnDocProps(OOX::Document *pMain = NULL) : OOX::WritingElement(pMain)
|
||||
{
|
||||
}
|
||||
virtual ~CEdnDocProps()
|
||||
@ -1363,7 +1363,7 @@ namespace OOX
|
||||
{
|
||||
public:
|
||||
WritingElement_AdditionConstructors(CFtnDocProps)
|
||||
CFtnDocProps()
|
||||
CFtnDocProps(OOX::Document *pMain = NULL) : OOX::WritingElement(pMain)
|
||||
{
|
||||
}
|
||||
virtual ~CFtnDocProps()
|
||||
|
||||
@ -813,6 +813,8 @@ namespace OOX
|
||||
sXml += toXML();
|
||||
|
||||
CDirectory::SaveToFile( oFilePath.GetPath(), sXml );
|
||||
|
||||
oContent.Registration(type().OverrideType(), oDirectory, oFilePath.GetFilename());
|
||||
}
|
||||
virtual const OOX::FileType type() const
|
||||
{
|
||||
|
||||
@ -4,6 +4,7 @@
|
||||
#include "../../common/File.h"
|
||||
#include "../../common/Array.h"
|
||||
#include "../../../Common/DocxFormat/Source/Base/SmartPtr.h"
|
||||
#include "../../graphics/BaseThread.h"
|
||||
|
||||
#define JS_VALUE_EXIST(value) (value.is_init() && !value->isNull() && !value->isUndefined())
|
||||
#define JS_IS_VALUE_ARRAY(value) (value.is_init() && !value->isNull() && !value->isUndefined() && value->isArray())
|
||||
@ -245,7 +246,7 @@ namespace NSJSBase
|
||||
|
||||
JSSmart<CJSValue> runScript(const std::string& script, JSSmart<CJSTryCatch> exception = NULL, const std::wstring& scriptPath = std::wstring(L""));
|
||||
CJSValue* JSON_Parse(const char* json_content);
|
||||
void MoveToThread();
|
||||
void MoveToThread(ASC_THREAD_ID* id = NULL);
|
||||
|
||||
public:
|
||||
static CJSValue* createUndefined();
|
||||
|
||||
@ -10,7 +10,6 @@
|
||||
|
||||
#import "../../../../DesktopEditor/common/Mac/NSString+StringUtils.h"
|
||||
#include <vector>
|
||||
#include "../../../../DesktopEditor/graphics/BaseThread.h"
|
||||
|
||||
@protocol JSEmbedObjectProtocol
|
||||
- (void*) getNative;
|
||||
@ -53,9 +52,9 @@ namespace NSJSBase
|
||||
}
|
||||
|
||||
private:
|
||||
static bool RegisterContext(JSContext* ctx)
|
||||
static bool RegisterContext(JSContext* ctx, ASC_THREAD_ID* id = NULL)
|
||||
{
|
||||
ASC_THREAD_ID nCurrentThread = NSThreads::GetCurrentThreadId();
|
||||
ASC_THREAD_ID nCurrentThread = (id == NULL) ? NSThreads::GetCurrentThreadId() : *id;
|
||||
for (std::vector<std::pair<ASC_THREAD_ID, JSContext*>>::const_iterator i = g_contexts.begin(); i != g_contexts.end(); i++)
|
||||
{
|
||||
if (i->first == nCurrentThread)
|
||||
|
||||
@ -331,11 +331,11 @@ namespace NSJSBase
|
||||
return _value;
|
||||
}
|
||||
|
||||
void CJSContext::MoveToThread()
|
||||
void CJSContext::MoveToThread(ASC_THREAD_ID* id)
|
||||
{
|
||||
if (CJSContextPrivate::RegisterContext(m_internal->context))
|
||||
if (CJSContextPrivate::RegisterContext(m_internal->context, id))
|
||||
{
|
||||
m_internal->m_arThreads.push_back(NSThreads::GetCurrentThreadId());
|
||||
m_internal->m_arThreads.push_back((NULL == id) ? NSThreads::GetCurrentThreadId() : *id);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
@ -350,7 +350,7 @@ namespace NSJSBase
|
||||
return _value;
|
||||
}
|
||||
|
||||
void CJSContext::MoveToThread()
|
||||
void CJSContext::MoveToThread(ASC_THREAD_ID* id)
|
||||
{
|
||||
// none
|
||||
}
|
||||
|
||||
@ -376,7 +376,7 @@ namespace NSStructures
|
||||
TextureAlpha = dNewAlpha;
|
||||
}
|
||||
|
||||
INT IsEqual(CBrush *pBrush)
|
||||
INT IsEqual(const CBrush *pBrush)
|
||||
{
|
||||
if (NULL == pBrush)
|
||||
return FALSE;
|
||||
@ -385,7 +385,7 @@ namespace NSStructures
|
||||
(Color1 == pBrush->Color1) && (Color2 == pBrush->Color2) &&
|
||||
(Alpha1 == pBrush->Alpha1) && (Alpha2 == pBrush->Alpha2) && (LinearAngle == pBrush->LinearAngle) &&
|
||||
(TexturePath == pBrush->TexturePath) && (TextureAlpha == pBrush->TextureAlpha) && (TextureMode == pBrush->TextureMode) &&
|
||||
(Rectable == pBrush->Rectable) && (Rect.Equals(pBrush->Rect)));
|
||||
(Rectable == pBrush->Rectable) && (Rect.Equals(pBrush->Rect)));
|
||||
}
|
||||
|
||||
void SetDefaultParams()
|
||||
@ -444,6 +444,7 @@ namespace NSStructures
|
||||
|
||||
LinearAngle = other.LinearAngle;
|
||||
m_arrSubColors = other.m_arrSubColors;
|
||||
m_oGradientInfo = other.m_oGradientInfo;
|
||||
}
|
||||
CBrush &operator=(const CBrush &other)
|
||||
{
|
||||
@ -464,6 +465,7 @@ namespace NSStructures
|
||||
|
||||
LinearAngle = other.LinearAngle;
|
||||
m_arrSubColors = other.m_arrSubColors;
|
||||
m_oGradientInfo = other.m_oGradientInfo;
|
||||
|
||||
return *this;
|
||||
}
|
||||
@ -501,7 +503,7 @@ namespace NSStructures
|
||||
|
||||
int FaceIndex;
|
||||
|
||||
int IsEqual(CFont *pFont)
|
||||
int IsEqual(const CFont *pFont)
|
||||
{
|
||||
if (NULL == pFont)
|
||||
return FALSE;
|
||||
@ -511,7 +513,7 @@ namespace NSStructures
|
||||
(Underline == pFont->Underline) && (Strikeout == pFont->Strikeout));
|
||||
}
|
||||
|
||||
int IsEqual2(CFont *pFont)
|
||||
int IsEqual2(const CFont *pFont)
|
||||
{
|
||||
if (NULL == pFont)
|
||||
return FALSE;
|
||||
@ -582,6 +584,19 @@ namespace NSStructures
|
||||
return 4;
|
||||
}
|
||||
|
||||
LONG GetTextFontStyle()
|
||||
{
|
||||
if ((0 == Bold) && (0 == Italic))
|
||||
return 0;
|
||||
if ((1 == Bold) && (0 == Italic))
|
||||
return 1;
|
||||
if ((0 == Bold) && (1 == Italic))
|
||||
return 2;
|
||||
if ((1 == Bold) && (1 == Italic))
|
||||
return 3;
|
||||
return 4;
|
||||
}
|
||||
|
||||
CFont()
|
||||
{
|
||||
SetDefaultParams();
|
||||
@ -592,7 +607,7 @@ namespace NSStructures
|
||||
}
|
||||
CFont &operator=(const CFont &other)
|
||||
{
|
||||
Name = other.Name;
|
||||
Name = other.Name;
|
||||
Path = other.Path;
|
||||
Size = other.Size;
|
||||
Bold = other.Bold;
|
||||
|
||||
@ -31,23 +31,24 @@
|
||||
*/
|
||||
|
||||
#include "DocxRenderer.h"
|
||||
#include "src/logic/Document.h"
|
||||
#include "../DesktopEditor/common/Directory.h"
|
||||
#include "../OfficeUtils/src/OfficeUtils.h"
|
||||
#include "src/logic/Document.h"
|
||||
|
||||
class CDocxRenderer_Private
|
||||
{
|
||||
public:
|
||||
NSDocxRenderer::CDocument m_oDocument;
|
||||
std::wstring m_sTempDirectory;
|
||||
public:
|
||||
NSDocxRenderer::CDocument m_oDocument;
|
||||
std::wstring m_sTempDirectory;
|
||||
|
||||
public:
|
||||
CDocxRenderer_Private(NSFonts::IApplicationFonts* pFonts, IRenderer* pRenderer) : m_oDocument(pRenderer, pFonts)
|
||||
{
|
||||
}
|
||||
~CDocxRenderer_Private()
|
||||
{
|
||||
public:
|
||||
CDocxRenderer_Private(NSFonts::IApplicationFonts* pFonts, IRenderer* pRenderer) : m_oDocument(pRenderer, pFonts)
|
||||
{
|
||||
}
|
||||
~CDocxRenderer_Private()
|
||||
{
|
||||
|
||||
}
|
||||
}
|
||||
};
|
||||
|
||||
CDocxRenderer::CDocxRenderer(NSFonts::IApplicationFonts* pAppFonts)
|
||||
@ -71,7 +72,7 @@ HRESULT CDocxRenderer::CreateNewFile(const std::wstring& wsPath, bool bIsOutComp
|
||||
}
|
||||
HRESULT CDocxRenderer::Close()
|
||||
{
|
||||
COfficeUtils oCOfficeUtils(NULL);
|
||||
COfficeUtils oCOfficeUtils(nullptr);
|
||||
HRESULT hr = oCOfficeUtils.CompressFileOrDirectory(m_pInternal->m_oDocument.m_strTempDirectory, m_pInternal->m_oDocument.m_strDstFilePath, true);
|
||||
if (!m_pInternal->m_oDocument.m_strTempDirectory.empty())
|
||||
NSDirectory::DeleteDirectory(m_pInternal->m_oDocument.m_strTempDirectory);
|
||||
@ -96,7 +97,7 @@ int CDocxRenderer::Convert(IOfficeDrawingFile* pFile, const std::wstring& sDstFi
|
||||
for (int i = 0; i < nPagesCount; ++i)
|
||||
{
|
||||
NewPage();
|
||||
BeginCommand(c_nPageType);
|
||||
BeginCommand(c_nPageType);
|
||||
m_pInternal->m_oDocument.m_bIsDisablePageCommand = true;
|
||||
|
||||
double dPageDpiX, dPageDpiY;
|
||||
@ -109,7 +110,7 @@ int CDocxRenderer::Convert(IOfficeDrawingFile* pFile, const std::wstring& sDstFi
|
||||
put_Width(dWidth);
|
||||
put_Height(dHeight);
|
||||
|
||||
pFile->DrawPageOnRenderer(this, i, NULL);
|
||||
pFile->DrawPageOnRenderer(this, i, nullptr);
|
||||
|
||||
m_pInternal->m_oDocument.m_bIsDisablePageCommand = false;
|
||||
EndCommand(c_nPageType);
|
||||
|
||||
@ -29,15 +29,12 @@
|
||||
* terms at http://creativecommons.org/licenses/by-sa/4.0/legalcode
|
||||
*
|
||||
*/
|
||||
#ifndef _DOCX_RENDERER_H
|
||||
#define _DOCX_RENDERER_H
|
||||
|
||||
#pragma once
|
||||
#include "../DesktopEditor/graphics/IRenderer.h"
|
||||
#include "../DesktopEditor/graphics/pro/officedrawingfile.h"
|
||||
#include "../DesktopEditor/graphics/pro/Fonts.h"
|
||||
#include <string>
|
||||
#include <vector>
|
||||
#include <algorithm>
|
||||
|
||||
#include "src/logic/ElementParagraph.h"
|
||||
|
||||
#ifndef DOCXRENDERER_USE_DYNAMIC_LIBRARY
|
||||
#define DOCXRENDERER_DECL_EXPORT
|
||||
@ -46,166 +43,153 @@
|
||||
#define DOCXRENDERER_DECL_EXPORT Q_DECL_EXPORT
|
||||
#endif
|
||||
|
||||
namespace NSDocxRenderer
|
||||
{
|
||||
enum TextAssociationType
|
||||
{
|
||||
TextAssociationTypeBlockChar = 0, // Каждый символ во фрейме
|
||||
TextAssociationTypeBlockLine = 1, // Каждая линия - параграф во фрейме. Линии могут объединяться в рамках одного блока.
|
||||
TextAssociationTypePlainLine = 2, // Каждая линия - параграф обычный
|
||||
TextAssociationTypePlainParagraph = 3 // Линии объединяются в параграфы
|
||||
};
|
||||
}
|
||||
|
||||
class CDocxRenderer_Private;
|
||||
class DOCXRENDERER_DECL_EXPORT CDocxRenderer : public IRenderer
|
||||
{
|
||||
public:
|
||||
CDocxRenderer(NSFonts::IApplicationFonts* pAppFonts);
|
||||
~CDocxRenderer();
|
||||
public:
|
||||
CDocxRenderer(NSFonts::IApplicationFonts* pAppFonts);
|
||||
virtual ~CDocxRenderer();
|
||||
|
||||
HRESULT CreateNewFile(const std::wstring& wsPath, bool bIsOutCompress = true);
|
||||
HRESULT Close();
|
||||
HRESULT CreateNewFile(const std::wstring& wsPath, bool bIsOutCompress = true);
|
||||
HRESULT Close();
|
||||
|
||||
HRESULT SetTempFolder(const std::wstring& wsPath);
|
||||
//----------------------------------------------------------------------------------------
|
||||
// Тип рендерера
|
||||
//----------------------------------------------------------------------------------------
|
||||
virtual HRESULT get_Type(LONG* lType);
|
||||
//----------------------------------------------------------------------------------------
|
||||
// Функции для работы со страницей
|
||||
//----------------------------------------------------------------------------------------
|
||||
virtual HRESULT NewPage();
|
||||
virtual HRESULT get_Height(double* dHeight);
|
||||
virtual HRESULT put_Height(const double& dHeight);
|
||||
virtual HRESULT get_Width(double* dWidth);
|
||||
virtual HRESULT put_Width(const double& dWidth);
|
||||
virtual HRESULT get_DpiX(double* dDpiX);
|
||||
virtual HRESULT get_DpiY(double* dDpiY);
|
||||
//----------------------------------------------------------------------------------------
|
||||
// Функции для работы с Pen
|
||||
//----------------------------------------------------------------------------------------
|
||||
virtual HRESULT get_PenColor(LONG* lColor);
|
||||
virtual HRESULT put_PenColor(const LONG& lColor);
|
||||
virtual HRESULT get_PenAlpha(LONG* lAlpha);
|
||||
virtual HRESULT put_PenAlpha(const LONG& lAlpha);
|
||||
virtual HRESULT get_PenSize(double* dSize);
|
||||
virtual HRESULT put_PenSize(const double& dSize);
|
||||
virtual HRESULT get_PenDashStyle(BYTE* nDashStyle);
|
||||
virtual HRESULT put_PenDashStyle(const BYTE& nDashStyle);
|
||||
virtual HRESULT get_PenLineStartCap(BYTE* nCapStyle);
|
||||
virtual HRESULT put_PenLineStartCap(const BYTE& nCapStyle);
|
||||
virtual HRESULT get_PenLineEndCap(BYTE* nCapStyle);
|
||||
virtual HRESULT put_PenLineEndCap(const BYTE& nCapStyle);
|
||||
virtual HRESULT get_PenLineJoin(BYTE* nJoinStyle);
|
||||
virtual HRESULT put_PenLineJoin(const BYTE& nJoinStyle);
|
||||
virtual HRESULT get_PenDashOffset(double* dOffset);
|
||||
virtual HRESULT put_PenDashOffset(const double& dOffset);
|
||||
virtual HRESULT get_PenAlign(LONG* lAlign);
|
||||
virtual HRESULT put_PenAlign(const LONG& lAlign);
|
||||
virtual HRESULT get_PenMiterLimit(double* dMiter);
|
||||
virtual HRESULT put_PenMiterLimit(const double& dMiter);
|
||||
virtual HRESULT PenDashPattern(double* pPattern, LONG lCount);
|
||||
//----------------------------------------------------------------------------------------
|
||||
// Функции для работы с Brush
|
||||
//----------------------------------------------------------------------------------------
|
||||
virtual HRESULT get_BrushType(LONG* lType);
|
||||
virtual HRESULT put_BrushType(const LONG& lType);
|
||||
virtual HRESULT get_BrushColor1(LONG* lColor);
|
||||
virtual HRESULT put_BrushColor1(const LONG& lColor);
|
||||
virtual HRESULT get_BrushAlpha1(LONG* lAlpha);
|
||||
virtual HRESULT put_BrushAlpha1(const LONG& lAlpha);
|
||||
virtual HRESULT get_BrushColor2(LONG* lColor);
|
||||
virtual HRESULT put_BrushColor2(const LONG& lColor);
|
||||
virtual HRESULT get_BrushAlpha2(LONG* lAlpha);
|
||||
virtual HRESULT put_BrushAlpha2(const LONG& lAlpha);
|
||||
virtual HRESULT get_BrushTexturePath(std::wstring* wsPath);
|
||||
virtual HRESULT put_BrushTexturePath(const std::wstring& wsPath);
|
||||
virtual HRESULT get_BrushTextureMode(LONG* lMode);
|
||||
virtual HRESULT put_BrushTextureMode(const LONG& lMode);
|
||||
virtual HRESULT get_BrushTextureAlpha(LONG* lAlpha);
|
||||
virtual HRESULT put_BrushTextureAlpha(const LONG& lAlpha);
|
||||
virtual HRESULT get_BrushLinearAngle(double* dAngle);
|
||||
virtual HRESULT put_BrushLinearAngle(const double& dAngle);
|
||||
virtual HRESULT BrushRect(const INT& nVal, const double& dLeft, const double& dTop, const double& dWidth, const double& dHeight);
|
||||
virtual HRESULT BrushBounds(const double& dLeft, const double& dTop, const double& dWidth, const double& dHeight);
|
||||
virtual HRESULT put_BrushGradientColors(LONG* pColors, double* pPositions, LONG lCount);
|
||||
//----------------------------------------------------------------------------------------
|
||||
// Функции для работы со шрифтами
|
||||
//----------------------------------------------------------------------------------------
|
||||
virtual HRESULT get_FontName(std::wstring* wsName);
|
||||
virtual HRESULT put_FontName(const std::wstring& wsName);
|
||||
virtual HRESULT get_FontPath(std::wstring* wsPath);
|
||||
virtual HRESULT put_FontPath(const std::wstring& wsPath);
|
||||
virtual HRESULT get_FontSize(double* dSize);
|
||||
virtual HRESULT put_FontSize(const double& dSize);
|
||||
virtual HRESULT get_FontStyle(LONG* lStyle);
|
||||
virtual HRESULT put_FontStyle(const LONG& lStyle);
|
||||
virtual HRESULT get_FontStringGID(INT* bGid);
|
||||
virtual HRESULT put_FontStringGID(const INT& bGid);
|
||||
virtual HRESULT get_FontCharSpace(double* dSpace);
|
||||
virtual HRESULT put_FontCharSpace(const double& dSpace);
|
||||
virtual HRESULT get_FontFaceIndex(int* lFaceIndex);
|
||||
virtual HRESULT put_FontFaceIndex(const int& lFaceIndex);
|
||||
//----------------------------------------------------------------------------------------
|
||||
// Функции для вывода текста
|
||||
//----------------------------------------------------------------------------------------
|
||||
virtual HRESULT CommandDrawTextCHAR (const LONG& lUnicode, const double& dX, const double& dY, const double& dW, const double& dH);
|
||||
virtual HRESULT CommandDrawTextExCHAR(const LONG& lUnicode, const LONG& lGid, const double& dX, const double& dY, const double& dW, const double& dH);
|
||||
virtual HRESULT CommandDrawText (const std::wstring& wsUnicodeText, const double& dX, const double& dY, const double& dW, const double& dH);
|
||||
virtual HRESULT CommandDrawTextEx (const std::wstring& wsUnicodeText, const unsigned int* pGids, const unsigned int nGidsCount, const double& dX, const double& dY, const double& dW, const double& dH);
|
||||
//----------------------------------------------------------------------------------------
|
||||
// Маркеры команд
|
||||
//----------------------------------------------------------------------------------------
|
||||
virtual HRESULT BeginCommand(const DWORD& lType);
|
||||
virtual HRESULT EndCommand(const DWORD& lType);
|
||||
//----------------------------------------------------------------------------------------
|
||||
// Функции для работы с патом
|
||||
//----------------------------------------------------------------------------------------
|
||||
virtual HRESULT PathCommandMoveTo(const double& dX, const double& dY);
|
||||
virtual HRESULT PathCommandLineTo(const double& dX, const double& dY);
|
||||
virtual HRESULT PathCommandLinesTo(double* pPoints, const int& nCount);
|
||||
virtual HRESULT PathCommandCurveTo(const double& dX1, const double& dY1, const double& dX2, const double& dY2, const double& dXe, const double& dYe);
|
||||
virtual HRESULT PathCommandCurvesTo(double* pPoints, const int& nCount);
|
||||
virtual HRESULT PathCommandArcTo(const double& dX, const double& dY, const double& dW, const double& dH, const double& dStartAngle, const double& dSweepAngle);
|
||||
virtual HRESULT PathCommandClose();
|
||||
virtual HRESULT PathCommandEnd();
|
||||
virtual HRESULT DrawPath(const LONG& lType);
|
||||
virtual HRESULT PathCommandStart();
|
||||
virtual HRESULT PathCommandGetCurrentPoint(double* dX, double* dY);
|
||||
virtual HRESULT PathCommandTextCHAR (const LONG& lUnicode, const double& dX, const double& dY, const double& dW, const double& dH);
|
||||
virtual HRESULT PathCommandTextExCHAR(const LONG& lUnicode, const LONG& lGid, const double& dX, const double& dY, const double& dW, const double& dH);
|
||||
virtual HRESULT PathCommandText (const std::wstring& wsUnicodeText, const double& dX, const double& dY, const double& dW, const double& dH);
|
||||
virtual HRESULT PathCommandTextEx (const std::wstring& wsUnicodeText, const unsigned int* pGids, const unsigned int nGidsCount, const double& dX, const double& dY, const double& dW, const double& dH);
|
||||
//----------------------------------------------------------------------------------------
|
||||
// Функции для вывода изображений
|
||||
//----------------------------------------------------------------------------------------
|
||||
virtual HRESULT DrawImage(IGrObject* pImage, const double& dX, const double& dY, const double& dW, const double& dH);
|
||||
virtual HRESULT DrawImageFromFile(const std::wstring& wsImagePath, const double& dX, const double& dY, const double& dW, const double& dH, const BYTE& nAlpha = 255);
|
||||
//----------------------------------------------------------------------------------------
|
||||
// Функции для выставления преобразования
|
||||
//----------------------------------------------------------------------------------------
|
||||
virtual HRESULT SetTransform(const double& dM11, const double& dM12, const double& dM21, const double& dM22, const double& dX, const double& dY);
|
||||
virtual HRESULT GetTransform(double* dM11, double* dM12, double* dM21, double* dM22, double* dX, double* dY);
|
||||
virtual HRESULT ResetTransform();
|
||||
//----------------------------------------------------------------------------------------
|
||||
// Тип клипа
|
||||
//----------------------------------------------------------------------------------------
|
||||
virtual HRESULT get_ClipMode(LONG* lMode);
|
||||
virtual HRESULT put_ClipMode(const LONG& lMode);
|
||||
//----------------------------------------------------------------------------------------
|
||||
// Дополнительные функции
|
||||
//----------------------------------------------------------------------------------------
|
||||
virtual HRESULT CommandLong(const LONG& lType, const LONG& lCommand);
|
||||
virtual HRESULT CommandDouble(const LONG& lType, const double& dCommand);
|
||||
virtual HRESULT CommandString(const LONG& lType, const std::wstring& sCommand);
|
||||
HRESULT SetTempFolder(const std::wstring& wsPath);
|
||||
//----------------------------------------------------------------------------------------
|
||||
// Тип рендерера
|
||||
//----------------------------------------------------------------------------------------
|
||||
virtual HRESULT get_Type(LONG* lType);
|
||||
//----------------------------------------------------------------------------------------
|
||||
// Функции для работы со страницей
|
||||
//----------------------------------------------------------------------------------------
|
||||
virtual HRESULT NewPage();
|
||||
virtual HRESULT get_Height(double* dHeight);
|
||||
virtual HRESULT put_Height(const double& dHeight);
|
||||
virtual HRESULT get_Width(double* dWidth);
|
||||
virtual HRESULT put_Width(const double& dWidth);
|
||||
virtual HRESULT get_DpiX(double* dDpiX);
|
||||
virtual HRESULT get_DpiY(double* dDpiY);
|
||||
//----------------------------------------------------------------------------------------
|
||||
// Функции для работы с Pen
|
||||
//----------------------------------------------------------------------------------------
|
||||
virtual HRESULT get_PenColor(LONG* lColor);
|
||||
virtual HRESULT put_PenColor(const LONG& lColor);
|
||||
virtual HRESULT get_PenAlpha(LONG* lAlpha);
|
||||
virtual HRESULT put_PenAlpha(const LONG& lAlpha);
|
||||
virtual HRESULT get_PenSize(double* dSize);
|
||||
virtual HRESULT put_PenSize(const double& dSize);
|
||||
virtual HRESULT get_PenDashStyle(BYTE* nDashStyle);
|
||||
virtual HRESULT put_PenDashStyle(const BYTE& nDashStyle);
|
||||
virtual HRESULT get_PenLineStartCap(BYTE* nCapStyle);
|
||||
virtual HRESULT put_PenLineStartCap(const BYTE& nCapStyle);
|
||||
virtual HRESULT get_PenLineEndCap(BYTE* nCapStyle);
|
||||
virtual HRESULT put_PenLineEndCap(const BYTE& nCapStyle);
|
||||
virtual HRESULT get_PenLineJoin(BYTE* nJoinStyle);
|
||||
virtual HRESULT put_PenLineJoin(const BYTE& nJoinStyle);
|
||||
virtual HRESULT get_PenDashOffset(double* dOffset);
|
||||
virtual HRESULT put_PenDashOffset(const double& dOffset);
|
||||
virtual HRESULT get_PenAlign(LONG* lAlign);
|
||||
virtual HRESULT put_PenAlign(const LONG& lAlign);
|
||||
virtual HRESULT get_PenMiterLimit(double* dMiter);
|
||||
virtual HRESULT put_PenMiterLimit(const double& dMiter);
|
||||
virtual HRESULT PenDashPattern(double* pPattern, LONG lCount);
|
||||
//----------------------------------------------------------------------------------------
|
||||
// Функции для работы с Brush
|
||||
//----------------------------------------------------------------------------------------
|
||||
virtual HRESULT get_BrushType(LONG* lType);
|
||||
virtual HRESULT put_BrushType(const LONG& lType);
|
||||
virtual HRESULT get_BrushColor1(LONG* lColor);
|
||||
virtual HRESULT put_BrushColor1(const LONG& lColor);
|
||||
virtual HRESULT get_BrushAlpha1(LONG* lAlpha);
|
||||
virtual HRESULT put_BrushAlpha1(const LONG& lAlpha);
|
||||
virtual HRESULT get_BrushColor2(LONG* lColor);
|
||||
virtual HRESULT put_BrushColor2(const LONG& lColor);
|
||||
virtual HRESULT get_BrushAlpha2(LONG* lAlpha);
|
||||
virtual HRESULT put_BrushAlpha2(const LONG& lAlpha);
|
||||
virtual HRESULT get_BrushTexturePath(std::wstring* wsPath);
|
||||
virtual HRESULT put_BrushTexturePath(const std::wstring& wsPath);
|
||||
virtual HRESULT get_BrushTextureMode(LONG* lMode);
|
||||
virtual HRESULT put_BrushTextureMode(const LONG& lMode);
|
||||
virtual HRESULT get_BrushTextureAlpha(LONG* lAlpha);
|
||||
virtual HRESULT put_BrushTextureAlpha(const LONG& lAlpha);
|
||||
virtual HRESULT get_BrushLinearAngle(double* dAngle);
|
||||
virtual HRESULT put_BrushLinearAngle(const double& dAngle);
|
||||
virtual HRESULT BrushRect(const INT& nVal, const double& dLeft, const double& dTop, const double& dWidth, const double& dHeight);
|
||||
virtual HRESULT BrushBounds(const double& dLeft, const double& dTop, const double& dWidth, const double& dHeight);
|
||||
virtual HRESULT put_BrushGradientColors(LONG* pColors, double* pPositions, LONG lCount);
|
||||
//----------------------------------------------------------------------------------------
|
||||
// Функции для работы со шрифтами
|
||||
//----------------------------------------------------------------------------------------
|
||||
virtual HRESULT get_FontName(std::wstring* wsName);
|
||||
virtual HRESULT put_FontName(const std::wstring& wsName);
|
||||
virtual HRESULT get_FontPath(std::wstring* wsPath);
|
||||
virtual HRESULT put_FontPath(const std::wstring& wsPath);
|
||||
virtual HRESULT get_FontSize(double* dSize);
|
||||
virtual HRESULT put_FontSize(const double& dSize);
|
||||
virtual HRESULT get_FontStyle(LONG* lStyle);
|
||||
virtual HRESULT put_FontStyle(const LONG& lStyle);
|
||||
virtual HRESULT get_FontStringGID(INT* bGid);
|
||||
virtual HRESULT put_FontStringGID(const INT& bGid);
|
||||
virtual HRESULT get_FontCharSpace(double* dSpace);
|
||||
virtual HRESULT put_FontCharSpace(const double& dSpace);
|
||||
virtual HRESULT get_FontFaceIndex(int* lFaceIndex);
|
||||
virtual HRESULT put_FontFaceIndex(const int& lFaceIndex);
|
||||
//----------------------------------------------------------------------------------------
|
||||
// Функции для вывода текста
|
||||
//----------------------------------------------------------------------------------------
|
||||
virtual HRESULT CommandDrawTextCHAR (const LONG& lUnicode, const double& dX, const double& dY, const double& dW, const double& dH);
|
||||
virtual HRESULT CommandDrawTextExCHAR(const LONG& lUnicode, const LONG& lGid, const double& dX, const double& dY, const double& dW, const double& dH);
|
||||
virtual HRESULT CommandDrawText (const std::wstring& wsUnicodeText, const double& dX, const double& dY, const double& dW, const double& dH);
|
||||
virtual HRESULT CommandDrawTextEx (const std::wstring& wsUnicodeText, const unsigned int* pGids, const unsigned int nGidsCount, const double& dX, const double& dY, const double& dW, const double& dH);
|
||||
//----------------------------------------------------------------------------------------
|
||||
// Маркеры команд
|
||||
//----------------------------------------------------------------------------------------
|
||||
virtual HRESULT BeginCommand(const DWORD& lType);
|
||||
virtual HRESULT EndCommand(const DWORD& lType);
|
||||
//----------------------------------------------------------------------------------------
|
||||
// Функции для работы с патом
|
||||
//----------------------------------------------------------------------------------------
|
||||
virtual HRESULT PathCommandMoveTo(const double& dX, const double& dY);
|
||||
virtual HRESULT PathCommandLineTo(const double& dX, const double& dY);
|
||||
virtual HRESULT PathCommandLinesTo(double* pPoints, const int& nCount);
|
||||
virtual HRESULT PathCommandCurveTo(const double& dX1, const double& dY1, const double& dX2, const double& dY2, const double& dXe, const double& dYe);
|
||||
virtual HRESULT PathCommandCurvesTo(double* pPoints, const int& nCount);
|
||||
virtual HRESULT PathCommandArcTo(const double& dX, const double& dY, const double& dW, const double& dH, const double& dStartAngle, const double& dSweepAngle);
|
||||
virtual HRESULT PathCommandClose();
|
||||
virtual HRESULT PathCommandEnd();
|
||||
virtual HRESULT DrawPath(const LONG& lType);
|
||||
virtual HRESULT PathCommandStart();
|
||||
virtual HRESULT PathCommandGetCurrentPoint(double* dX, double* dY);
|
||||
virtual HRESULT PathCommandTextCHAR (const LONG& lUnicode, const double& dX, const double& dY, const double& dW, const double& dH);
|
||||
virtual HRESULT PathCommandTextExCHAR(const LONG& lUnicode, const LONG& lGid, const double& dX, const double& dY, const double& dW, const double& dH);
|
||||
virtual HRESULT PathCommandText (const std::wstring& wsUnicodeText, const double& dX, const double& dY, const double& dW, const double& dH);
|
||||
virtual HRESULT PathCommandTextEx (const std::wstring& wsUnicodeText, const unsigned int* pGids, const unsigned int nGidsCount, const double& dX, const double& dY, const double& dW, const double& dH);
|
||||
//----------------------------------------------------------------------------------------
|
||||
// Функции для вывода изображений
|
||||
//----------------------------------------------------------------------------------------
|
||||
virtual HRESULT DrawImage(IGrObject* pImage, const double& dX, const double& dY, const double& dW, const double& dH);
|
||||
virtual HRESULT DrawImageFromFile(const std::wstring& wsImagePath, const double& dX, const double& dY, const double& dW, const double& dH, const BYTE& nAlpha = 255);
|
||||
//----------------------------------------------------------------------------------------
|
||||
// Функции для выставления преобразования
|
||||
//----------------------------------------------------------------------------------------
|
||||
virtual HRESULT SetTransform(const double& dM11, const double& dM12, const double& dM21, const double& dM22, const double& dX, const double& dY);
|
||||
virtual HRESULT GetTransform(double* dM11, double* dM12, double* dM21, double* dM22, double* dX, double* dY);
|
||||
virtual HRESULT ResetTransform();
|
||||
//----------------------------------------------------------------------------------------
|
||||
// Тип клипа
|
||||
//----------------------------------------------------------------------------------------
|
||||
virtual HRESULT get_ClipMode(LONG* lMode);
|
||||
virtual HRESULT put_ClipMode(const LONG& lMode);
|
||||
//----------------------------------------------------------------------------------------
|
||||
// Дополнительные функции
|
||||
//----------------------------------------------------------------------------------------
|
||||
virtual HRESULT CommandLong(const LONG& lType, const LONG& lCommand);
|
||||
virtual HRESULT CommandDouble(const LONG& lType, const double& dCommand);
|
||||
virtual HRESULT CommandString(const LONG& lType, const std::wstring& sCommand);
|
||||
|
||||
// методы, которыми будет пользоваться конвертер
|
||||
HRESULT SetTextAssociationType(const NSDocxRenderer::TextAssociationType& eType);
|
||||
int Convert(IOfficeDrawingFile* pFile, const std::wstring& sDstFile, bool bIsOutCompress = true);
|
||||
// методы, которыми будет пользоваться конвертер
|
||||
HRESULT SetTextAssociationType(const NSDocxRenderer::TextAssociationType& eType);
|
||||
int Convert(IOfficeDrawingFile* pFile, const std::wstring& sDstFile, bool bIsOutCompress = true);
|
||||
|
||||
private:
|
||||
CDocxRenderer_Private* m_pInternal;
|
||||
private:
|
||||
CDocxRenderer_Private* m_pInternal;
|
||||
};
|
||||
|
||||
#endif // _DOCX_RENDERER_H
|
||||
|
||||
@ -26,20 +26,43 @@ LIBS += -lgdi32 \
|
||||
}
|
||||
|
||||
HEADERS += \
|
||||
src/logic/BaseItem.h \
|
||||
src/logic/ElementContText.h \
|
||||
src/logic/ElementOldShape.h \
|
||||
src/logic/ElementShape.h \
|
||||
src/logic/ElementTextLine.h \
|
||||
src/logic/ImageManager.h \
|
||||
src/resources/ColorTable.h \
|
||||
src/resources/Constants.h \
|
||||
src/resources/LinesTable.h \
|
||||
src/resources/SingletonTemplate.h \
|
||||
src/resources/SortElements.h \
|
||||
src/resources/VectorGraphics.h \
|
||||
src/resources/resources.h \
|
||||
\
|
||||
src/logic/Common.h \
|
||||
src/logic/Page.h \
|
||||
src/logic/Document.h \
|
||||
src/logic/ElementImage.h \
|
||||
src/logic/ElementParagraph.h \
|
||||
src/logic/ElementShape.h \
|
||||
src/logic/FontManager.h \
|
||||
src/logic/FontManagerBase.h \
|
||||
\
|
||||
DocxRenderer.h
|
||||
DocxRenderer.h \
|
||||
src/resources/utils.h
|
||||
|
||||
SOURCES += \
|
||||
src/logic/Document.cpp \
|
||||
src/logic/ElementContText.cpp \
|
||||
src/logic/ElementImage.cpp \
|
||||
src/logic/ElementOldShape.cpp \
|
||||
src/logic/ElementParagraph.cpp \
|
||||
src/logic/ElementShape.cpp \
|
||||
src/logic/ElementTextLine.cpp \
|
||||
src/logic/FontManager.cpp \
|
||||
src/logic/FontManagerBase.cpp \
|
||||
src/logic/ImageManager.cpp \
|
||||
src/logic/Page.cpp \
|
||||
src/resources/VectorGraphics.cpp \
|
||||
src/resources/resources.cpp \
|
||||
\
|
||||
DocxRenderer.cpp
|
||||
|
||||
79
DocxRenderer/src/logic/BaseItem.h
Normal file
79
DocxRenderer/src/logic/BaseItem.h
Normal file
@ -0,0 +1,79 @@
|
||||
#pragma once
|
||||
#include "../DesktopEditor/common/StringBuilder.h"
|
||||
|
||||
namespace NSDocxRenderer
|
||||
{
|
||||
class CBaseItem
|
||||
{
|
||||
public:
|
||||
enum class ElemType
|
||||
{
|
||||
etContText = 0,
|
||||
etTextLine = 1,
|
||||
etParagraph = 2,
|
||||
etImage = 3,
|
||||
etShape = 4,
|
||||
etOldShape = 5,
|
||||
};
|
||||
|
||||
ElemType m_eType;
|
||||
|
||||
bool m_bIsNotNecessaryToUse {false};
|
||||
|
||||
double m_dLeft {0.0};
|
||||
double m_dTop {0.0};
|
||||
double m_dWidth {0.0};
|
||||
double m_dHeight {0.0};
|
||||
|
||||
public:
|
||||
CBaseItem(const ElemType& eType): m_eType(eType) {}
|
||||
virtual ~CBaseItem() {}
|
||||
|
||||
CBaseItem& operator=(const CBaseItem& oSrc)
|
||||
{
|
||||
if (this == &oSrc)
|
||||
{
|
||||
return *this;
|
||||
}
|
||||
|
||||
m_eType = oSrc.m_eType;
|
||||
m_bIsNotNecessaryToUse = oSrc.m_bIsNotNecessaryToUse;
|
||||
|
||||
m_dLeft = oSrc.m_dLeft;
|
||||
m_dTop = oSrc.m_dTop;
|
||||
m_dWidth = oSrc.m_dWidth;
|
||||
m_dHeight = oSrc.m_dHeight;
|
||||
|
||||
return *this;
|
||||
}
|
||||
|
||||
friend bool operator == (const CBaseItem& lh, const CBaseItem& rh)
|
||||
{
|
||||
return (lh.m_dLeft == rh.m_dLeft) ? true : false;
|
||||
}
|
||||
|
||||
friend bool operator < (const CBaseItem& lh, const CBaseItem& rh)
|
||||
{
|
||||
return (lh.m_dLeft < rh.m_dLeft) ? true : false;
|
||||
}
|
||||
|
||||
friend bool operator > (const CBaseItem& lh, const CBaseItem& rh)
|
||||
{
|
||||
return (lh.m_dLeft > rh.m_dLeft) ? true : false;
|
||||
}
|
||||
|
||||
virtual bool IsBigger(const CBaseItem* oSrc)
|
||||
{
|
||||
return (m_dLeft > oSrc->m_dLeft) ? true : false;
|
||||
}
|
||||
|
||||
virtual bool IsBiggerOrEqual(const CBaseItem* oSrc)
|
||||
{
|
||||
return (m_dLeft >= oSrc->m_dLeft) ? true : false;
|
||||
}
|
||||
|
||||
|
||||
virtual void ToXml(NSStringUtils::CStringBuilder& oWriter) = 0;
|
||||
virtual void Clear() = 0;
|
||||
};
|
||||
}
|
||||
@ -11,298 +11,5 @@
|
||||
#include "../DesktopEditor/common/Directory.h"
|
||||
#include "../DesktopEditor/xml/include/xmlutils.h"
|
||||
#include "../DesktopEditor/graphics/pro/Graphics.h"
|
||||
#include <algorithm>
|
||||
#include <map>
|
||||
|
||||
namespace NSDocxRenderer
|
||||
{
|
||||
inline LONG ConvertColor(LONG lBGR)
|
||||
{
|
||||
return (0x00FFFFFF & (((lBGR & 0xFF) << 16) | (lBGR & 0x0000FF00) | ((lBGR >> 16) & 0xFF)));
|
||||
}
|
||||
|
||||
class CBaseItem
|
||||
{
|
||||
public:
|
||||
enum ElemType
|
||||
{
|
||||
etParagraph = 0,
|
||||
etImage = 1,
|
||||
etShape = 2
|
||||
};
|
||||
|
||||
ElemType m_eType;
|
||||
|
||||
CBaseItem()
|
||||
{
|
||||
m_eType = etShape;
|
||||
}
|
||||
virtual ~CBaseItem() {}
|
||||
|
||||
virtual void ToXml(NSStringUtils::CStringBuilder& oWriter) = 0;
|
||||
};
|
||||
|
||||
class CImageInfo
|
||||
{
|
||||
public:
|
||||
enum ImageType
|
||||
{
|
||||
itPNG = 0,
|
||||
itJPG = 1
|
||||
};
|
||||
|
||||
public:
|
||||
ImageType m_eType;
|
||||
int m_nId;
|
||||
|
||||
CImageInfo()
|
||||
{
|
||||
m_eType = itPNG;
|
||||
m_nId = 0;
|
||||
}
|
||||
};
|
||||
|
||||
class CImageManager
|
||||
{
|
||||
public:
|
||||
std::map<std::wstring, CImageInfo> m_mapImagesFile;
|
||||
std::map<DWORD, CImageInfo> m_mapImageData;
|
||||
|
||||
std::wstring m_strDstMedia;
|
||||
|
||||
int m_lMaxSizeImage;
|
||||
int m_lNextIDImage;
|
||||
|
||||
CCalculatorCRC32 m_oCRC;
|
||||
|
||||
public:
|
||||
|
||||
CImageManager()
|
||||
{
|
||||
m_strDstMedia = L"";
|
||||
m_lMaxSizeImage = 1200;
|
||||
m_lNextIDImage = 0;
|
||||
}
|
||||
|
||||
inline void NewDocument()
|
||||
{
|
||||
m_strDstMedia = L"";
|
||||
m_lMaxSizeImage = 1200;
|
||||
m_lNextIDImage = 0;
|
||||
|
||||
m_mapImageData.clear();
|
||||
m_mapImagesFile.clear();
|
||||
}
|
||||
|
||||
public:
|
||||
CImageInfo WriteImage(Aggplus::CImage* pImage, double& x, double& y, double& width, double& height)
|
||||
{
|
||||
if (height < 0)
|
||||
{
|
||||
FlipY(pImage);
|
||||
height = -height;
|
||||
y -= height;
|
||||
}
|
||||
|
||||
return GenerateImageID(pImage);
|
||||
}
|
||||
CImageInfo WriteImage(const std::wstring& strFile, double& x, double& y, double& width, double& height)
|
||||
{
|
||||
return GenerateImageID(strFile);
|
||||
}
|
||||
|
||||
protected:
|
||||
inline void CopyFile(std::wstring& strFileSrc, std::wstring& strFileDst)
|
||||
{
|
||||
NSFile::CFileBinary::Copy(strFileSrc, strFileDst);
|
||||
}
|
||||
void SaveImage(const std::wstring& strFileSrc, CImageInfo& oInfo)
|
||||
{
|
||||
Aggplus::CImage oFrame(strFileSrc);
|
||||
if (NULL != oFrame.GetData())
|
||||
return SaveImage(&oFrame, oInfo);
|
||||
}
|
||||
void SaveImage(Aggplus::CImage* pImage, CImageInfo& oInfo)
|
||||
{
|
||||
if (NULL == pImage)
|
||||
return;
|
||||
|
||||
int w = pImage->GetWidth();
|
||||
int h = pImage->GetHeight();
|
||||
|
||||
oInfo.m_eType = GetImageType(pImage);
|
||||
|
||||
int format = (oInfo.m_eType == CImageInfo::itJPG) ? 3 : 4;
|
||||
std::wstring sSavedFile = m_strDstMedia + L"/image" + std::to_wstring(oInfo.m_nId);
|
||||
sSavedFile += ((oInfo.m_eType == CImageInfo::itJPG) ? L".jpg" : L".png");
|
||||
|
||||
if (w <= m_lMaxSizeImage && h <= m_lMaxSizeImage)
|
||||
{
|
||||
pImage->SaveFile(sSavedFile, format);
|
||||
}
|
||||
else
|
||||
{
|
||||
int lW = 0;
|
||||
int lH = 0;
|
||||
double dAspect = (double)w / h;
|
||||
|
||||
if (w >= h)
|
||||
{
|
||||
lW = m_lMaxSizeImage;
|
||||
lH = (int)((double)lW / dAspect);
|
||||
}
|
||||
else
|
||||
{
|
||||
lH = m_lMaxSizeImage;
|
||||
lW = (LONG)(dAspect * lH);
|
||||
}
|
||||
|
||||
// TODO: resize
|
||||
pImage->SaveFile(sSavedFile, format);
|
||||
}
|
||||
}
|
||||
|
||||
CImageInfo GenerateImageID(Aggplus::CImage* pImage)
|
||||
{
|
||||
BYTE* pData = pImage->GetData();
|
||||
int nSize = pImage->GetStride() * pImage->GetHeight();
|
||||
if (nSize < 0)
|
||||
nSize = -nSize;
|
||||
|
||||
DWORD dwSum = m_oCRC.Calc(pData, nSize);
|
||||
|
||||
std::map<DWORD, CImageInfo>::iterator find = m_mapImageData.find(dwSum);
|
||||
if (find != m_mapImageData.end())
|
||||
return find->second;
|
||||
|
||||
++m_lNextIDImage;
|
||||
CImageInfo oInfo;
|
||||
oInfo.m_nId = m_lNextIDImage;
|
||||
SaveImage(pImage, oInfo);
|
||||
m_mapImageData.insert(std::pair<DWORD, CImageInfo>(dwSum, oInfo));
|
||||
|
||||
return oInfo;
|
||||
}
|
||||
|
||||
CImageInfo GenerateImageID(const std::wstring& strFileName)
|
||||
{
|
||||
std::map<std::wstring, CImageInfo>::iterator find = m_mapImagesFile.find(strFileName);
|
||||
if (find != m_mapImagesFile.end())
|
||||
return find->second;
|
||||
|
||||
++m_lNextIDImage;
|
||||
CImageInfo oInfo;
|
||||
oInfo.m_nId = m_lNextIDImage;
|
||||
SaveImage(strFileName, oInfo);
|
||||
m_mapImagesFile.insert(std::pair<std::wstring, CImageInfo>(strFileName, oInfo));
|
||||
|
||||
return oInfo;
|
||||
}
|
||||
|
||||
CImageInfo::ImageType GetImageType(Aggplus::CImage* pFrame)
|
||||
{
|
||||
int w = pFrame->GetWidth();
|
||||
int h = pFrame->GetHeight();
|
||||
BYTE* pBuffer = pFrame->GetData();
|
||||
|
||||
BYTE* pBufferMem = pBuffer + 3;
|
||||
LONG lCountPix = w * h;
|
||||
|
||||
for (LONG i = 0; i < lCountPix; ++i, pBufferMem += 4)
|
||||
{
|
||||
if (255 != *pBufferMem)
|
||||
return CImageInfo::itPNG;
|
||||
}
|
||||
return CImageInfo::itJPG;
|
||||
}
|
||||
|
||||
void FlipY(Aggplus::CImage* pImage)
|
||||
{
|
||||
if (NULL == pImage)
|
||||
return;
|
||||
|
||||
int w = pImage->GetWidth();
|
||||
int h = pImage->GetHeight();
|
||||
BYTE* pBuffer = pImage->GetData();
|
||||
int stride = pImage->GetStride();
|
||||
|
||||
if (stride < 0)
|
||||
stride = -stride;
|
||||
|
||||
if ((w * 4) != stride)
|
||||
return;
|
||||
|
||||
BYTE* pBufferMem = new BYTE[stride];
|
||||
|
||||
BYTE* pBufferEnd = pBuffer + stride * (h - 1);
|
||||
|
||||
LONG lCountV = h / 2;
|
||||
|
||||
for (LONG lIndexV = 0; lIndexV < lCountV; ++lIndexV)
|
||||
{
|
||||
memcpy(pBufferMem, pBuffer, stride);
|
||||
memcpy(pBuffer, pBufferEnd, stride);
|
||||
memcpy(pBufferEnd, pBufferMem, stride);
|
||||
|
||||
pBuffer += stride;
|
||||
pBufferEnd -= stride;
|
||||
}
|
||||
|
||||
RELEASEARRAYOBJECTS(pBufferMem);
|
||||
}
|
||||
|
||||
void FlipX(CBgraFrame* pImage)
|
||||
{
|
||||
if (NULL == pImage)
|
||||
return;
|
||||
|
||||
int w = pImage->get_Width();
|
||||
int h = pImage->get_Height();
|
||||
BYTE* pBuffer = pImage->get_Data();
|
||||
int stride = pImage->get_Stride();
|
||||
|
||||
if (stride < 0)
|
||||
stride = -stride;
|
||||
|
||||
if ((w * 4) != stride)
|
||||
return;
|
||||
|
||||
DWORD* pBufferDWORD = (DWORD*)pBuffer;
|
||||
|
||||
LONG lW2 = w / 2;
|
||||
for (LONG lIndexV = 0; lIndexV < h; ++lIndexV)
|
||||
{
|
||||
DWORD* pMem1 = pBufferDWORD;
|
||||
DWORD* pMem2 = pBufferDWORD + w - 1;
|
||||
|
||||
LONG lI = 0;
|
||||
while (lI < lW2)
|
||||
{
|
||||
DWORD dwMem = *pMem1;
|
||||
*pMem1++ = *pMem2;
|
||||
*pMem2-- = dwMem;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
};
|
||||
}
|
||||
|
||||
namespace NSDocxRenderer
|
||||
{
|
||||
// 2-byte number
|
||||
inline short little_endian_2_big_endian( short s )
|
||||
{
|
||||
return ( ( s >> 8) & 0xff ) + ( ( s << 8 ) & 0xff00 );
|
||||
}
|
||||
|
||||
/*========================================================================================================*/
|
||||
|
||||
// 4-byte number
|
||||
inline int little_endian_2_big_endian( int i )
|
||||
{
|
||||
return ( ( i & 0xff ) << 24 ) + ( ( i & 0xff00 ) << 8 ) + ( ( i & 0xff0000 ) >> 8 ) + ( ( i >> 24 ) & 0xff );
|
||||
}
|
||||
}
|
||||
|
||||
#endif // DOCX_RENDERER_COMMON_H
|
||||
|
||||
967
DocxRenderer/src/logic/Document.cpp
Normal file
967
DocxRenderer/src/logic/Document.cpp
Normal file
@ -0,0 +1,967 @@
|
||||
#include "Document.h"
|
||||
|
||||
namespace NSDocxRenderer
|
||||
{
|
||||
CDocument::CDocument(IRenderer* pRenderer, NSFonts::IApplicationFonts* pFonts) :
|
||||
m_pAppFonts(pFonts), m_oCurrentPage(pFonts)
|
||||
{
|
||||
m_oSimpleGraphicsConverter.SetRenderer(pRenderer);
|
||||
}
|
||||
void CDocument::Clear()
|
||||
{
|
||||
m_lClipMode = 0;
|
||||
}
|
||||
|
||||
CDocument::~CDocument() {
|
||||
m_lClipMode = 0;
|
||||
RELEASEINTERFACE(m_pFontManager);
|
||||
}
|
||||
|
||||
HRESULT CDocument::NewPage()
|
||||
{
|
||||
if (0 != m_lPagesCount)
|
||||
{
|
||||
m_oCurrentPage.WriteSectionToFile(false, m_oWriter);
|
||||
m_oDocumentStream.WriteStringUTF8(m_oWriter.GetData());
|
||||
m_oWriter.ClearNoAttack();
|
||||
}
|
||||
|
||||
m_oPen.SetDefaultParams();
|
||||
m_oBrush.SetDefaultParams();
|
||||
m_oFont.SetDefaultParams();
|
||||
m_oShadow.SetDefaultParams();
|
||||
m_oEdge.SetDefaultParams();
|
||||
|
||||
m_oTransform.Reset();
|
||||
|
||||
++m_lPagesCount;
|
||||
m_oCurrentPage.Clear();
|
||||
|
||||
return S_OK;
|
||||
}
|
||||
HRESULT CDocument::get_Height(double* dHeight)
|
||||
{
|
||||
*dHeight = m_dHeight;
|
||||
return S_OK;
|
||||
}
|
||||
HRESULT CDocument::put_Height(double dHeight)
|
||||
{
|
||||
m_dHeight = dHeight;
|
||||
m_oCurrentPage.m_dHeight = dHeight;
|
||||
return S_OK;
|
||||
}
|
||||
HRESULT CDocument::get_Width(double* dWidth)
|
||||
{
|
||||
*dWidth = m_dWidth;
|
||||
return S_OK;
|
||||
}
|
||||
HRESULT CDocument::put_Width(double dWidth)
|
||||
{
|
||||
m_dWidth = dWidth;
|
||||
m_oCurrentPage.m_dWidth = dWidth;
|
||||
return S_OK;
|
||||
}
|
||||
HRESULT CDocument::get_DpiX(double* dDpiX)
|
||||
{
|
||||
*dDpiX = m_dDpiX;
|
||||
return S_OK;
|
||||
}
|
||||
HRESULT CDocument::get_DpiY(double* dDpiY)
|
||||
{
|
||||
*dDpiY = m_dDpiY;
|
||||
return S_OK;
|
||||
}
|
||||
//-------- Функции для задания настроек текста ----------------------------------------------
|
||||
// pen --------------------------------------------------------------------------------------
|
||||
HRESULT CDocument::get_PenColor(LONG* lColor)
|
||||
{
|
||||
*lColor = m_oPen.Color;
|
||||
return S_OK;
|
||||
}
|
||||
HRESULT CDocument::put_PenColor(LONG lColor)
|
||||
{
|
||||
m_oPen.Color = lColor;
|
||||
return S_OK;
|
||||
}
|
||||
HRESULT CDocument::get_PenAlpha(LONG* lAlpha)
|
||||
{
|
||||
*lAlpha = m_oPen.Alpha;
|
||||
return S_OK;
|
||||
}
|
||||
HRESULT CDocument::put_PenAlpha(LONG lAlpha)
|
||||
{
|
||||
m_oPen.Alpha = lAlpha;
|
||||
return S_OK;
|
||||
}
|
||||
HRESULT CDocument::get_PenSize(double* dSize)
|
||||
{
|
||||
*dSize = m_oPen.Size;
|
||||
return S_OK;
|
||||
}
|
||||
HRESULT CDocument::put_PenSize(double dSize)
|
||||
{
|
||||
m_oPen.Size = dSize;
|
||||
return S_OK;
|
||||
}
|
||||
HRESULT CDocument::get_PenDashStyle(BYTE* val)
|
||||
{
|
||||
*val = m_oPen.DashStyle;
|
||||
return S_OK;
|
||||
}
|
||||
HRESULT CDocument::put_PenDashStyle(BYTE val)
|
||||
{
|
||||
m_oPen.DashStyle = val;
|
||||
return S_OK;
|
||||
}
|
||||
HRESULT CDocument::get_PenLineStartCap(BYTE* val)
|
||||
{
|
||||
*val = m_oPen.LineStartCap;
|
||||
return S_OK;
|
||||
}
|
||||
HRESULT CDocument::put_PenLineStartCap(BYTE val)
|
||||
{
|
||||
m_oPen.LineStartCap = val;
|
||||
return S_OK;
|
||||
}
|
||||
HRESULT CDocument::get_PenLineEndCap(BYTE* val)
|
||||
{
|
||||
*val = m_oPen.LineEndCap;
|
||||
return S_OK;
|
||||
}
|
||||
HRESULT CDocument::put_PenLineEndCap(BYTE val)
|
||||
{
|
||||
m_oPen.LineEndCap = val;
|
||||
return S_OK;
|
||||
}
|
||||
HRESULT CDocument::get_PenLineJoin(BYTE* val)
|
||||
{
|
||||
*val = m_oPen.LineJoin;
|
||||
return S_OK;
|
||||
}
|
||||
HRESULT CDocument::put_PenLineJoin(BYTE val)
|
||||
{
|
||||
m_oPen.LineJoin = val;
|
||||
return S_OK;
|
||||
}
|
||||
HRESULT CDocument::get_PenDashOffset(double* val)
|
||||
{
|
||||
*val = m_oPen.DashOffset;
|
||||
return S_OK;
|
||||
}
|
||||
HRESULT CDocument::put_PenDashOffset(double val)
|
||||
{
|
||||
m_oPen.DashOffset = val;
|
||||
return S_OK;
|
||||
}
|
||||
HRESULT CDocument::get_PenAlign(LONG* val)
|
||||
{
|
||||
*val = m_oPen.Align;
|
||||
return S_OK;
|
||||
}
|
||||
HRESULT CDocument::put_PenAlign(LONG val)
|
||||
{
|
||||
m_oPen.Align = val;
|
||||
return S_OK;
|
||||
}
|
||||
HRESULT CDocument::get_PenMiterLimit(double* val)
|
||||
{
|
||||
*val = m_oPen.MiterLimit;
|
||||
return S_OK;
|
||||
}
|
||||
HRESULT CDocument::put_PenMiterLimit(double val)
|
||||
{
|
||||
m_oPen.MiterLimit = val;
|
||||
return S_OK;
|
||||
}
|
||||
HRESULT CDocument::PenDashPattern(double* pPattern, LONG lCount)
|
||||
{
|
||||
if (nullptr != pPattern)
|
||||
{
|
||||
m_oPen.SetDashPattern(pPattern, lCount);
|
||||
}
|
||||
|
||||
return S_OK;
|
||||
}
|
||||
// brush ------------------------------------------------------------------------------------
|
||||
HRESULT CDocument::get_BrushType(LONG* lType)
|
||||
{
|
||||
*lType = m_oBrush.Type;
|
||||
return S_OK;
|
||||
}
|
||||
HRESULT CDocument::put_BrushType(LONG lType)
|
||||
{
|
||||
m_oBrush.Type = lType;
|
||||
return S_OK;
|
||||
}
|
||||
HRESULT CDocument::get_BrushColor1(LONG* lColor)
|
||||
{
|
||||
*lColor = m_oBrush.Color1;
|
||||
return S_OK;
|
||||
}
|
||||
HRESULT CDocument::put_BrushColor1(LONG lColor)
|
||||
{
|
||||
m_oBrush.Color1 = lColor;
|
||||
return S_OK;
|
||||
}
|
||||
HRESULT CDocument::get_BrushAlpha1(LONG* lAlpha)
|
||||
{
|
||||
*lAlpha = m_oBrush.Alpha1;
|
||||
return S_OK;
|
||||
}
|
||||
HRESULT CDocument::put_BrushAlpha1(LONG lAlpha)
|
||||
{
|
||||
m_oBrush.Alpha1 = lAlpha;
|
||||
return S_OK;
|
||||
}
|
||||
HRESULT CDocument::get_BrushColor2(LONG* lColor)
|
||||
{
|
||||
*lColor = m_oBrush.Color2;
|
||||
return S_OK;
|
||||
}
|
||||
HRESULT CDocument::put_BrushColor2(LONG lColor)
|
||||
{
|
||||
m_oBrush.Color2 = lColor;
|
||||
return S_OK;
|
||||
}
|
||||
HRESULT CDocument::get_BrushAlpha2(LONG* lAlpha)
|
||||
{
|
||||
*lAlpha = m_oBrush.Alpha2;
|
||||
return S_OK;
|
||||
}
|
||||
HRESULT CDocument::put_BrushAlpha2(LONG lAlpha)
|
||||
{
|
||||
m_oBrush.Alpha2 = lAlpha;
|
||||
return S_OK;
|
||||
}
|
||||
HRESULT CDocument::get_BrushTexturePath(std::wstring* sPath)
|
||||
{
|
||||
*sPath = m_oBrush.TexturePath;
|
||||
return S_OK;
|
||||
}
|
||||
HRESULT CDocument::put_BrushTexturePath(const std::wstring& sPath)
|
||||
{
|
||||
m_oBrush.TexturePath = sPath;
|
||||
return S_OK;
|
||||
}
|
||||
HRESULT CDocument::get_BrushTextureMode(LONG* lMode)
|
||||
{
|
||||
*lMode = m_oBrush.TextureMode;
|
||||
return S_OK;
|
||||
}
|
||||
HRESULT CDocument::put_BrushTextureMode(LONG lMode)
|
||||
{
|
||||
m_oBrush.TextureMode = lMode;
|
||||
return S_OK;
|
||||
}
|
||||
HRESULT CDocument::get_BrushTextureAlpha(LONG* lTxAlpha)
|
||||
{
|
||||
*lTxAlpha = m_oBrush.TextureAlpha;
|
||||
return S_OK;
|
||||
}
|
||||
HRESULT CDocument::put_BrushTextureAlpha(LONG lTxAlpha)
|
||||
{
|
||||
m_oBrush.TextureAlpha = lTxAlpha;
|
||||
return S_OK;
|
||||
}
|
||||
HRESULT CDocument::get_BrushLinearAngle(double* dAngle)
|
||||
{
|
||||
*dAngle = m_oBrush.LinearAngle;
|
||||
return S_OK;
|
||||
}
|
||||
HRESULT CDocument::put_BrushLinearAngle(double dAngle)
|
||||
{
|
||||
m_oBrush.LinearAngle = dAngle;
|
||||
return S_OK;
|
||||
}
|
||||
HRESULT CDocument::BrushRect(bool val, double left, double top, double width, double height)
|
||||
{
|
||||
m_oBrush.Rectable = val ? 1 : 0;
|
||||
m_oBrush.Rect.X = (float)left;
|
||||
m_oBrush.Rect.Y = (float)top;
|
||||
m_oBrush.Rect.Width = (float)width;
|
||||
m_oBrush.Rect.Height = (float)height;
|
||||
|
||||
return S_OK;
|
||||
}
|
||||
// font -------------------------------------------------------------------------------------
|
||||
HRESULT CDocument::get_FontName(std::wstring* sName)
|
||||
{
|
||||
*sName = m_oFont.Name;
|
||||
return S_OK;
|
||||
}
|
||||
HRESULT CDocument::put_FontName(std::wstring sName)
|
||||
{
|
||||
m_oFont.Name = sName;
|
||||
return S_OK;
|
||||
}
|
||||
HRESULT CDocument::get_FontPath(std::wstring* sPath)
|
||||
{
|
||||
*sPath = m_oFont.Path;
|
||||
return S_OK;
|
||||
}
|
||||
HRESULT CDocument::put_FontPath(std::wstring sPath)
|
||||
{
|
||||
m_oFont.Path = sPath;
|
||||
return S_OK;
|
||||
}
|
||||
HRESULT CDocument::get_FontSize(double* dSize)
|
||||
{
|
||||
*dSize = m_oFont.Size;
|
||||
return S_OK;
|
||||
}
|
||||
HRESULT CDocument::put_FontSize(double dSize)
|
||||
{
|
||||
m_oFont.Size = dSize;
|
||||
return S_OK;
|
||||
}
|
||||
HRESULT CDocument::get_FontStyle(LONG* lStyle)
|
||||
{
|
||||
*lStyle = m_oFont.GetStyle();
|
||||
return S_OK;
|
||||
}
|
||||
HRESULT CDocument::put_FontStyle(LONG lStyle)
|
||||
{
|
||||
m_oFont.SetStyle(lStyle);
|
||||
return S_OK;
|
||||
}
|
||||
HRESULT CDocument::get_FontStringGID(INT* bGID)
|
||||
{
|
||||
*bGID = m_oFont.StringGID;
|
||||
return S_OK;
|
||||
}
|
||||
HRESULT CDocument::put_FontStringGID(INT bGID)
|
||||
{
|
||||
m_oFont.StringGID = bGID;
|
||||
return S_OK;
|
||||
}
|
||||
HRESULT CDocument::get_FontCharSpace(double* dSpace)
|
||||
{
|
||||
*dSpace = m_oFont.CharSpace;
|
||||
return S_OK;
|
||||
}
|
||||
HRESULT CDocument::put_FontCharSpace(double dSpace)
|
||||
{
|
||||
m_oFont.CharSpace = dSpace;
|
||||
return S_OK;
|
||||
}
|
||||
HRESULT CDocument::get_FontFaceIndex(int* lFaceIndex)
|
||||
{
|
||||
*lFaceIndex = m_oFont.FaceIndex;
|
||||
return S_OK;
|
||||
}
|
||||
HRESULT CDocument::put_FontFaceIndex(const int& lFaceIndex)
|
||||
{
|
||||
m_oFont.FaceIndex = lFaceIndex;
|
||||
return S_OK;
|
||||
}
|
||||
// shadow -----------------------------------------------------------------------------------
|
||||
HRESULT CDocument::get_ShadowDistanceX(double* val)
|
||||
{
|
||||
*val = m_oShadow.DistanceX;
|
||||
return S_OK;
|
||||
}
|
||||
HRESULT CDocument::put_ShadowDistanceX(double val)
|
||||
{
|
||||
m_oShadow.DistanceX = val;
|
||||
return S_OK;
|
||||
}
|
||||
HRESULT CDocument::get_ShadowDistanceY(double* val)
|
||||
{
|
||||
*val = m_oShadow.DistanceY;
|
||||
return S_OK;
|
||||
}
|
||||
HRESULT CDocument::put_ShadowDistanceY(double val)
|
||||
{
|
||||
m_oShadow.DistanceY = val;
|
||||
return S_OK;
|
||||
}
|
||||
HRESULT CDocument::get_ShadowBlurSize(double* val)
|
||||
{
|
||||
*val = m_oShadow.BlurSize;
|
||||
return S_OK;
|
||||
}
|
||||
HRESULT CDocument::put_ShadowBlurSize(double val)
|
||||
{
|
||||
m_oShadow.BlurSize = val;
|
||||
return S_OK;
|
||||
}
|
||||
HRESULT CDocument::get_ShadowColor(LONG* val)
|
||||
{
|
||||
*val = m_oShadow.Color;
|
||||
return S_OK;
|
||||
}
|
||||
HRESULT CDocument::put_ShadowColor(LONG val)
|
||||
{
|
||||
m_oShadow.Color = val;
|
||||
return S_OK;
|
||||
}
|
||||
HRESULT CDocument::get_ShadowAlpha(LONG* val)
|
||||
{
|
||||
*val = m_oShadow.Alpha;
|
||||
return S_OK;
|
||||
}
|
||||
HRESULT CDocument::put_ShadowAlpha(LONG val)
|
||||
{
|
||||
m_oShadow.Alpha = val;
|
||||
return S_OK;
|
||||
}
|
||||
HRESULT CDocument::get_ShadowVisible(INT* val)
|
||||
{
|
||||
*val = m_oShadow.Visible;
|
||||
return S_OK;
|
||||
}
|
||||
HRESULT CDocument::put_ShadowVisible(INT val)
|
||||
{
|
||||
m_oShadow.Visible = val;
|
||||
return S_OK;
|
||||
}
|
||||
// edge -------------------------------------------------------------------------------------
|
||||
HRESULT CDocument::get_EdgeVisible(LONG* val)
|
||||
{
|
||||
*val = m_oEdge.Visible;
|
||||
return S_OK;
|
||||
}
|
||||
HRESULT CDocument::put_EdgeVisible(LONG val)
|
||||
{
|
||||
m_oEdge.Visible = val;
|
||||
return S_OK;
|
||||
}
|
||||
HRESULT CDocument::get_EdgeColor(LONG* val)
|
||||
{
|
||||
*val = m_oEdge.Color;
|
||||
return S_OK;
|
||||
}
|
||||
HRESULT CDocument::put_EdgeColor(LONG val)
|
||||
{
|
||||
m_oEdge.Color = val;
|
||||
return S_OK;
|
||||
}
|
||||
HRESULT CDocument::get_EdgeAlpha(LONG* val)
|
||||
{
|
||||
*val = m_oEdge.Alpha;
|
||||
return S_OK;
|
||||
}
|
||||
HRESULT CDocument::put_EdgeAlpha(LONG val)
|
||||
{
|
||||
m_oEdge.Alpha = val;
|
||||
return S_OK;
|
||||
}
|
||||
HRESULT CDocument::get_EdgeDist(double* val)
|
||||
{
|
||||
*val = m_oEdge.Dist;
|
||||
return S_OK;
|
||||
}
|
||||
HRESULT CDocument::put_EdgeDist(double val)
|
||||
{
|
||||
m_oEdge.Dist = val;
|
||||
return S_OK;
|
||||
}
|
||||
|
||||
//-------- Функции для вывода текста --------------------------------------------------------
|
||||
HRESULT CDocument::CommandDrawTextPrivate(const int* pUnicodes, const int* pGids, int nCount,
|
||||
const double& dX, const double& dY, const double& dW,
|
||||
const double& dH, const double& dBaseLineOffset)
|
||||
{
|
||||
double dAngleMatrix = m_oTransform.z_Rotation();
|
||||
if (abs(dAngleMatrix) > 1 || m_oTransform.sx() < 0 || m_oTransform.sy() < 0)
|
||||
{
|
||||
_SetFont();
|
||||
PathCommandEnd();
|
||||
BeginCommand(c_nPathType);
|
||||
m_oSimpleGraphicsConverter.PathCommandText2(pUnicodes, pGids, nCount, m_pFontManager, dX, dY, dW, dH);
|
||||
DrawPath(c_nWindingFillMode);
|
||||
EndCommand(c_nPathType);
|
||||
PathCommandEnd();
|
||||
return S_OK;
|
||||
}
|
||||
|
||||
m_oCurrentPage.CollectTextData((unsigned int*)pUnicodes, (unsigned int*)pGids, nCount, dX, dY, dW, dH, 0, m_bIsNeedPDFTextAnalyzer);
|
||||
return S_OK;
|
||||
}
|
||||
|
||||
HRESULT CDocument::CommandDrawTextCHAR(const int& lUnicode, const double& dX, const double& dY, const double& dW, const double& dH)
|
||||
{
|
||||
return CommandDrawTextPrivate(&lUnicode, nullptr, 1, dX, dY, dW, dH);
|
||||
}
|
||||
HRESULT CDocument::CommandDrawTextExCHAR(const int& lUnicode, const int& lGid, const double& dX, const double& dY, const double& dW, const double& dH)
|
||||
{
|
||||
return CommandDrawTextPrivate(&lUnicode, &lGid, 1, dX, dY, dW, dH);
|
||||
}
|
||||
HRESULT CDocument::CommandDrawText(const std::wstring& wsUnicodeText, const double& dX, const double& dY, const double& dW, const double& dH)
|
||||
{
|
||||
unsigned int nLen = 0;
|
||||
unsigned int* pUnicodes = NSStringExt::CConverter::GetUtf32FromUnicode(wsUnicodeText, nLen);
|
||||
if (nLen == 0)
|
||||
return S_OK;
|
||||
CommandDrawTextPrivate((int*)pUnicodes, nullptr, nLen, dX, dY, dW, dH);
|
||||
delete [] pUnicodes;
|
||||
return S_OK;
|
||||
}
|
||||
HRESULT CDocument::CommandDrawTextEx(const std::wstring& wsUnicodeText, const unsigned int* pGids, const unsigned int nGidsCount, const double& dX, const double& dY, const double& dW, const double& dH)
|
||||
{
|
||||
unsigned int nLen = 0;
|
||||
unsigned int* pUnicodes = NSStringExt::CConverter::GetUtf32FromUnicode(wsUnicodeText, nLen);
|
||||
if (nLen == 0)
|
||||
return S_OK;
|
||||
if (nLen != nGidsCount)
|
||||
{
|
||||
delete [] pUnicodes;
|
||||
return S_OK;
|
||||
}
|
||||
|
||||
CommandDrawTextPrivate((int*)pUnicodes, (int*)pGids, (int)nLen, dX, dY, dW, dH);
|
||||
delete [] pUnicodes;
|
||||
return S_OK;
|
||||
}
|
||||
//-------- Маркеры для команд ---------------------------------------------------------------
|
||||
HRESULT CDocument::BeginCommand(DWORD lType)
|
||||
{
|
||||
if (c_nPageType == lType && m_bIsDisablePageCommand)
|
||||
return S_OK;
|
||||
|
||||
m_lCurrentCommandType = (LONG)lType;
|
||||
m_oCurrentPage.m_lCurrentCommand = m_lCurrentCommandType;
|
||||
|
||||
if (c_nTextType == lType)
|
||||
m_oCurrentPage.m_dLastTextX_block = -1;
|
||||
|
||||
return S_OK;
|
||||
}
|
||||
HRESULT CDocument::EndCommand(DWORD lType)
|
||||
{
|
||||
if (c_nPageType == lType && m_bIsDisablePageCommand)
|
||||
return S_OK;
|
||||
|
||||
m_lCurrentCommandType = -1;
|
||||
m_oCurrentPage.m_lCurrentCommand = m_lCurrentCommandType;
|
||||
|
||||
if (c_nPageType == lType)
|
||||
{
|
||||
// нужно записать страницу в файл
|
||||
m_oCurrentPage.AnalyzeCollectedShapes();
|
||||
m_oCurrentPage.AnalyzeCollectedData();
|
||||
m_oCurrentPage.BuildLines();
|
||||
m_oCurrentPage.DeleteTextClipPage();
|
||||
m_oCurrentPage.BuildByType();
|
||||
m_oCurrentPage.ToXml(m_oWriter);
|
||||
}
|
||||
else if (c_nPathType == lType)
|
||||
{
|
||||
m_oCurrentPage.End();
|
||||
}
|
||||
|
||||
if (c_nTextType == lType)
|
||||
m_oCurrentPage.m_dLastTextX_block = -1;
|
||||
|
||||
return S_OK;
|
||||
}
|
||||
//-------- Функции для работы с Graphics Path -----------------------------------------------
|
||||
HRESULT CDocument::PathCommandMoveTo(double fX, double fY)
|
||||
{
|
||||
if (c_nSimpleGraphicType == m_lCurrentCommandType)
|
||||
{
|
||||
m_oCurrentPage.MoveTo(fX, fY);
|
||||
}
|
||||
else
|
||||
{
|
||||
m_oSimpleGraphicsConverter.PathCommandMoveTo(fX, fY);
|
||||
}
|
||||
return S_OK;
|
||||
}
|
||||
HRESULT CDocument::PathCommandLineTo(double fX, double fY)
|
||||
{
|
||||
if (c_nSimpleGraphicType == m_lCurrentCommandType)
|
||||
{
|
||||
m_oCurrentPage.LineTo(fX, fY);
|
||||
}
|
||||
else
|
||||
{
|
||||
m_oSimpleGraphicsConverter.PathCommandLineTo(fX, fY);
|
||||
}
|
||||
return S_OK;
|
||||
}
|
||||
HRESULT CDocument::PathCommandLinesTo(double* pPoints, LONG lCount)
|
||||
{
|
||||
m_oSimpleGraphicsConverter.PathCommandLinesTo(pPoints, lCount);
|
||||
return S_OK;
|
||||
}
|
||||
HRESULT CDocument::PathCommandCurveTo(double fX1, double fY1, double fX2, double fY2, double fX3, double fY3)
|
||||
{
|
||||
if (c_nSimpleGraphicType == m_lCurrentCommandType)
|
||||
{
|
||||
m_oCurrentPage.CurveTo(fX1, fY1, fX2, fY2, fX3, fY3);
|
||||
}
|
||||
else
|
||||
{
|
||||
m_oSimpleGraphicsConverter.PathCommandCurveTo(fX1, fY1, fX2, fY2, fX3, fY3);
|
||||
}
|
||||
return S_OK;
|
||||
}
|
||||
HRESULT CDocument::PathCommandCurvesTo(double* pPoints, LONG lCount)
|
||||
{
|
||||
m_oSimpleGraphicsConverter.PathCommandCurvesTo(pPoints, lCount);
|
||||
return S_OK;
|
||||
}
|
||||
HRESULT CDocument::PathCommandArcTo(double fX, double fY, double fWidth, double fHeight, double fStartAngle, double fSweepAngle)
|
||||
{
|
||||
m_oSimpleGraphicsConverter.PathCommandArcTo(fX, fY, fWidth, fHeight, fStartAngle, fSweepAngle);
|
||||
return S_OK;
|
||||
}
|
||||
HRESULT CDocument::PathCommandClose()
|
||||
{
|
||||
if (c_nSimpleGraphicType == m_lCurrentCommandType)
|
||||
{
|
||||
m_oCurrentPage.Close();
|
||||
}
|
||||
else
|
||||
{
|
||||
m_oSimpleGraphicsConverter.PathCommandClose();
|
||||
}
|
||||
return S_OK;
|
||||
}
|
||||
HRESULT CDocument::PathCommandEnd()
|
||||
{
|
||||
if (c_nSimpleGraphicType == m_lCurrentCommandType)
|
||||
{
|
||||
m_oCurrentPage.End();
|
||||
}
|
||||
else
|
||||
{
|
||||
m_oSimpleGraphicsConverter.PathCommandEnd();
|
||||
}
|
||||
return S_OK;
|
||||
}
|
||||
HRESULT CDocument::DrawPath(long nType)
|
||||
{
|
||||
LONG lTxId = -1;
|
||||
if ((nType > 0xFF) && (c_BrushTypeTexture == m_oBrush.Type))
|
||||
{
|
||||
double x = 0;
|
||||
double y = 0;
|
||||
double w = 0;
|
||||
double h = 0;
|
||||
CImageInfo oInfo = m_oManager.WriteImage(m_oBrush.TexturePath, x, y, w, h);
|
||||
lTxId = oInfo.m_nId;
|
||||
return S_OK;
|
||||
}
|
||||
|
||||
m_oCurrentPage.DrawPath(nType, lTxId);
|
||||
return S_OK;
|
||||
}
|
||||
HRESULT CDocument::PathCommandStart()
|
||||
{
|
||||
if (c_nSimpleGraphicType == m_lCurrentCommandType)
|
||||
{
|
||||
m_oCurrentPage.Start();
|
||||
}
|
||||
else
|
||||
{
|
||||
m_oSimpleGraphicsConverter.PathCommandStart();
|
||||
}
|
||||
return S_OK;
|
||||
}
|
||||
HRESULT CDocument::PathCommandGetCurrentPoint(double* fX, double* fY)
|
||||
{
|
||||
m_oSimpleGraphicsConverter.PathCommandGetCurrentPoint(fX, fY);
|
||||
return S_OK;
|
||||
}
|
||||
|
||||
HRESULT CDocument::PathCommandTextCHAR(const int& lUnicode, const double& dX, const double& dY, const double& dW, const double& dH)
|
||||
{
|
||||
_SetFont();
|
||||
m_oSimpleGraphicsConverter.PathCommandText2(&lUnicode, nullptr, 1, m_pFontManager, dX, dY, dW, dH);
|
||||
return S_OK;
|
||||
}
|
||||
HRESULT CDocument::PathCommandTextExCHAR(const int& lUnicode, const int& lGid, const double& dX, const double& dY, const double& dW, const double& dH)
|
||||
{
|
||||
_SetFont();
|
||||
m_oSimpleGraphicsConverter.PathCommandText2(&lUnicode, &lGid, 1, m_pFontManager, dX, dY, dW, dH);
|
||||
return S_OK;
|
||||
}
|
||||
HRESULT CDocument::PathCommandText(const std::wstring& wsUnicodeText, const double& dX, const double& dY, const double& dW, const double& dH)
|
||||
{
|
||||
_SetFont();
|
||||
m_oSimpleGraphicsConverter.PathCommandText(wsUnicodeText, m_pFontManager, dX, dY, dW, dH, 0);
|
||||
return S_OK;
|
||||
}
|
||||
HRESULT CDocument::PathCommandTextEx(const std::wstring& wsUnicodeText, const unsigned int* pGids, const unsigned int nGidsCount, const double& dX, const double& dY, const double& dW, const double& dH)
|
||||
{
|
||||
_SetFont();
|
||||
m_oSimpleGraphicsConverter.PathCommandText2(wsUnicodeText, (const int*)pGids, nGidsCount, m_pFontManager, dX, dY, dW, dH);
|
||||
return S_OK;
|
||||
}
|
||||
|
||||
HRESULT CDocument::GetCommandParams(double* dAngle, double* dLeft, double* dTop, double* dWidth, double* dHeight, DWORD* lFlags)
|
||||
{
|
||||
return S_OK;
|
||||
}
|
||||
HRESULT CDocument::SetCommandParams(double dAngle, double dLeft, double dTop, double dWidth, double dHeight, DWORD lFlags)
|
||||
{
|
||||
ApplyTransform2(dAngle, dLeft, dTop, dWidth, dHeight, lFlags);
|
||||
return S_OK;
|
||||
}
|
||||
//-------- Функции для вывода изображений --------------------------------------------------
|
||||
HRESULT CDocument::DrawImage(IGrObject* pImage, double fX, double fY, double fWidth, double fHeight)
|
||||
{
|
||||
CImageInfo oInfo = m_oManager.WriteImage((Aggplus::CImage*)pImage, fX, fY, fWidth, fHeight);
|
||||
m_oCurrentPage.WriteImage(oInfo, fX, fY, fWidth, fHeight);
|
||||
return S_OK;
|
||||
}
|
||||
HRESULT CDocument::DrawImageFromFile(const std::wstring& sVal, double fX, double fY, double fWidth, double fHeight)
|
||||
{
|
||||
CImageInfo oInfo = m_oManager.WriteImage(sVal, fX, fY, fWidth, fHeight);
|
||||
m_oCurrentPage.WriteImage(oInfo, fX, fY, fWidth, fHeight);
|
||||
return S_OK;
|
||||
}
|
||||
//------------------------------------------------------------------------------------------
|
||||
HRESULT CDocument::SetTransform(double dA, double dB, double dC, double dD, double dE, double dF)
|
||||
{
|
||||
ApplyTransform(dA, dB, dC, dD, dE, dF);
|
||||
return S_OK;
|
||||
}
|
||||
HRESULT CDocument::GetTransform(double *pdA, double *pdB, double *pdC, double *pdD, double *pdE, double *pdF)
|
||||
{
|
||||
return S_OK;
|
||||
}
|
||||
HRESULT CDocument::ResetTransform(void)
|
||||
{
|
||||
m_oTransform.Reset();
|
||||
return S_OK;
|
||||
}
|
||||
HRESULT CDocument::get_ClipMode(LONG* plMode)
|
||||
{
|
||||
*plMode = m_lClipMode;
|
||||
return S_OK;
|
||||
}
|
||||
HRESULT CDocument::put_ClipMode(LONG lMode)
|
||||
{
|
||||
m_lClipMode = lMode;
|
||||
return S_OK;
|
||||
}
|
||||
|
||||
void CDocument::ApplyTransform(double d1, double d2, double d3, double d4, double d5, double d6)
|
||||
{
|
||||
m_oTransform.SetElements(d1, d2, d3, d4, d5, d6);
|
||||
}
|
||||
|
||||
void CDocument::ApplyTransform2(double dAngle, double dLeft, double dTop, double dWidth, double dHeight, DWORD lFlags)
|
||||
{
|
||||
if ((dWidth <= 1) || (dHeight <= 1))
|
||||
lFlags = 0;
|
||||
|
||||
bool bFlipX = (0 != (c_nParamFlipX & lFlags));
|
||||
bool bFlipY = (0 != (c_nParamFlipY & lFlags));
|
||||
|
||||
double m11 = bFlipX ? -1.0 : 1.0;
|
||||
double m22 = bFlipY ? -1.0 : 1.0;
|
||||
|
||||
Aggplus::CMatrix oMatrix(1, 0, 0, 1, 0, 0);
|
||||
|
||||
if ((0 != dAngle) || (0 != lFlags))
|
||||
{
|
||||
double dCentreX = (dLeft + dWidth / 2.0);
|
||||
double dCentreY = (dTop + dHeight / 2.0);
|
||||
|
||||
oMatrix.Translate(-dCentreX, -dCentreY , Aggplus::MatrixOrderAppend);
|
||||
|
||||
oMatrix.Rotate(dAngle , Aggplus::MatrixOrderAppend);
|
||||
oMatrix.Scale(m11, m22 , Aggplus::MatrixOrderAppend);
|
||||
|
||||
oMatrix.Translate(dCentreX, dCentreY , Aggplus::MatrixOrderAppend);
|
||||
}
|
||||
|
||||
m_oTransform = oMatrix;
|
||||
}
|
||||
|
||||
void CDocument::_SetFont()
|
||||
{
|
||||
if (nullptr == m_pFontManager)
|
||||
{
|
||||
m_pFontManager = NSFontManager::CreateFontManager(m_pAppFonts);
|
||||
}
|
||||
|
||||
double dPix = m_oFont.CharSpace * m_dDpiX / 25.4;
|
||||
|
||||
if (m_oInstalledFont.IsEqual(&m_oFont))
|
||||
{
|
||||
if (1 < m_dWidth)
|
||||
{
|
||||
m_pFontManager->SetCharSpacing(dPix);
|
||||
}
|
||||
return;
|
||||
}
|
||||
|
||||
m_pFontManager->SetStringGID(m_oFont.StringGID);
|
||||
if (1 < m_dWidth)
|
||||
{
|
||||
m_pFontManager->SetCharSpacing(dPix);
|
||||
}
|
||||
|
||||
if (m_oFont.Path.empty())
|
||||
{
|
||||
m_pFontManager->LoadFontByName(m_oFont.Name, (float)m_oFont.Size, m_oFont.GetStyle(), m_dDpiX, m_dDpiY);
|
||||
}
|
||||
else
|
||||
{
|
||||
m_pFontManager->LoadFontFromFile(m_oFont.Path, m_oFont.FaceIndex, (float)m_oFont.Size, m_dDpiX, m_dDpiY);
|
||||
}
|
||||
|
||||
m_oInstalledFont = m_oFont;
|
||||
}
|
||||
|
||||
bool CDocument::CreateDocument()
|
||||
{
|
||||
CreateTemplate(m_strTempDirectory);
|
||||
|
||||
// Init
|
||||
Clear();
|
||||
|
||||
m_lCurrentCommandType = 0;
|
||||
m_oCurrentPage.Init(&m_oFont, &m_oPen, &m_oBrush, &m_oShadow, &m_oEdge, &m_oTransform, &m_oSimpleGraphicsConverter);
|
||||
|
||||
m_oManager.NewDocument();
|
||||
// media
|
||||
m_oManager.m_strDstMedia = m_strTempDirectory + L"/word/media";
|
||||
NSDirectory::CreateDirectory(m_oManager.m_strDstMedia);
|
||||
|
||||
m_oCurrentPage.m_oManager.m_oFontTable.m_mapTable.clear();
|
||||
|
||||
m_oDocumentStream.CloseFile();
|
||||
m_oDocumentStream.CreateFileW(m_strTempDirectory + L"/word/document.xml");
|
||||
m_oDocumentStream.WriteStringUTF8(L"<?xml version=\"1.0\" encoding=\"UTF-8\" standalone=\"yes\"?>\
|
||||
<w:document xmlns:wpc=\"http://schemas.microsoft.com/office/word/2010/wordprocessingCanvas\" \
|
||||
xmlns:cx=\"http://schemas.microsoft.com/office/drawing/2014/chartex\" \
|
||||
xmlns:cx1=\"http://schemas.microsoft.com/office/drawing/2015/9/8/chartex\" \
|
||||
xmlns:cx2=\"http://schemas.microsoft.com/office/drawing/2015/10/21/chartex\" \
|
||||
xmlns:cx3=\"http://schemas.microsoft.com/office/drawing/2016/5/9/chartex\" \
|
||||
xmlns:cx4=\"http://schemas.microsoft.com/office/drawing/2016/5/10/chartex\" \
|
||||
xmlns:cx5=\"http://schemas.microsoft.com/office/drawing/2016/5/11/chartex\" \
|
||||
xmlns:cx6=\"http://schemas.microsoft.com/office/drawing/2016/5/12/chartex\" \
|
||||
xmlns:cx7=\"http://schemas.microsoft.com/office/drawing/2016/5/13/chartex\" \
|
||||
xmlns:cx8=\"http://schemas.microsoft.com/office/drawing/2016/5/14/chartex\" \
|
||||
xmlns:mc=\"http://schemas.openxmlformats.org/markup-compatibility/2006\" \
|
||||
xmlns:aink=\"http://schemas.microsoft.com/office/drawing/2016/ink\" \
|
||||
xmlns:am3d=\"http://schemas.microsoft.com/office/drawing/2017/model3d\" \
|
||||
xmlns:o=\"urn:schemas-microsoft-com:office:office\" \
|
||||
xmlns:r=\"http://schemas.openxmlformats.org/officeDocument/2006/relationships\" \
|
||||
xmlns:m=\"http://schemas.openxmlformats.org/officeDocument/2006/math\" \
|
||||
xmlns:v=\"urn:schemas-microsoft-com:vml\" \
|
||||
xmlns:a=\"http://schemas.openxmlformats.org/drawingml/2006/main\" \
|
||||
xmlns:pic=\"http://schemas.openxmlformats.org/drawingml/2006/picture\" \
|
||||
xmlns:wp14=\"http://schemas.microsoft.com/office/word/2010/wordprocessingDrawing\" \
|
||||
xmlns:wp=\"http://schemas.openxmlformats.org/drawingml/2006/wordprocessingDrawing\" \
|
||||
xmlns:w10=\"urn:schemas-microsoft-com:office:word\" \
|
||||
xmlns:w=\"http://schemas.openxmlformats.org/wordprocessingml/2006/main\" \
|
||||
xmlns:w14=\"http://schemas.microsoft.com/office/word/2010/wordml\" \
|
||||
xmlns:w15=\"http://schemas.microsoft.com/office/word/2012/wordml\" \
|
||||
xmlns:w16cex=\"http://schemas.microsoft.com/office/word/2018/wordml/cex\" \
|
||||
xmlns:w16cid=\"http://schemas.microsoft.com/office/word/2016/wordml/cid\" \
|
||||
xmlns:w16=\"http://schemas.microsoft.com/office/word/2018/wordml\" \
|
||||
xmlns:w16sdtdh=\"http://schemas.microsoft.com/office/word/2020/wordml/sdtdatahash\" \
|
||||
xmlns:w16se=\"http://schemas.microsoft.com/office/word/2015/wordml/symex\" \
|
||||
xmlns:wpg=\"http://schemas.microsoft.com/office/word/2010/wordprocessingGroup\" \
|
||||
xmlns:wpi=\"http://schemas.microsoft.com/office/word/2010/wordprocessingInk\" \
|
||||
xmlns:wne=\"http://schemas.microsoft.com/office/word/2006/wordml\" \
|
||||
xmlns:wps=\"http://schemas.microsoft.com/office/word/2010/wordprocessingShape\" \
|
||||
mc:Ignorable=\"w14 w15 w16se w16cid w16 w16cex w16sdtdh wp14\">\
|
||||
<w:body>");
|
||||
m_lPagesCount = 0;
|
||||
m_oWriter.Clear();
|
||||
m_oWriter.AddSize(10000);
|
||||
|
||||
return true;
|
||||
}
|
||||
|
||||
void CDocument::Close()
|
||||
{
|
||||
// сохраним rels (images & docs)
|
||||
NSStringUtils::CStringBuilder oWriter;
|
||||
|
||||
oWriter.WriteString(L"<?xml version=\"1.0\" encoding=\"UTF-8\" standalone=\"yes\"?>\
|
||||
<Relationships xmlns=\"http://schemas.openxmlformats.org/package/2006/relationships\">\
|
||||
<Relationship Id=\"rId1\" Type=\"http://schemas.openxmlformats.org/officeDocument/2006/relationships/styles\" Target=\"styles.xml\"/>\
|
||||
<Relationship Id=\"rId2\" Type=\"http://schemas.openxmlformats.org/officeDocument/2006/relationships/settings\" Target=\"settings.xml\"/>\
|
||||
<Relationship Id=\"rId3\" Type=\"http://schemas.openxmlformats.org/officeDocument/2006/relationships/webSettings\" Target=\"webSettings.xml\"/>\
|
||||
<Relationship Id=\"rId4\" Type=\"http://schemas.openxmlformats.org/officeDocument/2006/relationships/fontTable\" Target=\"fontTable.xml\"/>\
|
||||
<Relationship Id=\"rId5\" Type=\"http://schemas.openxmlformats.org/officeDocument/2006/relationships/theme\" Target=\"theme/theme.xml\"/>");
|
||||
|
||||
for (std::map<DWORD, CImageInfo>::iterator iterImage = m_oManager.m_mapImageData.begin(); iterImage != m_oManager.m_mapImageData.end(); iterImage++)
|
||||
{
|
||||
CImageInfo& oInfo = iterImage->second;
|
||||
|
||||
oWriter.WriteString(L"<Relationship Id=\"rId");
|
||||
oWriter.AddInt(10 + oInfo.m_nId);
|
||||
oWriter.WriteString(L"\" Type=\"http://schemas.openxmlformats.org/officeDocument/2006/relationships/image\" Target=\"media/image");
|
||||
oWriter.AddInt(oInfo.m_nId);
|
||||
(oInfo.m_eType == CImageInfo::itPNG) ? oWriter.WriteString(L".png\"/>") : oWriter.WriteString(L".jpg\"/>");
|
||||
}
|
||||
|
||||
for (std::map<std::wstring, CImageInfo>::iterator iterImage = m_oManager.m_mapImagesFile.begin(); iterImage != m_oManager.m_mapImagesFile.end(); iterImage++)
|
||||
{
|
||||
CImageInfo& oInfo = iterImage->second;
|
||||
|
||||
oWriter.WriteString(L"<Relationship Id=\"rId");
|
||||
oWriter.AddInt(10 + oInfo.m_nId);
|
||||
oWriter.WriteString(L"\" Type=\"http://schemas.openxmlformats.org/officeDocument/2006/relationships/image\" Target=\"media/image");
|
||||
oWriter.AddInt(oInfo.m_nId);
|
||||
(oInfo.m_eType == CImageInfo::itPNG) ? oWriter.WriteString(L".png\"/>") : oWriter.WriteString(L".jpg\"/>");
|
||||
}
|
||||
|
||||
oWriter.WriteString(L"</Relationships>");
|
||||
|
||||
NSFile::CFileBinary::SaveToFile(m_strTempDirectory + L"/word/_rels/document.xml.rels", oWriter.GetData());
|
||||
oWriter.ClearNoAttack();
|
||||
|
||||
// сохраним fontTable
|
||||
oWriter.WriteString(L"<?xml version=\"1.0\" encoding=\"UTF-8\" standalone=\"yes\"?>\
|
||||
<w:fonts xmlns:w=\"http://schemas.openxmlformats.org/wordprocessingml/2006/main\">");
|
||||
|
||||
CFontTable* pFontTable = &m_oCurrentPage.m_oManager.m_oFontTable;
|
||||
for (std::map<std::wstring, CFontTableEntry>::iterator iterFont = pFontTable->m_mapTable.begin(); iterFont != pFontTable->m_mapTable.end(); iterFont++)
|
||||
{
|
||||
CFontTableEntry& oEntry = iterFont->second;
|
||||
|
||||
oWriter.WriteString(L"<w:font w:name=\"");
|
||||
oWriter.WriteEncodeXmlString(oEntry.m_strFamilyName);
|
||||
oWriter.WriteString(L"\">");
|
||||
|
||||
oWriter.WriteString(L"<w:panose1 w:val=\"");
|
||||
oWriter.WriteString(oEntry.m_strPANOSE);
|
||||
oWriter.WriteString(L"\"/>");
|
||||
|
||||
if (oEntry.m_bIsFixedWidth)
|
||||
oWriter.WriteString(L"<w:pitch w:val=\"fixed\" />");
|
||||
else
|
||||
oWriter.WriteString(L"<w:pitch w:val=\"variable\" />");
|
||||
|
||||
oWriter.WriteString(L"<w:charset w:val=\"00\"/>");
|
||||
|
||||
oWriter.WriteString(L"<w:sig w:usb0=\"");
|
||||
oWriter.WriteHexInt4(oEntry.m_arSignature[0]);
|
||||
oWriter.WriteString(L"\" w:usb1=\"");
|
||||
oWriter.WriteHexInt4(oEntry.m_arSignature[1]);
|
||||
oWriter.WriteString(L"\" w:usb2=\"");
|
||||
oWriter.WriteHexInt4(oEntry.m_arSignature[2]);
|
||||
oWriter.WriteString(L"\" w:usb3=\"");
|
||||
oWriter.WriteHexInt4(oEntry.m_arSignature[3]);
|
||||
oWriter.WriteString(L"\" w:csb0=\"");
|
||||
oWriter.WriteHexInt4(oEntry.m_arSignature[4]);
|
||||
oWriter.WriteString(L"\" w:csb1=\"");
|
||||
oWriter.WriteHexInt4(oEntry.m_arSignature[5]);
|
||||
oWriter.WriteString(L"\"/>");
|
||||
|
||||
oWriter.WriteString(L"</w:font>");
|
||||
}
|
||||
|
||||
oWriter.WriteString(L"</w:fonts>");
|
||||
NSFile::CFileBinary::SaveToFile(m_strTempDirectory + L"/word/fontTable.xml", oWriter.GetData());
|
||||
|
||||
// document
|
||||
m_oCurrentPage.WriteSectionToFile(true, m_oWriter);
|
||||
m_oWriter.WriteString(L"</w:body></w:document>");
|
||||
m_oDocumentStream.WriteStringUTF8(m_oWriter.GetData());
|
||||
m_oWriter.ClearNoAttack();
|
||||
|
||||
m_oDocumentStream.CloseFile();
|
||||
}
|
||||
}
|
||||
File diff suppressed because it is too large
Load Diff
320
DocxRenderer/src/logic/ElementContText.cpp
Normal file
320
DocxRenderer/src/logic/ElementContText.cpp
Normal file
@ -0,0 +1,320 @@
|
||||
#include "ElementContText.h"
|
||||
#include "../resources/ColorTable.h"
|
||||
#include "../resources/SingletonTemplate.h"
|
||||
#include "../resources/utils.h"
|
||||
|
||||
namespace NSDocxRenderer
|
||||
{
|
||||
CContText::CContText(CFontManagerLight& oManagerLight): CBaseItem(ElemType::etContText),
|
||||
m_pManagerLight(&oManagerLight)
|
||||
{
|
||||
}
|
||||
|
||||
void CContText::Clear()
|
||||
{
|
||||
}
|
||||
|
||||
CContText::CContText(const CContText& oSrc): CBaseItem(ElemType::etContText)
|
||||
{
|
||||
*this = oSrc;
|
||||
}
|
||||
|
||||
CContText& CContText::operator=(const CContText& oSrc)
|
||||
{
|
||||
if (this == &oSrc)
|
||||
{
|
||||
return *this;
|
||||
}
|
||||
|
||||
CBaseItem::operator=(oSrc);
|
||||
|
||||
m_oFont = oSrc.m_oFont;
|
||||
m_oBrush = oSrc.m_oBrush;
|
||||
|
||||
m_strPickFontName = oSrc.m_strPickFontName;
|
||||
m_lPickFontStyle = oSrc.m_lPickFontStyle;
|
||||
|
||||
m_oText = oSrc.m_oText;
|
||||
|
||||
m_dBaselinePos = oSrc.m_dBaselinePos;
|
||||
m_dBaselineOffset = oSrc.m_dBaselineOffset;
|
||||
m_dLastX = oSrc.m_dLastX;
|
||||
m_dSpaceWidthMM = oSrc.m_dSpaceWidthMM;
|
||||
|
||||
m_bIsNeedSpace = oSrc.m_bIsNeedSpace;
|
||||
m_bIsDoubleStrikeout = oSrc.m_bIsDoubleStrikeout;
|
||||
m_bIsHighlightPresent = oSrc.m_bIsHighlightPresent;
|
||||
m_lHighlightColor = oSrc.m_lHighlightColor;
|
||||
|
||||
m_eUnderlineType = oSrc.m_eUnderlineType;
|
||||
m_lUnderlineColor = oSrc.m_lUnderlineColor;
|
||||
|
||||
m_pShape = oSrc.m_pShape;
|
||||
m_pManagerLight = oSrc.m_pManagerLight;
|
||||
|
||||
return *this;
|
||||
}
|
||||
|
||||
double CContText::GetIntersect(const CContText* oSrc) const
|
||||
{
|
||||
double d1 = std::max(m_dLeft, oSrc->m_dLeft);
|
||||
double d2 = std::min(m_dLeft + m_dWidth, oSrc->m_dLeft + oSrc->m_dWidth);
|
||||
|
||||
if (d2 > d1)
|
||||
return d2 - d1;
|
||||
return 0;
|
||||
}
|
||||
|
||||
void CContText::ToXml(NSStringUtils::CStringBuilder& oWriter)
|
||||
{
|
||||
oWriter.WriteString(L"<w:r>");
|
||||
oWriter.WriteString(L"<w:rPr>");
|
||||
|
||||
if (m_strPickFontName.empty())
|
||||
{
|
||||
if (m_oFont.Bold)
|
||||
oWriter.WriteString(L"<w:b w:val=\"true\"/>");
|
||||
if (m_oFont.Italic)
|
||||
oWriter.WriteString(L"<w:i w:val=\"true\"/>");
|
||||
|
||||
if (m_bIsNeedSpace)
|
||||
{
|
||||
m_dWidth += m_dSpaceWidthMM;
|
||||
m_oText += L" ";
|
||||
}
|
||||
}
|
||||
else
|
||||
{
|
||||
if (0x01 == (0x01 & m_lPickFontStyle))
|
||||
oWriter.WriteString(L"<w:b w:val=\"true\"/>");
|
||||
if (0x02 == (0x02 & m_lPickFontStyle))
|
||||
oWriter.WriteString(L"<w:i w:val=\"true\"/>");
|
||||
|
||||
if (m_bIsNeedSpace)
|
||||
{
|
||||
m_dWidth += m_pManagerLight->GetSpaceWidth();
|
||||
m_oText += L" ";
|
||||
}
|
||||
|
||||
// нужно перемерять...
|
||||
double ___dSize = (double)(static_cast<LONG>(m_oFont.Size * 2)) / 2;
|
||||
m_pManagerLight->LoadFont(m_strPickFontName, m_lPickFontStyle, ___dSize, false);
|
||||
double dWidth = m_pManagerLight->MeasureStringWidth(m_oText.ToStdWString());
|
||||
|
||||
double dSpacing = (m_dWidth - dWidth) / (m_oText.length() + 1);
|
||||
dSpacing *= c_dMMToDx;
|
||||
|
||||
LONG lSpacing = static_cast<LONG>(dSpacing);
|
||||
//note принудительно уменьшаем spacing чтобы текстовые линии не выходили за правую границу
|
||||
lSpacing -= 1;
|
||||
|
||||
if (lSpacing != 0)
|
||||
{
|
||||
oWriter.WriteString(L"<w:spacing w:val=\"");
|
||||
oWriter.AddInt(lSpacing);
|
||||
oWriter.WriteString(L"\"/>");
|
||||
}
|
||||
}
|
||||
|
||||
int lSize = static_cast<int>(2 * m_oFont.Size);
|
||||
oWriter.WriteString(L"<w:sz w:val=\"");
|
||||
oWriter.AddInt(lSize);
|
||||
oWriter.WriteString(L"\"/><w:szCs w:val=\"");
|
||||
oWriter.AddInt(lSize);
|
||||
oWriter.WriteString(L"\"/>");
|
||||
|
||||
std::wstring& strFontName = m_strPickFontName.empty() ? m_oFont.Name : m_strPickFontName;
|
||||
oWriter.WriteString(L"<w:rFonts w:ascii=\"");
|
||||
oWriter.WriteEncodeXmlString(strFontName);
|
||||
oWriter.WriteString(L"\" w:hAnsi=\"");
|
||||
oWriter.WriteEncodeXmlString(strFontName);
|
||||
oWriter.WriteString(L"\" w:cs=\"");
|
||||
oWriter.WriteEncodeXmlString(strFontName);
|
||||
oWriter.WriteString(L"\"/>");
|
||||
|
||||
if (ConvertColorBGRToRGB(m_oBrush.Color1) != c_iBlackColor)
|
||||
{
|
||||
oWriter.WriteString(L"<w:color w:val=\"");
|
||||
oWriter.WriteHexInt3(ConvertColorBGRToRGB(m_oBrush.Color1));
|
||||
oWriter.WriteString(L"\"/>");
|
||||
}
|
||||
|
||||
if (m_oFont.Strikeout == TRUE)
|
||||
{
|
||||
if (m_bIsDoubleStrikeout)
|
||||
{
|
||||
oWriter.WriteString(L"<w:dstrike/>");
|
||||
}
|
||||
else
|
||||
{
|
||||
oWriter.WriteString(L"<w:strike/>");
|
||||
}
|
||||
}
|
||||
|
||||
if (m_oFont.Underline == TRUE)
|
||||
{
|
||||
oWriter.WriteString(L"<w:u w:val=");
|
||||
oWriter.WriteString(SingletonInstance<LinesTable>().ConverLineToString(m_eUnderlineType));
|
||||
|
||||
if (m_lUnderlineColor != m_oBrush.Color1)
|
||||
{
|
||||
oWriter.WriteString(L" w:color=\"");
|
||||
oWriter.WriteHexInt3(ConvertColorBGRToRGB(m_lUnderlineColor));
|
||||
oWriter.WriteString(L"\"");
|
||||
}
|
||||
oWriter.WriteString(L"/>");
|
||||
}
|
||||
|
||||
if (m_bIsHighlightPresent)
|
||||
{
|
||||
ColorTable& colorTable = SingletonInstance<ColorTable>();
|
||||
if (colorTable.IsStandardColor(m_lHighlightColor))
|
||||
{
|
||||
oWriter.WriteString(L"<w:highlight w:val=\"");
|
||||
oWriter.WriteString(colorTable.ConverColorToString(ConvertColorBGRToRGB(m_lHighlightColor)));
|
||||
}
|
||||
else
|
||||
{
|
||||
oWriter.WriteString(L"<w:shd w:val=\"clear\" w:color=\"auto\" w:fill=\"");
|
||||
oWriter.WriteHexInt3(ConvertColorBGRToRGB(m_lHighlightColor));
|
||||
}
|
||||
oWriter.WriteString(L"\"/>");
|
||||
}
|
||||
|
||||
oWriter.WriteString(L"</w:rPr>");
|
||||
|
||||
oWriter.WriteString(L"<w:t xml:space=\"preserve\">");
|
||||
oWriter.WriteEncodeXmlString(m_oText.ToStdWString());
|
||||
oWriter.WriteString(L"</w:t>");
|
||||
|
||||
oWriter.WriteString(L"</w:r>");
|
||||
}
|
||||
|
||||
void CContText::AddWideSpaceToXml(double dSpacingMM,
|
||||
NSStringUtils::CStringBuilder& oWriter,
|
||||
bool bIsNeedSaveFormat)
|
||||
{
|
||||
oWriter.WriteString(L"<w:r><w:rPr>");
|
||||
|
||||
double dSpaceMMSize = m_dSpaceWidthMM;
|
||||
if (m_strPickFontName.empty())
|
||||
{
|
||||
if (m_oFont.Bold && bIsNeedSaveFormat)
|
||||
oWriter.WriteString(L"<w:b w:val=\"true\"/>");
|
||||
if (m_oFont.Italic && bIsNeedSaveFormat)
|
||||
oWriter.WriteString(L"<w:i w:val=\"true\"/>");
|
||||
}
|
||||
else
|
||||
{
|
||||
if (0x01 == (0x01 & m_lPickFontStyle) && bIsNeedSaveFormat)
|
||||
oWriter.WriteString(L"<w:b w:val=\"true\"/>");
|
||||
if (0x02 == (0x02 & m_lPickFontStyle) && bIsNeedSaveFormat)
|
||||
oWriter.WriteString(L"<w:i w:val=\"true\"/>");
|
||||
|
||||
dSpaceMMSize = m_pManagerLight->GetSpaceWidth();
|
||||
}
|
||||
|
||||
int lSize = (int)(2 * m_oFont.Size);
|
||||
oWriter.WriteString(L"<w:sz w:val=\"");
|
||||
oWriter.AddInt(lSize);
|
||||
oWriter.WriteString(L"\"/><w:szCs w:val=\"");
|
||||
oWriter.AddInt(lSize);
|
||||
oWriter.WriteString(L"\"/>");
|
||||
|
||||
std::wstring& strFontName = m_strPickFontName.empty() ? m_oFont.Name : m_strPickFontName;
|
||||
oWriter.WriteString(L"<w:rFonts w:ascii=\"");
|
||||
oWriter.WriteEncodeXmlString(strFontName);
|
||||
oWriter.WriteString(L"\" w:hAnsi=\"");
|
||||
oWriter.WriteEncodeXmlString(strFontName);
|
||||
oWriter.WriteString(L"\" w:cs=\"");
|
||||
oWriter.WriteEncodeXmlString(strFontName);
|
||||
oWriter.WriteString(L"\"/>");
|
||||
|
||||
oWriter.WriteString(L"<w:color w:val=\"");
|
||||
oWriter.WriteHexInt3(ConvertColorBGRToRGB(m_oBrush.Color1));
|
||||
oWriter.WriteString(L"\"/>");
|
||||
|
||||
LONG lSpacing = static_cast<LONG>((dSpacingMM - dSpaceMMSize) * c_dMMToDx);
|
||||
//note принудительно уменьшаем spacing чтобы текстовые линии не выходили за правую границу
|
||||
lSpacing -= 1;
|
||||
if (lSpacing != 0)
|
||||
{
|
||||
oWriter.WriteString(L"<w:spacing w:val=\"");
|
||||
oWriter.AddInt(lSpacing);
|
||||
oWriter.WriteString(L"\"/>");
|
||||
}
|
||||
|
||||
if (ConvertColorBGRToRGB(m_oBrush.Color1) != c_iBlackColor)
|
||||
{
|
||||
oWriter.WriteString(L"<w:color w:val=\"");
|
||||
oWriter.WriteHexInt3(ConvertColorBGRToRGB(m_oBrush.Color1));
|
||||
oWriter.WriteString(L"\"/>");
|
||||
}
|
||||
|
||||
if (m_oFont.Strikeout == TRUE && bIsNeedSaveFormat)
|
||||
{
|
||||
oWriter.WriteString(L"<w:strike/>");
|
||||
}
|
||||
|
||||
if (m_oFont.Underline == TRUE && bIsNeedSaveFormat)
|
||||
{
|
||||
oWriter.WriteString(L"<w:u w:val=");
|
||||
oWriter.WriteString(SingletonInstance<LinesTable>().ConverLineToString(m_eUnderlineType));
|
||||
|
||||
if (m_lUnderlineColor != m_oBrush.Color1)
|
||||
{
|
||||
oWriter.WriteString(L" w:color=\"");
|
||||
oWriter.WriteHexInt3(ConvertColorBGRToRGB(m_lUnderlineColor));
|
||||
oWriter.WriteString(L"\"");
|
||||
}
|
||||
oWriter.WriteString(L"/>");
|
||||
}
|
||||
|
||||
if (m_bIsHighlightPresent && bIsNeedSaveFormat)
|
||||
{
|
||||
ColorTable& colorTable = SingletonInstance<ColorTable>();
|
||||
if (colorTable.IsStandardColor(m_lHighlightColor))
|
||||
{
|
||||
oWriter.WriteString(L"<w:highlight w:val=\"");
|
||||
oWriter.WriteString(colorTable.ConverColorToString(ConvertColorBGRToRGB(m_lHighlightColor)));
|
||||
}
|
||||
else
|
||||
{
|
||||
oWriter.WriteString(L"<w:shd w:val=\"clear\" w:color=\"auto\" w:fill=\"");
|
||||
oWriter.WriteHexInt3(ConvertColorBGRToRGB(m_lHighlightColor));
|
||||
}
|
||||
oWriter.WriteString(L"\"/>");
|
||||
}
|
||||
|
||||
oWriter.WriteString(L"</w:rPr>");
|
||||
|
||||
oWriter.WriteString(L"<w:t xml:space=\"preserve\">");
|
||||
oWriter.WriteString(L" ");
|
||||
oWriter.WriteString(L"</w:t>");
|
||||
|
||||
oWriter.WriteString(L"</w:r>");
|
||||
}
|
||||
|
||||
void CContText::AddSpaceToEnd()
|
||||
{
|
||||
m_bIsNeedSpace = true;
|
||||
m_dWidth += m_dSpaceWidthMM;
|
||||
}
|
||||
|
||||
bool CContText::IsEqual(const CContText* oSrc)
|
||||
{
|
||||
if( m_strPickFontName == oSrc->m_strPickFontName &&
|
||||
m_eUnderlineType == oSrc->m_eUnderlineType &&
|
||||
m_lUnderlineColor == oSrc->m_lUnderlineColor &&
|
||||
m_bIsHighlightPresent == oSrc->m_bIsHighlightPresent &&
|
||||
m_lHighlightColor == oSrc->m_lHighlightColor &&
|
||||
m_bIsDoubleStrikeout == oSrc->m_bIsDoubleStrikeout &&
|
||||
m_pShape == oSrc->m_pShape &&
|
||||
m_oFont.IsEqual(&oSrc->m_oFont) &&
|
||||
m_oBrush.IsEqual(&oSrc->m_oBrush))
|
||||
{
|
||||
return true;
|
||||
}
|
||||
return false;
|
||||
}
|
||||
}
|
||||
62
DocxRenderer/src/logic/ElementContText.h
Normal file
62
DocxRenderer/src/logic/ElementContText.h
Normal file
@ -0,0 +1,62 @@
|
||||
#pragma once
|
||||
#include "BaseItem.h"
|
||||
#include "../DesktopEditor/common/StringBuilder.h"
|
||||
#include "FontManager.h"
|
||||
#include "../resources/Constants.h"
|
||||
#include "../resources/LinesTable.h"
|
||||
|
||||
|
||||
namespace NSDocxRenderer
|
||||
{
|
||||
class CShape;
|
||||
|
||||
class CContText : public CBaseItem
|
||||
{
|
||||
public:
|
||||
NSStructures::CFont m_oFont;
|
||||
NSStructures::CBrush m_oBrush;
|
||||
|
||||
std::wstring m_strPickFontName {L""};
|
||||
LONG m_lPickFontStyle {0};
|
||||
|
||||
NSStringUtils::CStringUTF32 m_oText;
|
||||
|
||||
double m_dBaselinePos {0};
|
||||
double m_dBaselineOffset {0};
|
||||
double m_dLastX {0};
|
||||
|
||||
double m_dSpaceWidthMM {0};
|
||||
|
||||
bool m_bIsNeedSpace {false};
|
||||
bool m_bIsDoubleStrikeout {false};
|
||||
bool m_bIsHighlightPresent {false};
|
||||
LONG m_lHighlightColor {c_iBlackColor};
|
||||
|
||||
eLineType m_eUnderlineType {eLineType::ltUnknown};
|
||||
LONG m_lUnderlineColor {c_iBlackColor};
|
||||
|
||||
const CShape* m_pShape {nullptr}; //Если не nullptr, то есть фоновая графика - можно анализировать.
|
||||
CFontManagerLight* m_pManagerLight {nullptr};
|
||||
|
||||
public:
|
||||
CContText(CFontManagerLight& oManagerLight);
|
||||
~CContText(){}
|
||||
|
||||
void Clear() override final;
|
||||
|
||||
CContText(const CContText& oSrc);
|
||||
|
||||
CContText& operator=(const CContText& oSrc);
|
||||
|
||||
double GetIntersect(const CContText* oSrc) const;
|
||||
|
||||
void ToXml(NSStringUtils::CStringBuilder& oWriter) override final;
|
||||
|
||||
void AddWideSpaceToXml(double dSpacingMM,
|
||||
NSStringUtils::CStringBuilder& oWriter,
|
||||
bool bIsNeedSaveFormat = false);
|
||||
|
||||
void AddSpaceToEnd();
|
||||
bool IsEqual(const CContText* oSrc);
|
||||
};
|
||||
}
|
||||
66
DocxRenderer/src/logic/ElementImage.cpp
Normal file
66
DocxRenderer/src/logic/ElementImage.cpp
Normal file
@ -0,0 +1,66 @@
|
||||
#include "ElementImage.h"
|
||||
|
||||
namespace NSDocxRenderer
|
||||
{
|
||||
CImage::CImage() : CBaseItem(ElemType::etImage)
|
||||
{
|
||||
}
|
||||
CImage::CImage(const CImage& oSrc) : CBaseItem(ElemType::etImage)
|
||||
{
|
||||
*this = oSrc;
|
||||
}
|
||||
CImage::CImage(const CImageInfo& oInfo, const std::wstring& strDstMedia) : CBaseItem(ElemType::etImage),
|
||||
m_strPath(strDstMedia), m_lID(oInfo.m_nId)
|
||||
{
|
||||
}
|
||||
void CImage::Clear(){}
|
||||
|
||||
CImage& CImage::operator=(const CImage& oSrc)
|
||||
{
|
||||
if (this == &oSrc)
|
||||
{
|
||||
return *this;
|
||||
}
|
||||
|
||||
Clear();
|
||||
|
||||
CBaseItem::operator=(oSrc);
|
||||
|
||||
m_strPath = oSrc.m_strPath;
|
||||
m_lID = oSrc.m_lID;
|
||||
|
||||
m_dRotate = oSrc.m_dRotate;
|
||||
|
||||
return *this;
|
||||
}
|
||||
|
||||
void CImage::ToXml(NSStringUtils::CStringBuilder& oWriter)
|
||||
{
|
||||
oWriter.WriteString(L"<w:r><w:pict><v:shape id=\"\" type=\"\" style=\"position:absolute;");
|
||||
|
||||
oWriter.WriteString(L"margin-left:");
|
||||
oWriter.AddDouble(m_dLeft, 2);
|
||||
oWriter.WriteString(L"mm;margin-top:");
|
||||
oWriter.AddDouble(m_dTop, 2);
|
||||
oWriter.WriteString(L"mm;width:");
|
||||
oWriter.AddDouble(m_dWidth, 2);
|
||||
oWriter.WriteString(L"mm;height:");
|
||||
oWriter.AddDouble(m_dHeight, 2);
|
||||
oWriter.WriteString(L"mm;");
|
||||
|
||||
if (fabs(m_dRotate) > 0.01)
|
||||
{
|
||||
oWriter.WriteString(L"rotation:");
|
||||
oWriter.AddInt((int)m_dRotate);
|
||||
oWriter.AddCharSafe(';');
|
||||
}
|
||||
|
||||
oWriter.WriteString(L"z-index:-1;mso-position-horizontal-relative:page;mso-position-vertical-relative:page\" filled=\"f\">");
|
||||
|
||||
oWriter.WriteString(L"<v:imagedata r:id=\"rId");
|
||||
oWriter.AddInt(10 + m_lID);
|
||||
oWriter.WriteString(L"\" o:title=\"\"/>");
|
||||
|
||||
oWriter.WriteString(L"</v:shape></w:pict></w:r>");
|
||||
}
|
||||
}
|
||||
@ -1,86 +1,23 @@
|
||||
#ifndef DOCX_RENDERER_ELEMENT_IMAGE_H
|
||||
#define DOCX_RENDERER_ELEMENT_IMAGE_H
|
||||
|
||||
#include "Common.h"
|
||||
#pragma once
|
||||
#include "BaseItem.h"
|
||||
#include "ImageManager.h"
|
||||
|
||||
namespace NSDocxRenderer
|
||||
{
|
||||
class CImage : public CBaseItem
|
||||
{
|
||||
public:
|
||||
std::wstring m_strPath;
|
||||
int m_lID;
|
||||
|
||||
double m_dLeft;
|
||||
double m_dTop;
|
||||
double m_dWidth;
|
||||
double m_dHeight;
|
||||
|
||||
double m_dRotate;
|
||||
std::wstring m_strPath {L""};
|
||||
int m_lID {-1};
|
||||
double m_dRotate {0.0};
|
||||
|
||||
public:
|
||||
CImage()
|
||||
{
|
||||
m_eType = etImage;
|
||||
m_strPath = L"";
|
||||
m_lID = -1;
|
||||
}
|
||||
CImage(const CImage& oSrc)
|
||||
{
|
||||
*this = oSrc;
|
||||
}
|
||||
CImage(const CImageInfo& oInfo, const std::wstring& strDstMedia)
|
||||
{
|
||||
m_eType = etImage;
|
||||
m_strPath = strDstMedia;
|
||||
m_lID = oInfo.m_nId;
|
||||
}
|
||||
CImage& operator=(const CImage& oSrc)
|
||||
{
|
||||
m_eType = etImage;
|
||||
m_strPath = oSrc.m_strPath;
|
||||
m_lID = oSrc.m_lID;
|
||||
CImage();
|
||||
CImage(const CImage& oSrc);
|
||||
CImage(const CImageInfo& oInfo, const std::wstring& strDstMedia);
|
||||
void Clear() override final;
|
||||
|
||||
m_dLeft = oSrc.m_dLeft;
|
||||
m_dTop = oSrc.m_dTop;
|
||||
m_dWidth = oSrc.m_dWidth;
|
||||
m_dHeight = oSrc.m_dHeight;
|
||||
|
||||
m_dRotate = oSrc.m_dRotate;
|
||||
|
||||
return *this;
|
||||
}
|
||||
|
||||
virtual void ToXml(NSStringUtils::CStringBuilder& oWriter)
|
||||
{
|
||||
oWriter.WriteString(L"<w:r><w:pict><v:shape id=\"\" type=\"\" style=\"position:absolute;");
|
||||
|
||||
oWriter.WriteString(L"margin-left:");
|
||||
oWriter.AddDouble(m_dLeft, 2);
|
||||
oWriter.WriteString(L"mm;margin-top:");
|
||||
oWriter.AddDouble(m_dTop, 2);
|
||||
oWriter.WriteString(L"mm;width:");
|
||||
oWriter.AddDouble(m_dWidth, 2);
|
||||
oWriter.WriteString(L"mm;height:");
|
||||
oWriter.AddDouble(m_dHeight, 2);
|
||||
oWriter.WriteString(L"mm;");
|
||||
|
||||
if (fabs(m_dRotate) > 0.01)
|
||||
{
|
||||
oWriter.WriteString(L"rotation:");
|
||||
oWriter.AddInt((int)m_dRotate);
|
||||
oWriter.AddCharSafe(';');
|
||||
}
|
||||
|
||||
oWriter.WriteString(L"z-index:-1;mso-position-horizontal-relative:page;mso-position-vertical-relative:page\" filled=\"f\">");
|
||||
|
||||
oWriter.WriteString(L"<v:imagedata r:id=\"rId");
|
||||
oWriter.AddInt(10 + m_lID);
|
||||
oWriter.WriteString(L"\" o:title=\"\"/>");
|
||||
|
||||
oWriter.WriteString(L"</v:shape></w:pict></w:r>");
|
||||
}
|
||||
CImage& operator=(const CImage& oSrc);
|
||||
void ToXml(NSStringUtils::CStringBuilder& oWriter) override final;
|
||||
};
|
||||
}
|
||||
|
||||
#endif // DOCX_RENDERER_ELEMENT_IMAGE_H
|
||||
|
||||
286
DocxRenderer/src/logic/ElementOldShape.cpp
Normal file
286
DocxRenderer/src/logic/ElementOldShape.cpp
Normal file
@ -0,0 +1,286 @@
|
||||
#include "ElementOldShape.h"
|
||||
#include "../resources/utils.h"
|
||||
|
||||
namespace NSDocxRenderer
|
||||
{
|
||||
const double COldShape::POSITION_CORRECTION_FOR_X_MM = 3.0;
|
||||
const double COldShape::POSITION_CORRECTION_FOR_Y_MM = 2.0;
|
||||
const double COldShape::SIZE_CORRECTION_FOR_X_MM = 10.0;
|
||||
const double COldShape::SIZE_CORRECTION_FOR_Y_MM = 5.0;
|
||||
|
||||
COldShape::COldShape() : CBaseItem(ElemType::etOldShape)
|
||||
{
|
||||
}
|
||||
|
||||
COldShape::COldShape(const COldShape &oSrc) : CBaseItem(ElemType::etOldShape)
|
||||
{
|
||||
*this = oSrc;
|
||||
}
|
||||
|
||||
COldShape::~COldShape()
|
||||
{
|
||||
Clear();
|
||||
}
|
||||
|
||||
void COldShape::Clear()
|
||||
{
|
||||
for (auto pParagraph : m_arParagraphs)
|
||||
{
|
||||
pParagraph->Clear();
|
||||
}
|
||||
m_arParagraphs.clear();
|
||||
}
|
||||
|
||||
COldShape &COldShape::operator=(const COldShape &oSrc)
|
||||
{
|
||||
if (this == &oSrc)
|
||||
{
|
||||
return *this;
|
||||
}
|
||||
|
||||
Clear();
|
||||
|
||||
CBaseItem::operator=(oSrc);
|
||||
|
||||
m_strPath = oSrc.m_strPath;
|
||||
|
||||
m_oBrush = oSrc.m_oBrush;
|
||||
m_oPen = oSrc.m_oPen;
|
||||
|
||||
m_bIsNoFill = oSrc.m_bIsNoFill;
|
||||
m_bIsNoStroke = oSrc.m_bIsNoStroke;
|
||||
|
||||
m_lCoordSizeX = oSrc.m_lCoordSizeX;
|
||||
m_lCoordSizeY = oSrc.m_lCoordSizeY;
|
||||
|
||||
m_lTxId = oSrc.m_lTxId;
|
||||
|
||||
for (auto pParagraph : oSrc.m_arParagraphs)
|
||||
{
|
||||
m_arParagraphs.push_back(new CParagraph(*pParagraph));
|
||||
}
|
||||
|
||||
return *this;
|
||||
}
|
||||
|
||||
void COldShape::GetDataFromVector(const CVectorGraphics& oVector, const LONG& lType, const LONG& lCoordSize)
|
||||
{
|
||||
m_dLeft = oVector.m_dLeft;
|
||||
m_dTop = oVector.m_dTop;
|
||||
m_dWidth = oVector.m_dRight - m_dLeft;
|
||||
m_dHeight = oVector.m_dBottom - m_dTop;
|
||||
|
||||
if (m_dWidth < 0.0001)
|
||||
m_dWidth = 0.0001;
|
||||
if (m_dHeight < 0.0001)
|
||||
m_dHeight = 0.0001;
|
||||
|
||||
m_lCoordSizeX = lCoordSize;
|
||||
m_lCoordSizeY = lCoordSize;
|
||||
|
||||
if (0x00 == (lType & 0x01))
|
||||
{
|
||||
m_bIsNoStroke = true;
|
||||
}
|
||||
if (0x00 == (lType >> 8))
|
||||
{
|
||||
m_bIsNoFill = true;
|
||||
}
|
||||
|
||||
WritePath(oVector, lType, lCoordSize);
|
||||
}
|
||||
|
||||
void COldShape::WritePath(const CVectorGraphics& oVector, const LONG& lType, const LONG& lCoordSize)
|
||||
{
|
||||
size_t nCount = oVector.GetCurSize();
|
||||
double *pData = oVector.m_pData;
|
||||
|
||||
double dWidth = oVector.m_dRight - m_dLeft;
|
||||
double dHeight = oVector.m_dBottom - m_dTop;
|
||||
|
||||
NSStringUtils::CStringBuilder oWriter;
|
||||
|
||||
while (nCount > 0)
|
||||
{
|
||||
CVectorGraphics::VectorGraphicsType eType = static_cast<CVectorGraphics::VectorGraphicsType>((int)(0.5 + *pData++));
|
||||
|
||||
switch (eType)
|
||||
{
|
||||
case CVectorGraphics::vgtMove:
|
||||
{
|
||||
LONG lX = static_cast<LONG>((*pData - m_dLeft) * lCoordSize / dWidth);
|
||||
++pData;
|
||||
LONG lY = static_cast<LONG>((*pData - m_dTop) * lCoordSize / dHeight);
|
||||
++pData;
|
||||
|
||||
oWriter.AddCharSafe('m');
|
||||
oWriter.AddInt(lX);
|
||||
oWriter.AddCharSafe(',');
|
||||
oWriter.AddInt(lY);
|
||||
|
||||
nCount -= 3;
|
||||
break;
|
||||
}
|
||||
case CVectorGraphics::vgtLine:
|
||||
{
|
||||
LONG lX = static_cast<LONG>((*pData - m_dLeft) * lCoordSize / dWidth);
|
||||
++pData;
|
||||
LONG lY = static_cast<LONG>((*pData - m_dTop) * lCoordSize / dHeight);
|
||||
++pData;
|
||||
|
||||
oWriter.AddCharSafe('l');
|
||||
oWriter.AddInt(lX);
|
||||
oWriter.AddCharSafe(',');
|
||||
oWriter.AddInt(lY);
|
||||
|
||||
nCount -= 3;
|
||||
break;
|
||||
}
|
||||
case CVectorGraphics::vgtCurve:
|
||||
{
|
||||
LONG lX1 = static_cast<LONG>((*pData - m_dLeft) * lCoordSize / dWidth);
|
||||
++pData;
|
||||
LONG lY1 = static_cast<LONG>((*pData - m_dTop) * lCoordSize / dHeight);
|
||||
++pData;
|
||||
|
||||
LONG lX2 = static_cast<LONG>((*pData - m_dLeft) * lCoordSize / dWidth);
|
||||
++pData;
|
||||
LONG lY2 = static_cast<LONG>((*pData - m_dTop) * lCoordSize / dHeight);
|
||||
++pData;
|
||||
|
||||
LONG lX3 = static_cast<LONG>((*pData - m_dLeft) * lCoordSize / dWidth);
|
||||
++pData;
|
||||
LONG lY3 = static_cast<LONG>((*pData - m_dTop) * lCoordSize / dHeight);
|
||||
++pData;
|
||||
|
||||
oWriter.AddCharSafe('c');
|
||||
oWriter.AddInt(lX1);
|
||||
oWriter.AddCharSafe(',');
|
||||
oWriter.AddInt(lY1);
|
||||
oWriter.AddCharSafe(',');
|
||||
oWriter.AddInt(lX2);
|
||||
oWriter.AddCharSafe(',');
|
||||
oWriter.AddInt(lY2);
|
||||
oWriter.AddCharSafe(',');
|
||||
oWriter.AddInt(lX3);
|
||||
oWriter.AddCharSafe(',');
|
||||
oWriter.AddInt(lY3);
|
||||
|
||||
nCount -= 7;
|
||||
break;
|
||||
}
|
||||
case CVectorGraphics::vgtClose:
|
||||
default:
|
||||
oWriter.AddCharSafe('x');
|
||||
--nCount;
|
||||
break;
|
||||
}
|
||||
}
|
||||
|
||||
if (0x00 == (lType & 0x01))
|
||||
{
|
||||
//m_bIsNoStroke = true;
|
||||
oWriter.WriteString(L"ns");
|
||||
}
|
||||
if (0x00 == (lType >> 8))
|
||||
{
|
||||
//m_bIsNoFill = true;
|
||||
oWriter.WriteString(L"nf");
|
||||
}
|
||||
|
||||
oWriter.AddCharSafe('e');
|
||||
|
||||
m_strPath = oWriter.GetData();
|
||||
oWriter.ClearNoAttack();
|
||||
}
|
||||
|
||||
void COldShape::ToXml(NSStringUtils::CStringBuilder &oWriter)
|
||||
{
|
||||
oWriter.WriteString(
|
||||
L"<w:r><w:pict><v:shape id=\"\" o:spid=\"\" style=\"position:absolute;");
|
||||
|
||||
//oWriter.WriteString(L"left:0;text-align:left;");
|
||||
|
||||
oWriter.WriteString(L"margin-left:");
|
||||
oWriter.AddDouble(m_dLeft, 2);
|
||||
oWriter.WriteString(L"mm;margin-top:");
|
||||
oWriter.AddDouble(m_dTop, 2);
|
||||
oWriter.WriteString(L"mm;width:");
|
||||
oWriter.AddDouble(m_dWidth, 2);
|
||||
oWriter.WriteString(L"mm;height:");
|
||||
oWriter.AddDouble(m_dHeight, 2);
|
||||
oWriter.WriteString(L"mm;");
|
||||
|
||||
oWriter.WriteString(L"z-index:-1;mso-position-horizontal-relative:page;mso-"
|
||||
L"position-vertical-relative:page;\"");
|
||||
|
||||
oWriter.WriteString(L" coordsize=\"");
|
||||
oWriter.AddInt(static_cast<int>(m_lCoordSizeX));
|
||||
oWriter.AddCharSafe(',');
|
||||
oWriter.AddInt(static_cast<int>(m_lCoordSizeY));
|
||||
oWriter.WriteString(L"\" path=\"");
|
||||
oWriter.WriteString(m_strPath);
|
||||
if (c_BrushTypeTexture == m_oBrush.Type)
|
||||
{
|
||||
// у нас нет таких шейпов в pdf/xps
|
||||
oWriter.WriteString(L"\" fillcolor=\"transparent");
|
||||
}
|
||||
else
|
||||
{
|
||||
oWriter.WriteString(L"\" fillcolor=\"#");
|
||||
oWriter.WriteHexInt3(static_cast<int>(ConvertColorBGRToRGB(m_oBrush.Color1)));
|
||||
}
|
||||
oWriter.WriteString(L"\" strokecolor=\"#");
|
||||
oWriter.WriteHexInt3(static_cast<int>(ConvertColorBGRToRGB(m_oPen.Color)));
|
||||
oWriter.WriteString(L"\" strokeweight=\"");
|
||||
oWriter.AddDouble(m_oPen.Size, 2);
|
||||
oWriter.WriteString(L"mm\">");
|
||||
|
||||
std::wstring g_string_fill_opacity = L"<v:fill opacity=\"%.2lf\"/>";
|
||||
std::wstring g_string_stroke_opacity = L"<v:stroke opacity=\"%.2lf\"/>";
|
||||
|
||||
if (c_BrushTypeTexture == m_oBrush.Type && !m_bIsNoFill)
|
||||
{
|
||||
oWriter.WriteString(L"<v:imagedata r:id=\"rId");
|
||||
oWriter.AddInt(10 + m_lTxId);
|
||||
oWriter.WriteString(L"\" o:title=\"\"/>");
|
||||
|
||||
if (0xFF != m_oBrush.TextureAlpha)
|
||||
{
|
||||
oWriter.WriteString(L"<v:fill opacity=\"");
|
||||
oWriter.AddDouble(static_cast<double>(m_oBrush.TextureAlpha / 255.0), 2);
|
||||
oWriter.WriteString(L"\"/>");
|
||||
}
|
||||
}
|
||||
else
|
||||
{
|
||||
if (0xFF != m_oBrush.Alpha1)
|
||||
{
|
||||
oWriter.WriteString(L"<v:fill opacity=\"");
|
||||
oWriter.AddDouble(static_cast<double>(m_oBrush.Alpha1 / 255.0), 2);
|
||||
oWriter.WriteString(L"\"/>");
|
||||
}
|
||||
if (0xFF != m_oPen.Alpha)
|
||||
{
|
||||
oWriter.WriteString(L"<v:stroke opacity=\"");
|
||||
oWriter.AddDouble(static_cast<double>(m_oPen.Alpha / 255.0), 2);
|
||||
oWriter.WriteString(L"\"/>");
|
||||
}
|
||||
}
|
||||
|
||||
oWriter.WriteString(L"<w10:wrap anchorx=\"page\" "
|
||||
L"anchory=\"page\"/>");
|
||||
|
||||
if (!m_arParagraphs.empty())
|
||||
{
|
||||
oWriter.WriteString(L"<v:textbox><w:txbxContent>");
|
||||
for(auto pParagraph : m_arParagraphs)
|
||||
{
|
||||
pParagraph->ToXml(oWriter);
|
||||
}
|
||||
oWriter.WriteString(L"</w:txbxContent></v:textbox>");
|
||||
}
|
||||
|
||||
oWriter.WriteString(L"</v:shape></w:pict></w:r>");
|
||||
}
|
||||
} // namespace NSDocxRenderer
|
||||
46
DocxRenderer/src/logic/ElementOldShape.h
Normal file
46
DocxRenderer/src/logic/ElementOldShape.h
Normal file
@ -0,0 +1,46 @@
|
||||
#pragma once
|
||||
#include "BaseItem.h"
|
||||
#include "../resources/VectorGraphics.h"
|
||||
#include "ElementParagraph.h"
|
||||
|
||||
namespace NSDocxRenderer
|
||||
{
|
||||
class COldShape : public CBaseItem
|
||||
{
|
||||
public:
|
||||
//Подобранные константы
|
||||
static const double POSITION_CORRECTION_FOR_X_MM;
|
||||
static const double POSITION_CORRECTION_FOR_Y_MM;
|
||||
static const double SIZE_CORRECTION_FOR_X_MM;
|
||||
static const double SIZE_CORRECTION_FOR_Y_MM;
|
||||
|
||||
public:
|
||||
std::wstring m_strPath {L""};
|
||||
NSStructures::CBrush m_oBrush;
|
||||
NSStructures::CPen m_oPen;
|
||||
|
||||
bool m_bIsNoFill {false};
|
||||
bool m_bIsNoStroke {false};
|
||||
|
||||
LONG m_lCoordSizeX {100000};
|
||||
LONG m_lCoordSizeY {100000};
|
||||
|
||||
LONG m_lTxId {-1};
|
||||
|
||||
std::vector<CParagraph*> m_arParagraphs;
|
||||
|
||||
public:
|
||||
COldShape();
|
||||
COldShape(const COldShape& oSrc);
|
||||
virtual ~COldShape();
|
||||
void Clear() override final;
|
||||
|
||||
COldShape& operator=(const COldShape& oSrc);
|
||||
|
||||
void GetDataFromVector(const CVectorGraphics& oVector, const LONG& lType, const LONG& lCoordSize);
|
||||
|
||||
void WritePath(const CVectorGraphics& oVector, const LONG& lType, const LONG& lCoordSize);
|
||||
|
||||
void ToXml(NSStringUtils::CStringBuilder& oWriter) override final;
|
||||
};
|
||||
}
|
||||
222
DocxRenderer/src/logic/ElementParagraph.cpp
Normal file
222
DocxRenderer/src/logic/ElementParagraph.cpp
Normal file
@ -0,0 +1,222 @@
|
||||
#include "ElementParagraph.h"
|
||||
#include "src/resources/ColorTable.h"
|
||||
#include "src/resources/SingletonTemplate.h"
|
||||
#include "src/resources/utils.h"
|
||||
|
||||
namespace NSDocxRenderer
|
||||
{
|
||||
CParagraph::CParagraph(const TextAssociationType& eType):
|
||||
CBaseItem(ElemType::etParagraph), m_eTextAssociationType(eType)
|
||||
{
|
||||
}
|
||||
|
||||
CParagraph::CParagraph(const CParagraph& oSrc):
|
||||
CBaseItem(ElemType::etParagraph)
|
||||
{
|
||||
*this = oSrc;
|
||||
}
|
||||
|
||||
CParagraph::~CParagraph()
|
||||
{
|
||||
Clear();
|
||||
}
|
||||
|
||||
void CParagraph::Clear()
|
||||
{
|
||||
for (auto pLine : m_arLines)
|
||||
{
|
||||
RELEASEOBJECT(pLine);
|
||||
}
|
||||
m_arLines.clear();
|
||||
}
|
||||
|
||||
CParagraph& CParagraph::operator=(const CParagraph& oSrc)
|
||||
{
|
||||
if (this == &oSrc)
|
||||
{
|
||||
return *this;
|
||||
}
|
||||
|
||||
Clear();
|
||||
|
||||
CBaseItem::operator=(oSrc);
|
||||
|
||||
m_eTextConversionType = oSrc.m_eTextConversionType;
|
||||
m_bIsNeedFirstLineIndent = oSrc.m_bIsNeedFirstLineIndent;
|
||||
m_bIsAroundTextWrapping = oSrc.m_bIsAroundTextWrapping;
|
||||
m_bIsShadingPresent = oSrc.m_bIsShadingPresent;
|
||||
m_lColorOfShadingFill = oSrc.m_lColorOfShadingFill;
|
||||
m_eTextAlignmentType = oSrc.m_eTextAlignmentType;
|
||||
|
||||
m_dRight = oSrc.m_dRight;
|
||||
m_dFirstLine = oSrc.m_dFirstLine;
|
||||
|
||||
m_dSpaceBefore = oSrc.m_dSpaceBefore;
|
||||
m_dSpaceAfter = oSrc.m_dSpaceAfter;
|
||||
m_dBaselinePos = oSrc.m_dBaselinePos;
|
||||
|
||||
m_eTextAssociationType = oSrc.m_eTextAssociationType;
|
||||
|
||||
for (auto pLine : oSrc.m_arLines)
|
||||
{
|
||||
m_arLines.push_back(new CTextLine(*pLine));
|
||||
}
|
||||
|
||||
m_nNumLines = oSrc.m_nNumLines;
|
||||
return *this;
|
||||
}
|
||||
|
||||
void CParagraph::ToXml(NSStringUtils::CStringBuilder& oWriter)
|
||||
{
|
||||
//todo использовать паттерн builder
|
||||
oWriter.WriteString(L"<w:p>");
|
||||
oWriter.WriteString(L"<w:pPr>");
|
||||
|
||||
switch (m_eTextConversionType)
|
||||
{
|
||||
case tctTextToFrame:
|
||||
{
|
||||
oWriter.WriteString(L"<w:framePr");
|
||||
|
||||
if (m_eTextAssociationType == tatPlainParagraph)
|
||||
{
|
||||
if (m_bIsAroundTextWrapping)
|
||||
{
|
||||
oWriter.WriteString(L" w:wrap=\"around\"");
|
||||
}
|
||||
else
|
||||
{
|
||||
oWriter.WriteString(L" w:wrap=\"notBeside\"");
|
||||
}
|
||||
}
|
||||
|
||||
oWriter.WriteString(L" w:hAnchor=\"page\"");
|
||||
oWriter.WriteString(L" w:vAnchor=\"page\"");
|
||||
|
||||
oWriter.WriteString(L" w:x=\"");
|
||||
oWriter.AddInt(static_cast<int>(m_dLeft * c_dMMToDx));
|
||||
oWriter.WriteString(L"\"");
|
||||
|
||||
oWriter.WriteString(L" w:y=\"");
|
||||
oWriter.AddInt(static_cast<int>(m_dTop * c_dMMToDx));
|
||||
oWriter.WriteString(L"\"");
|
||||
|
||||
oWriter.WriteString(L"/>"); //конец w:framePr
|
||||
break;
|
||||
}
|
||||
case tctTextToShape:
|
||||
case tctTextToParagraph:
|
||||
{
|
||||
oWriter.WriteString(L"<w:spacing");
|
||||
if (m_eTextConversionType == tctTextToParagraph)
|
||||
{
|
||||
oWriter.WriteString(L" w:before=\"");
|
||||
oWriter.AddInt(static_cast<int>(m_dSpaceBefore * c_dMMToDx));
|
||||
oWriter.WriteString(L"\"");
|
||||
}
|
||||
|
||||
if (m_eTextConversionType == tctTextToShape)
|
||||
{
|
||||
oWriter.WriteString(L" w:after=\"");
|
||||
oWriter.AddInt(static_cast<int>(m_dSpaceAfter * c_dMMToDx));
|
||||
oWriter.WriteString(L"\"");
|
||||
}
|
||||
|
||||
oWriter.WriteString(L" w:line=\"");
|
||||
oWriter.AddInt(static_cast<int>(m_dHeight * c_dMMToDx));
|
||||
oWriter.WriteString(L"\" w:lineRule=\"exact\""); // exact - точный размер строки
|
||||
|
||||
oWriter.WriteString(L"/>"); //конец w:spacing
|
||||
|
||||
oWriter.WriteString(L"<w:ind");
|
||||
if (m_dLeft > 0)
|
||||
{
|
||||
oWriter.WriteString(L" w:left=\"");
|
||||
oWriter.AddInt(static_cast<int>(m_dLeft * c_dMMToDx));
|
||||
oWriter.WriteString(L"\"");
|
||||
}
|
||||
if (m_dRight > 0)
|
||||
{
|
||||
oWriter.WriteString(L" w:right=\"");
|
||||
oWriter.AddInt(static_cast<int>(m_dRight * c_dMMToDx));
|
||||
oWriter.WriteString(L"\"");
|
||||
}
|
||||
if (m_bIsNeedFirstLineIndent)
|
||||
{
|
||||
oWriter.WriteString(L" w:firstLine=\"");
|
||||
oWriter.AddInt(static_cast<int>(m_dFirstLine * c_dMMToDx));
|
||||
oWriter.WriteString(L"\"");
|
||||
}
|
||||
oWriter.WriteString(L"/>"); //конец w:ind
|
||||
|
||||
|
||||
if (m_eTextAssociationType == tatPlainParagraph)
|
||||
{
|
||||
switch (m_eTextAlignmentType)
|
||||
{
|
||||
case tatByCenter:
|
||||
oWriter.WriteString(L"<w:jc w:val=\"center\"/>");
|
||||
break;
|
||||
case tatByRightEdge:
|
||||
oWriter.WriteString(L"<w:jc w:val=\"end\"/>");
|
||||
break;
|
||||
case tatByWidth:
|
||||
oWriter.WriteString(L"<w:jc w:val=\"both\"/>");
|
||||
break;
|
||||
case tatByLeftEdge:
|
||||
oWriter.WriteString(L"<w:jc w:val=\"begin\"/>");
|
||||
break;
|
||||
case tatUnknown:
|
||||
default: //по умолчанию выравнивание по левому краю - можно ничего не добавлять
|
||||
break;
|
||||
}
|
||||
}
|
||||
|
||||
if (m_bIsShadingPresent)
|
||||
{
|
||||
oWriter.WriteString(L"<w:shd w:val=\"clear\" w:color=\"auto\" w:fill=\"");
|
||||
oWriter.WriteHexInt3(ConvertColorBGRToRGB(m_lColorOfShadingFill));
|
||||
oWriter.WriteString(L"\"/>");
|
||||
}
|
||||
break;
|
||||
}
|
||||
default:
|
||||
break;
|
||||
}
|
||||
|
||||
oWriter.WriteString(L"</w:pPr>");
|
||||
|
||||
for(auto pLine : m_arLines)
|
||||
{
|
||||
if (m_eTextAssociationType != tatPlainParagraph)
|
||||
{
|
||||
pLine->SortConts();
|
||||
}
|
||||
pLine->ToXml(oWriter);
|
||||
}
|
||||
|
||||
oWriter.WriteString(L"</w:p>");
|
||||
}
|
||||
|
||||
void CParagraph::RemoveHighlightColor()
|
||||
{
|
||||
if (!m_bIsShadingPresent)
|
||||
{
|
||||
return;
|
||||
}
|
||||
|
||||
for(auto pLine : m_arLines)
|
||||
{
|
||||
if (pLine->m_pDominantShape)
|
||||
{
|
||||
for (auto pCont : pLine->m_arConts)
|
||||
{
|
||||
if (m_lColorOfShadingFill == pCont->m_lHighlightColor)
|
||||
{
|
||||
pCont->m_bIsHighlightPresent = false;
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
@ -1,726 +1,71 @@
|
||||
#pragma once
|
||||
#include "Common.h"
|
||||
#include "BaseItem.h"
|
||||
#include "FontManager.h"
|
||||
#include "ElementTextLine.h"
|
||||
|
||||
namespace NSDocxRenderer
|
||||
{
|
||||
const double c_dMMToDx = 72 * 20 / 25.4;
|
||||
|
||||
// у класса T должен быть метод IsBigger, IsBiggerOrEqual
|
||||
template<typename T>
|
||||
void SortElements(std::vector<T*>& oArray)
|
||||
enum TextAssociationType
|
||||
{
|
||||
int nSize = (int)oArray.size();
|
||||
|
||||
// handle 0, 1 and 2 elements
|
||||
if (nSize <= 1)
|
||||
return;
|
||||
if (nSize == 2)
|
||||
{
|
||||
if (oArray[0]->IsBigger(oArray[1]))
|
||||
{
|
||||
T* pTemp = oArray[0];
|
||||
oArray[0] = oArray[1];
|
||||
oArray[1] = pTemp;
|
||||
}
|
||||
return;
|
||||
}
|
||||
|
||||
T* tTemp;
|
||||
|
||||
// arrange elements as tree with greater elements appearing first
|
||||
int nIndex = (nSize >> 1) - 1, nCurr = 0, nNext = 0;
|
||||
int nLast = nSize - 1;
|
||||
int nHalf = nSize >> 1;
|
||||
do
|
||||
{
|
||||
// save element at start of chain
|
||||
tTemp = oArray[nIndex];
|
||||
|
||||
nCurr = nIndex;
|
||||
while (nCurr < nHalf)
|
||||
{
|
||||
nNext = (nCurr << 1) + 1;
|
||||
if (nNext < nLast && (oArray[nNext + 1]->IsBigger(oArray[nNext])))
|
||||
nNext++;
|
||||
if (tTemp->IsBiggerOrEqual(oArray[nNext]))
|
||||
break;
|
||||
|
||||
// promote element in chain
|
||||
oArray[nCurr] = oArray[nNext];
|
||||
nCurr = nNext;
|
||||
}
|
||||
|
||||
// restore element at end of chain
|
||||
oArray[nCurr] = tTemp;
|
||||
}
|
||||
while (nIndex--);
|
||||
|
||||
// sequentially reduce tree size by removing maximum element and rebalancing
|
||||
nIndex = nSize;
|
||||
while (--nIndex)
|
||||
{
|
||||
// save element at start of chain
|
||||
tTemp = oArray[nIndex];
|
||||
oArray[nIndex] = oArray[0];
|
||||
|
||||
nCurr = 0;
|
||||
nLast = nIndex - 1;
|
||||
nHalf = nIndex >> 1;
|
||||
while (nCurr < nHalf)
|
||||
{
|
||||
nNext = (nCurr << 1) + 1;
|
||||
if (nNext < nLast && (oArray[nNext + 1]->IsBigger(oArray[nNext])))
|
||||
nNext++;
|
||||
if (tTemp->IsBiggerOrEqual(oArray[nNext]))
|
||||
break;
|
||||
|
||||
// promote element in chain
|
||||
oArray[nCurr] = oArray[nNext];
|
||||
nCurr = nNext;
|
||||
}
|
||||
|
||||
// restore element at end of chain
|
||||
oArray[nCurr] = tTemp;
|
||||
}
|
||||
}
|
||||
|
||||
inline void DeleteSpaces(NSStringUtils::CStringUTF32& oText)
|
||||
{
|
||||
size_t nLen = oText.length();
|
||||
size_t nStart = 0;
|
||||
|
||||
while ((nStart < nLen) && (' ' == oText[nStart]))
|
||||
++nStart;
|
||||
|
||||
if (nStart == nLen)
|
||||
{
|
||||
oText = L"";
|
||||
return;
|
||||
}
|
||||
|
||||
size_t nEnd = nLen - 1;
|
||||
while ((nEnd > nStart) && (' ' == oText[nEnd]))
|
||||
--nEnd;
|
||||
|
||||
oText = oText.substr(nStart, nEnd - nStart + 1);
|
||||
}
|
||||
|
||||
class CContText
|
||||
{
|
||||
public:
|
||||
NSStructures::CFont m_oFont;
|
||||
NSStructures::CBrush m_oBrush;
|
||||
|
||||
std::wstring m_strPickFontName;
|
||||
LONG m_lPickFontStyle;
|
||||
|
||||
NSStringUtils::CStringUTF32 m_oText;
|
||||
NSStringUtils::CStringUTF32 m_oGidText;
|
||||
|
||||
double m_dX;
|
||||
double m_dY;
|
||||
double m_dWidth;
|
||||
double m_dHeight;
|
||||
double m_dLastX;
|
||||
|
||||
double m_dWidthWithoutSpaces;
|
||||
double m_dLeftWithoutSpaces;
|
||||
|
||||
double m_dPosition;
|
||||
double m_dSpaceWidthMM;
|
||||
|
||||
double m_dCalculateWidth;
|
||||
double m_dSpaceByText;
|
||||
|
||||
public:
|
||||
CContText()
|
||||
{
|
||||
m_strPickFontName = L"";
|
||||
m_lPickFontStyle = 0;
|
||||
|
||||
m_dX = 0;
|
||||
m_dY = 0;
|
||||
m_dWidth = 0;
|
||||
m_dHeight = 0;
|
||||
m_dLastX = 0;
|
||||
|
||||
m_dWidthWithoutSpaces = 0;
|
||||
m_dLeftWithoutSpaces = 0;
|
||||
|
||||
m_dPosition = 0;
|
||||
m_dSpaceWidthMM = 0;
|
||||
|
||||
m_dCalculateWidth = 0;
|
||||
|
||||
m_dSpaceByText = 0;
|
||||
}
|
||||
~CContText()
|
||||
{
|
||||
}
|
||||
|
||||
inline void Clear()
|
||||
{
|
||||
}
|
||||
|
||||
CContText(const CContText& oSrc)
|
||||
{
|
||||
*this = oSrc;
|
||||
}
|
||||
CContText& operator=(const CContText& oSrc)
|
||||
{
|
||||
m_oFont = oSrc.m_oFont;
|
||||
m_oBrush = oSrc.m_oBrush;
|
||||
|
||||
m_oText = oSrc.m_oText;
|
||||
m_oGidText = oSrc.m_oGidText;
|
||||
|
||||
m_strPickFontName = oSrc.m_strPickFontName;
|
||||
m_lPickFontStyle = oSrc.m_lPickFontStyle;
|
||||
|
||||
m_dX = oSrc.m_dX;
|
||||
m_dY = oSrc.m_dY;
|
||||
m_dWidth = oSrc.m_dWidth;
|
||||
m_dHeight = oSrc.m_dHeight;
|
||||
|
||||
m_dLastX = oSrc.m_dLastX;
|
||||
|
||||
m_dWidthWithoutSpaces = oSrc.m_dWidthWithoutSpaces;
|
||||
m_dLeftWithoutSpaces = oSrc.m_dLeftWithoutSpaces;
|
||||
|
||||
m_dPosition = oSrc.m_dPosition;
|
||||
m_dSpaceWidthMM = oSrc.m_dSpaceWidthMM;
|
||||
|
||||
m_dCalculateWidth = oSrc.m_dCalculateWidth;
|
||||
m_dSpaceByText = oSrc.m_dSpaceByText;
|
||||
|
||||
return *this;
|
||||
}
|
||||
|
||||
inline bool IsBigger(const CContText* oSrc)
|
||||
{
|
||||
return (m_dX > oSrc->m_dX) ? true : false;
|
||||
}
|
||||
inline bool IsBiggerOrEqual(const CContText* oSrc)
|
||||
{
|
||||
return (m_dX >= oSrc->m_dX) ? true : false;
|
||||
}
|
||||
|
||||
inline double GetIntersect(const CContText* oSrc) const
|
||||
{
|
||||
double d1 = std::max(m_dX, oSrc->m_dX);
|
||||
double d2 = std::min(m_dX + m_dWidth, oSrc->m_dX + oSrc->m_dWidth);
|
||||
|
||||
if (d2 > d1)
|
||||
return d2 - d1;
|
||||
return 0;
|
||||
}
|
||||
|
||||
inline void Write(NSStringUtils::CStringBuilder& oWriter, CFontManagerLight* pManagerLight, bool bIsAddSpace = false)
|
||||
{
|
||||
oWriter.WriteString(L"<w:r><w:rPr>");
|
||||
|
||||
if (m_dWidth != m_dWidthWithoutSpaces)
|
||||
{
|
||||
DeleteSpaces(m_oText);
|
||||
m_dWidth = m_dWidthWithoutSpaces;
|
||||
}
|
||||
|
||||
if (m_strPickFontName.empty())
|
||||
{
|
||||
if (m_oFont.Bold)
|
||||
oWriter.WriteString(L"<w:b w:val=\"true\"/>");
|
||||
if (m_oFont.Italic)
|
||||
oWriter.WriteString(L"<w:i w:val=\"true\"/>");
|
||||
|
||||
if (bIsAddSpace)
|
||||
{
|
||||
m_dWidth += m_dSpaceWidthMM;
|
||||
m_oText += L" ";
|
||||
}
|
||||
}
|
||||
else
|
||||
{
|
||||
if (0x01 == (0x01 & m_lPickFontStyle))
|
||||
oWriter.WriteString(L"<w:b w:val=\"true\"/>");
|
||||
if (0x02 == (0x02 & m_lPickFontStyle))
|
||||
oWriter.WriteString(L"<w:i w:val=\"true\"/>");
|
||||
|
||||
if (bIsAddSpace)
|
||||
{
|
||||
m_dWidth += pManagerLight->GetSpaceWidth();
|
||||
m_oText += L" ";
|
||||
}
|
||||
|
||||
// нужно перемерять...
|
||||
double ___dSize = (double)((LONG)(m_oFont.Size * 2)) / 2;
|
||||
pManagerLight->LoadFont(m_strPickFontName, m_lPickFontStyle, ___dSize, false);
|
||||
double dWidth = pManagerLight->MeasureStringWidth(m_oText.ToStdWString());
|
||||
|
||||
if (fabs(dWidth - m_dWidth) > 2)
|
||||
{
|
||||
double dSpacing = (m_dWidth - dWidth) / (m_oText.length() + 1);
|
||||
dSpacing *= c_dMMToDx;
|
||||
|
||||
oWriter.WriteString(L"<w:spacing w:val=\"");
|
||||
oWriter.AddInt((int)dSpacing);
|
||||
oWriter.WriteString(L"\"/>");
|
||||
}
|
||||
}
|
||||
|
||||
int lSize = (int)(2 * m_oFont.Size);
|
||||
oWriter.WriteString(L"<w:sz w:val=\"");
|
||||
oWriter.AddInt(lSize);
|
||||
oWriter.WriteString(L"\"/><w:szCs w:val=\"");
|
||||
oWriter.AddInt(lSize);
|
||||
oWriter.WriteString(L"\"/>");
|
||||
|
||||
std::wstring& strFontName = m_strPickFontName.empty() ? m_oFont.Name : m_strPickFontName;
|
||||
oWriter.WriteString(L"<w:rFonts w:ascii=\"");
|
||||
oWriter.WriteEncodeXmlString(strFontName);
|
||||
oWriter.WriteString(L"\" w:hAnsi=\"");
|
||||
oWriter.WriteEncodeXmlString(strFontName);
|
||||
oWriter.WriteString(L"\" w:cs=\"");
|
||||
oWriter.WriteEncodeXmlString(strFontName);
|
||||
oWriter.WriteString(L"\"/>");
|
||||
|
||||
oWriter.WriteString(L"<w:color w:val=\"");
|
||||
oWriter.WriteHexInt3(ConvertColor(m_oBrush.Color1));
|
||||
oWriter.WriteString(L"\"/>");
|
||||
|
||||
oWriter.WriteString(L"</w:rPr>");
|
||||
|
||||
oWriter.WriteString(L"<w:t xml:space=\"preserve\">");
|
||||
oWriter.WriteEncodeXmlString(m_oText.ToStdWString());
|
||||
oWriter.WriteString(L"</w:t>");
|
||||
|
||||
oWriter.WriteString(L"</w:r>");
|
||||
}
|
||||
|
||||
void WriteTo(double dSpacingMM, NSStringUtils::CStringBuilder& oWriter, CFontManagerLight* pManagerLight)
|
||||
{
|
||||
oWriter.WriteString(L"<w:r><w:rPr>");
|
||||
|
||||
double dSpaceMMSize = m_dSpaceWidthMM;
|
||||
if (m_strPickFontName.empty())
|
||||
{
|
||||
if (m_oFont.Bold)
|
||||
oWriter.WriteString(L"<w:b w:val=\"true\"/>");
|
||||
if (m_oFont.Italic)
|
||||
oWriter.WriteString(L"<w:i w:val=\"true\"/>");
|
||||
}
|
||||
else
|
||||
{
|
||||
if (0x01 == (0x01 & m_lPickFontStyle))
|
||||
oWriter.WriteString(L"<w:b w:val=\"true\"/>");
|
||||
if (0x02 == (0x02 & m_lPickFontStyle))
|
||||
oWriter.WriteString(L"<w:i w:val=\"true\"/>");
|
||||
|
||||
dSpaceMMSize = pManagerLight->GetSpaceWidth();
|
||||
}
|
||||
|
||||
int lSize = (int)(2 * m_oFont.Size);
|
||||
oWriter.WriteString(L"<w:sz w:val=\"");
|
||||
oWriter.AddInt(lSize);
|
||||
oWriter.WriteString(L"\"/><w:szCs w:val=\"");
|
||||
oWriter.AddInt(lSize);
|
||||
oWriter.WriteString(L"\"/>");
|
||||
|
||||
std::wstring& strFontName = m_strPickFontName.empty() ? m_oFont.Name : m_strPickFontName;
|
||||
oWriter.WriteString(L"<w:rFonts w:ascii=\"");
|
||||
oWriter.WriteEncodeXmlString(strFontName);
|
||||
oWriter.WriteString(L"\" w:hAnsi=\"");
|
||||
oWriter.WriteEncodeXmlString(strFontName);
|
||||
oWriter.WriteString(L"\" w:cs=\"");
|
||||
oWriter.WriteEncodeXmlString(strFontName);
|
||||
oWriter.WriteString(L"\"/>");
|
||||
|
||||
oWriter.WriteString(L"<w:color w:val=\"");
|
||||
oWriter.WriteHexInt3(ConvertColor(m_oBrush.Color1));
|
||||
oWriter.WriteString(L"\"/>");
|
||||
|
||||
LONG lSpacing = (LONG)((dSpacingMM - dSpaceMMSize) * c_dMMToDx);
|
||||
oWriter.WriteString(L"<w:spacing w:val=\"");
|
||||
oWriter.AddInt((int)lSpacing);
|
||||
oWriter.WriteString(L"\"/>");
|
||||
|
||||
oWriter.WriteString(L"</w:rPr>");
|
||||
|
||||
oWriter.WriteString(L"<w:t xml:space=\"preserve\">");
|
||||
oWriter.WriteString(L" ");
|
||||
oWriter.WriteString(L"</w:t>");
|
||||
|
||||
oWriter.WriteString(L"</w:r>");
|
||||
}
|
||||
};
|
||||
|
||||
class CTextLine
|
||||
{
|
||||
public:
|
||||
std::vector<CContText*> m_arConts;
|
||||
|
||||
double m_dBaselinePos;
|
||||
double m_dBaselineOffset;
|
||||
|
||||
double m_dX;
|
||||
double m_dY;
|
||||
double m_dWidth;
|
||||
double m_dHeight;
|
||||
|
||||
public:
|
||||
CTextLine() : m_arConts()
|
||||
{
|
||||
m_dBaselinePos = 0;
|
||||
|
||||
m_dX = 0;
|
||||
m_dY = 0;
|
||||
m_dWidth = 0;
|
||||
m_dHeight = 0;
|
||||
}
|
||||
void Clear()
|
||||
{
|
||||
for (std::vector<CContText*>::iterator iter = m_arConts.begin(); iter != m_arConts.end(); iter++)
|
||||
{
|
||||
CContText* pText = *iter;
|
||||
RELEASEOBJECT(pText);
|
||||
}
|
||||
m_arConts.clear();
|
||||
}
|
||||
|
||||
~CTextLine()
|
||||
{
|
||||
Clear();
|
||||
}
|
||||
|
||||
CTextLine(const CTextLine& oSrc)
|
||||
{
|
||||
*this = oSrc;
|
||||
}
|
||||
CTextLine& operator=(const CTextLine& oSrc)
|
||||
{
|
||||
Clear();
|
||||
for (std::vector<CContText*>::const_iterator iter = oSrc.m_arConts.begin(); iter != oSrc.m_arConts.end(); iter++)
|
||||
{
|
||||
m_arConts.push_back(new CContText(*(*iter)));
|
||||
}
|
||||
|
||||
m_dBaselinePos = oSrc.m_dBaselinePos;
|
||||
m_dX = oSrc.m_dX;
|
||||
m_dY = oSrc.m_dY;
|
||||
m_dWidth = oSrc.m_dWidth;
|
||||
m_dHeight = oSrc.m_dHeight;
|
||||
}
|
||||
|
||||
inline void AddCont(CContText* pCont, double dBaselineOffset)
|
||||
{
|
||||
if (0 == m_arConts.size())
|
||||
m_dBaselineOffset = dBaselineOffset;
|
||||
|
||||
if ( ( pCont->m_dX > 0 ) && ( ( m_dX == 0 ) || ( pCont->m_dX < m_dX ) ) )
|
||||
m_dX = pCont->m_dX;
|
||||
|
||||
if (m_dHeight < pCont->m_dHeight)
|
||||
m_dHeight = pCont->m_dHeight;
|
||||
|
||||
m_arConts.push_back(pCont);
|
||||
}
|
||||
|
||||
inline bool IsBigger(const CTextLine* oSrc)
|
||||
{
|
||||
return (m_dBaselinePos > oSrc->m_dBaselinePos) ? true : false;
|
||||
}
|
||||
inline bool IsBiggerOrEqual(const CTextLine* oSrc)
|
||||
{
|
||||
return (m_dBaselinePos >= oSrc->m_dBaselinePos) ? true : false;
|
||||
}
|
||||
|
||||
inline void SortConts()
|
||||
{
|
||||
// сортировка непрерывных слов по m_dX
|
||||
SortElements(m_arConts);
|
||||
}
|
||||
|
||||
void Merge(CTextLine* pTextLine)
|
||||
{
|
||||
size_t nCount = pTextLine->m_arConts.size();
|
||||
if (0 != nCount)
|
||||
{
|
||||
if (pTextLine->m_dX < m_dX)
|
||||
{
|
||||
m_dX = pTextLine->m_dX;
|
||||
}
|
||||
if (pTextLine->m_dBaselinePos < m_dBaselinePos)
|
||||
{
|
||||
m_dHeight = (m_dBaselinePos - pTextLine->m_dBaselinePos + pTextLine->m_dHeight);
|
||||
}
|
||||
else
|
||||
{
|
||||
m_dHeight = (pTextLine->m_dBaselinePos - m_dBaselinePos + m_dHeight);
|
||||
}
|
||||
|
||||
double dSubPosition = m_dBaselinePos - pTextLine->m_dBaselinePos;
|
||||
|
||||
for (size_t i = 0; i < nCount; ++i)
|
||||
{
|
||||
pTextLine->m_arConts[i]->m_dPosition = dSubPosition;
|
||||
m_arConts.push_back(pTextLine->m_arConts[i]);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
void Analyze()
|
||||
{
|
||||
size_t nCountConts = m_arConts.size();
|
||||
|
||||
if (0 == nCountConts)
|
||||
return;
|
||||
|
||||
CContText* pFirst = m_arConts[0];
|
||||
|
||||
for (size_t i = 1; i < nCountConts; ++i)
|
||||
{
|
||||
CContText* pCurrent = m_arConts[i];
|
||||
|
||||
if (pFirst->m_strPickFontName != pCurrent->m_strPickFontName ||
|
||||
pFirst->m_oFont.Bold != pCurrent->m_oFont.Bold ||
|
||||
pFirst->m_oFont.Italic != pCurrent->m_oFont.Italic)
|
||||
{
|
||||
// вообще надо бы все объединить. но пока этот метод на соединение "первых"
|
||||
break;
|
||||
}
|
||||
|
||||
double dRight = pFirst->m_dX + pFirst->m_dWidth;
|
||||
double dLeft = pCurrent->m_dX;
|
||||
|
||||
if (fabs(dRight - dLeft) > 0.5)
|
||||
{
|
||||
// вообще надо бы все объединить. но пока этот метод на соединение "первых"
|
||||
break;
|
||||
}
|
||||
|
||||
// продолжаем слово
|
||||
pFirst->m_oText += pCurrent->m_oText;
|
||||
pFirst->m_dWidth = (dLeft + pCurrent->m_dWidth - pFirst->m_dX);
|
||||
|
||||
if (pFirst->m_dWidthWithoutSpaces < 0.0001)
|
||||
{
|
||||
pFirst->m_dLeftWithoutSpaces = pCurrent->m_dLeftWithoutSpaces;
|
||||
}
|
||||
|
||||
if (pCurrent->m_dWidthWithoutSpaces > 0.0001)
|
||||
{
|
||||
pFirst->m_dWidthWithoutSpaces = pCurrent->m_dLeftWithoutSpaces + pCurrent->m_dWidthWithoutSpaces - pFirst->m_dLeftWithoutSpaces;
|
||||
}
|
||||
|
||||
m_arConts.erase(m_arConts.begin() + i);
|
||||
--i;
|
||||
--nCountConts;
|
||||
}
|
||||
}
|
||||
|
||||
bool IsForceBlock()
|
||||
{
|
||||
// линия отсортирована, так что сравниваем только соседние conts
|
||||
size_t nCount = m_arConts.size();
|
||||
if (nCount <= 1)
|
||||
return false;
|
||||
|
||||
for (size_t i = 0; i < nCount; i++)
|
||||
{
|
||||
for (size_t j = i + 1; j < nCount; j++)
|
||||
{
|
||||
if (m_arConts[i]->GetIntersect(m_arConts[j]) > 10)
|
||||
return true;
|
||||
}
|
||||
}
|
||||
return false;
|
||||
}
|
||||
|
||||
void ToXml(NSStringUtils::CStringBuilder& oWriter, CFontManagerLight* pManagerLight)
|
||||
{
|
||||
size_t nCountConts = m_arConts.size();
|
||||
|
||||
if (0 == nCountConts)
|
||||
return;
|
||||
|
||||
CContText* pPrev = m_arConts[0];
|
||||
double dDelta = 0;
|
||||
|
||||
for (size_t i = 1; i < nCountConts; ++i)
|
||||
{
|
||||
CContText* pCurrent = m_arConts[i];
|
||||
|
||||
if (0 == pCurrent->m_dWidthWithoutSpaces)
|
||||
continue;
|
||||
|
||||
dDelta = pCurrent->m_dLeftWithoutSpaces - (pPrev->m_dLeftWithoutSpaces + pPrev->m_dWidthWithoutSpaces);
|
||||
|
||||
if (dDelta < 0.5)
|
||||
{
|
||||
// просто текст на тексте или сменились настройки (font/brush)
|
||||
pPrev->Write(oWriter, pManagerLight);
|
||||
pPrev = pCurrent;
|
||||
}
|
||||
//else if (dDelta < 2 * pPrev->m_dSpaceWidthMM)
|
||||
//{
|
||||
// // сменились настройки, но пробел все-таки вставить нужно
|
||||
// pPrev->Write(oWriter, pManagerLight, true);
|
||||
// pPrev = pCurrent;
|
||||
//}
|
||||
else
|
||||
{
|
||||
// расстояние слишком большое. нужно сделать большой пробел
|
||||
pPrev->Write(oWriter, pManagerLight);
|
||||
pPrev->WriteTo(dDelta, oWriter, pManagerLight);
|
||||
pPrev = pCurrent;
|
||||
}
|
||||
}
|
||||
|
||||
pPrev->Write(oWriter, pManagerLight);
|
||||
}
|
||||
tatBlockChar = 0, // Каждый символ во фрейме
|
||||
tatBlockLine = 1, // Каждая линия - параграф во фрейме. Линии могут объединяться в рамках одного блока.
|
||||
tatPlainLine = 2, // Каждая линия - параграф обычный
|
||||
tatShapeLine = 3, // Каждая линия - параграф в шейпе. Линии могут объединяться в рамках одного блока.
|
||||
tatPlainParagraph = 4 // Линии объединяются в параграфы
|
||||
};
|
||||
|
||||
class CParagraph : public CBaseItem
|
||||
{
|
||||
public:
|
||||
enum TextAlignmentType
|
||||
{
|
||||
tatUnknown,
|
||||
tatByLeftEdge,
|
||||
tatByCenter,
|
||||
tatByRightEdge,
|
||||
tatByWidth
|
||||
};
|
||||
|
||||
enum TextConversionType
|
||||
{
|
||||
tctUnknown,
|
||||
tctTextToParagraph,
|
||||
tctTextToFrame,
|
||||
tctTextToShape
|
||||
};
|
||||
|
||||
// text frame properties
|
||||
bool m_bIsTextFrameProperties;
|
||||
TextConversionType m_eTextConversionType {tctUnknown};
|
||||
bool m_bIsNeedFirstLineIndent {false};
|
||||
bool m_bIsAroundTextWrapping {true}; //по умолчанию обтекание включено, если отсутсвует w:wrap
|
||||
bool m_bIsShadingPresent {false};
|
||||
LONG m_lColorOfShadingFill {c_iWhiteColor}; //BGR
|
||||
TextAlignmentType m_eTextAlignmentType {tatUnknown};
|
||||
|
||||
// geometry paragraph
|
||||
double m_dLeft;
|
||||
double m_dTop;
|
||||
double m_dWidth;
|
||||
double m_dHeight;
|
||||
double m_dRight {0.0}; //сдвиг относительно правого края страницы
|
||||
double m_dFirstLine {0.0}; //сдвиг относительно m_dLeft
|
||||
|
||||
CFontManagerLight* m_pManagerLight;
|
||||
|
||||
double m_dSpaceBefore;
|
||||
TextAssociationType m_eTextAssociationType;
|
||||
double m_dSpaceBefore {0.0}; //по умолчанию выставляется 0, если отсутсвует w:before
|
||||
double m_dSpaceAfter {0.0}; //в shape по умолчанию выставляется 8pt, если отсутсвует w:after
|
||||
double m_dBaselinePos {0.0};
|
||||
TextAssociationType m_eTextAssociationType {tatPlainParagraph};
|
||||
|
||||
std::vector<CTextLine*> m_arLines;
|
||||
|
||||
// statistic
|
||||
size_t m_nNumLines {0}; //число изначально входящих линий
|
||||
|
||||
public:
|
||||
CParagraph(const TextAssociationType& eType) : m_arLines()
|
||||
{
|
||||
m_eType = etParagraph;
|
||||
CParagraph(const TextAssociationType& eType);
|
||||
CParagraph(const CParagraph& oSrc);
|
||||
virtual ~CParagraph();
|
||||
void Clear() override final;
|
||||
|
||||
m_bIsTextFrameProperties = false;
|
||||
CParagraph& operator=(const CParagraph& oSrc);
|
||||
|
||||
m_dLeft = 0.0;
|
||||
m_dTop = 0.0;
|
||||
m_dWidth = 0.0;
|
||||
m_dHeight = 0.0;
|
||||
void ToXml(NSStringUtils::CStringBuilder& oWriter) override final;
|
||||
|
||||
m_dSpaceBefore = 0.0;
|
||||
|
||||
m_pManagerLight = NULL;
|
||||
m_eTextAssociationType = eType;
|
||||
}
|
||||
CParagraph(const CParagraph& oSrc)
|
||||
{
|
||||
*this = oSrc;
|
||||
}
|
||||
~CParagraph()
|
||||
{
|
||||
Clear();
|
||||
}
|
||||
|
||||
void Clear()
|
||||
{
|
||||
size_t nCount = m_arLines.size();
|
||||
for (size_t i = 0; i < nCount; ++i)
|
||||
{
|
||||
CTextLine* pText = m_arLines[i];
|
||||
RELEASEOBJECT(pText);
|
||||
}
|
||||
m_arLines.clear();
|
||||
|
||||
m_pManagerLight = NULL;
|
||||
}
|
||||
|
||||
CParagraph& operator=(const CParagraph& oSrc)
|
||||
{
|
||||
m_eType = etParagraph;
|
||||
|
||||
m_bIsTextFrameProperties = oSrc.m_bIsTextFrameProperties;
|
||||
|
||||
m_dLeft = oSrc.m_dLeft;
|
||||
m_dTop = oSrc.m_dTop;
|
||||
m_dWidth = oSrc.m_dWidth;
|
||||
m_dHeight = oSrc.m_dHeight;
|
||||
|
||||
m_dSpaceBefore = oSrc.m_dSpaceBefore;
|
||||
|
||||
m_eTextAssociationType = oSrc.m_eTextAssociationType;
|
||||
|
||||
Clear();
|
||||
size_t nCount = oSrc.m_arLines.size();
|
||||
for (size_t i = 0; i < nCount; ++i)
|
||||
{
|
||||
m_arLines.push_back(new CTextLine(*oSrc.m_arLines[i]));
|
||||
}
|
||||
|
||||
m_pManagerLight = oSrc.m_pManagerLight;
|
||||
return *this;
|
||||
}
|
||||
|
||||
virtual void ToXml(NSStringUtils::CStringBuilder& oWriter)
|
||||
{
|
||||
oWriter.WriteString(L"<w:p>");
|
||||
|
||||
switch (m_eTextAssociationType)
|
||||
{
|
||||
case TextAssociationTypeBlockChar:
|
||||
{
|
||||
oWriter.WriteString(L"<w:pPr><w:framePr w:hAnchor=\"page\" w:vAnchor=\"page\" w:x=\"");
|
||||
oWriter.AddInt((int)(m_dLeft * c_dMMToDx));
|
||||
oWriter.WriteString(L"\" w:y=\"");
|
||||
oWriter.AddInt((int)(m_dTop * c_dMMToDx));
|
||||
oWriter.WriteString(L"\"/></w:pPr>");
|
||||
break;
|
||||
}
|
||||
case TextAssociationTypeBlockLine:
|
||||
{
|
||||
oWriter.WriteString(L"<w:pPr><w:framePr w:hAnchor=\"page\" w:vAnchor=\"page\" w:x=\"");
|
||||
oWriter.AddInt((int)(m_dLeft * c_dMMToDx));
|
||||
oWriter.WriteString(L"\" w:y=\"");
|
||||
oWriter.AddInt((int)(m_dTop * c_dMMToDx));
|
||||
oWriter.WriteString(L"\"/></w:pPr>");
|
||||
break;
|
||||
}
|
||||
case TextAssociationTypePlainLine:
|
||||
{
|
||||
if (m_bIsTextFrameProperties)
|
||||
{
|
||||
oWriter.WriteString(L"<w:pPr><w:framePr w:hAnchor=\"page\" w:vAnchor=\"page\" w:x=\"");
|
||||
oWriter.AddInt((int)(m_dLeft * c_dMMToDx));
|
||||
oWriter.WriteString(L"\" w:y=\"");
|
||||
oWriter.AddInt((int)(m_dTop * c_dMMToDx));
|
||||
oWriter.WriteString(L"\"/></w:pPr>");
|
||||
break;
|
||||
}
|
||||
oWriter.WriteString(L"<w:pPr><w:spacing w:before=\"");
|
||||
oWriter.AddInt((int)(m_dSpaceBefore * c_dMMToDx));
|
||||
oWriter.WriteString(L"\" w:line=\"");
|
||||
oWriter.AddInt((int)(m_dHeight * c_dMMToDx));
|
||||
oWriter.WriteString(L"\" w:lineRule=\"exact\"/><w:ind w:left=\"");
|
||||
oWriter.AddInt((int)(m_dLeft * c_dMMToDx));
|
||||
oWriter.WriteString(L"\"/></w:pPr>");
|
||||
break;
|
||||
}
|
||||
default:
|
||||
break;
|
||||
}
|
||||
|
||||
size_t nCount = m_arLines.size();
|
||||
for (size_t i = 0; i < nCount; ++i)
|
||||
{
|
||||
CTextLine* pTextLine = m_arLines[i];
|
||||
pTextLine->SortConts();
|
||||
pTextLine->ToXml(oWriter, m_pManagerLight);
|
||||
}
|
||||
|
||||
oWriter.WriteString(L"</w:p>");
|
||||
}
|
||||
};
|
||||
void RemoveHighlightColor();
|
||||
};
|
||||
}
|
||||
|
||||
827
DocxRenderer/src/logic/ElementShape.cpp
Normal file
827
DocxRenderer/src/logic/ElementShape.cpp
Normal file
@ -0,0 +1,827 @@
|
||||
#include "ElementShape.h"
|
||||
#include <limits.h>
|
||||
#include "../resources/Constants.h"
|
||||
#include "../resources/utils.h"
|
||||
|
||||
namespace NSDocxRenderer
|
||||
{
|
||||
CShape::CShape() : CBaseItem(ElemType::etShape)
|
||||
{
|
||||
}
|
||||
|
||||
CShape::CShape(const CShape &oSrc) : CBaseItem(ElemType::etShape)
|
||||
{
|
||||
*this = oSrc;
|
||||
}
|
||||
|
||||
/*CShape::CShape(const CShape& oSrc1, const CShape& oSrc2) : CBaseItem(etShape)
|
||||
{
|
||||
//todo добавить логику объединения двух похожих шейпов в один новый
|
||||
//todo добавить метод ConverPathToVectorGraphics
|
||||
}*/
|
||||
|
||||
CShape::~CShape()
|
||||
{
|
||||
Clear();
|
||||
}
|
||||
|
||||
void CShape::Clear()
|
||||
{
|
||||
for(auto pParagraph : m_arParagraphs)
|
||||
{
|
||||
pParagraph->Clear();
|
||||
}
|
||||
m_arParagraphs.clear();
|
||||
m_pCont = nullptr;
|
||||
}
|
||||
|
||||
CShape& CShape::operator=(const CShape &oSrc)
|
||||
{
|
||||
if (this == &oSrc)
|
||||
{
|
||||
return *this;
|
||||
}
|
||||
|
||||
Clear();
|
||||
|
||||
CBaseItem::operator=(oSrc);
|
||||
|
||||
m_strPath = oSrc.m_strPath;
|
||||
|
||||
m_oBrush = oSrc.m_oBrush;
|
||||
m_oPen = oSrc.m_oPen;
|
||||
|
||||
m_bIsNoFill = oSrc.m_bIsNoFill;
|
||||
m_bIsNoStroke = oSrc.m_bIsNoStroke;
|
||||
m_bIsBehindDoc = oSrc.m_bIsBehindDoc;
|
||||
|
||||
m_lTxId = oSrc.m_lTxId;
|
||||
|
||||
m_eGraphicsType = oSrc.m_eGraphicsType;
|
||||
m_eSimpleLineType = oSrc.m_eSimpleLineType;
|
||||
m_eLineType = oSrc.m_eLineType;
|
||||
|
||||
for (auto pParagraph : oSrc.m_arParagraphs)
|
||||
{
|
||||
m_arParagraphs.push_back(new CParagraph(*pParagraph));
|
||||
}
|
||||
|
||||
m_pCont = oSrc.m_pCont;
|
||||
|
||||
return *this;
|
||||
}
|
||||
|
||||
void CShape::GetDataFromVector(const CVectorGraphics& oVector, const LONG& lType, const LONG& lCoordSize)
|
||||
{
|
||||
m_dLeft = oVector.m_dLeft;
|
||||
m_dTop = oVector.m_dTop;
|
||||
m_dWidth = oVector.m_dRight - m_dLeft;
|
||||
m_dHeight = oVector.m_dBottom - m_dTop;
|
||||
|
||||
if (m_dWidth < 0.0001)
|
||||
m_dWidth = 0.0001;
|
||||
if (m_dHeight < 0.0001)
|
||||
m_dHeight = 0.0001;
|
||||
|
||||
m_lCoordSizeX = lCoordSize;
|
||||
m_lCoordSizeY = lCoordSize;
|
||||
|
||||
if (0x00 == (lType & 0x01))
|
||||
{
|
||||
m_bIsNoStroke = true;
|
||||
}
|
||||
if (0x00 == (lType >> 8))
|
||||
{
|
||||
m_bIsNoFill = true;
|
||||
}
|
||||
|
||||
WritePath(oVector);
|
||||
}
|
||||
|
||||
void CShape::WritePath(const CVectorGraphics& oVector)
|
||||
{
|
||||
size_t nCount = oVector.GetCurSize();
|
||||
double *pData = oVector.m_pData;
|
||||
|
||||
double dWidth = oVector.m_dRight - oVector.m_dLeft;
|
||||
double dHeight = oVector.m_dBottom - oVector.m_dTop;
|
||||
|
||||
NSStringUtils::CStringBuilder oWriter;
|
||||
|
||||
oWriter.WriteString(L"<a:path w=\"");
|
||||
oWriter.AddInt(static_cast<int>(dWidth * c_dMMToEMU));
|
||||
oWriter.WriteString(L"\" h=\"");
|
||||
oWriter.AddInt(static_cast<int>(dHeight * c_dMMToEMU));
|
||||
oWriter.WriteString(L"\">");
|
||||
|
||||
size_t nPeacks = 0;
|
||||
size_t nCurves = 0;
|
||||
|
||||
while (nCount > 0)
|
||||
{
|
||||
CVectorGraphics::VectorGraphicsType eType = static_cast<CVectorGraphics::VectorGraphicsType>((int)(0.5 + *pData++));
|
||||
|
||||
switch (eType)
|
||||
{
|
||||
case CVectorGraphics::vgtMove:
|
||||
{
|
||||
LONG lX = static_cast<LONG>((*pData - m_dLeft) * c_dMMToEMU);
|
||||
++pData;
|
||||
LONG lY = static_cast<LONG>((*pData - m_dTop) * c_dMMToEMU);
|
||||
++pData;
|
||||
|
||||
oWriter.WriteString(L"<a:moveTo><a:pt x=\"");
|
||||
oWriter.AddInt(static_cast<int>(lX));
|
||||
oWriter.WriteString(L"\" y=\"");
|
||||
oWriter.AddInt(static_cast<int>(lY));
|
||||
oWriter.WriteString(L"\"/></a:moveTo>");
|
||||
|
||||
nPeacks++;
|
||||
nCount -= 3;
|
||||
break;
|
||||
}
|
||||
case CVectorGraphics::vgtLine:
|
||||
{
|
||||
LONG lX = static_cast<LONG>((*pData - m_dLeft)* c_dMMToEMU);
|
||||
++pData;
|
||||
LONG lY = static_cast<LONG>((*pData - m_dTop)* c_dMMToEMU);
|
||||
++pData;
|
||||
|
||||
oWriter.WriteString(L"<a:lnTo><a:pt x=\"");
|
||||
oWriter.AddInt(static_cast<int>(lX));
|
||||
oWriter.WriteString(L"\" y=\"");
|
||||
oWriter.AddInt(static_cast<int>(lY));
|
||||
oWriter.WriteString(L"\"/></a:lnTo>");
|
||||
|
||||
nPeacks++;
|
||||
nCount -= 3;
|
||||
break;
|
||||
}
|
||||
case CVectorGraphics::vgtCurve:
|
||||
{
|
||||
LONG lX1 = static_cast<LONG>((*pData - m_dLeft)* c_dMMToEMU);
|
||||
++pData;
|
||||
LONG lY1 = static_cast<LONG>((*pData - m_dTop)* c_dMMToEMU);
|
||||
++pData;
|
||||
LONG lX2 = static_cast<LONG>((*pData - m_dLeft)* c_dMMToEMU);
|
||||
++pData;
|
||||
LONG lY2 = static_cast<LONG>((*pData - m_dTop)* c_dMMToEMU);
|
||||
++pData;
|
||||
LONG lX3 = static_cast<LONG>((*pData - m_dLeft)* c_dMMToEMU);
|
||||
++pData;
|
||||
LONG lY3 = static_cast<LONG>((*pData - m_dTop)* c_dMMToEMU);
|
||||
++pData;
|
||||
|
||||
oWriter.WriteString(L"<a:cubicBezTo>");
|
||||
|
||||
oWriter.WriteString(L"<a:pt x=\"");
|
||||
oWriter.AddInt(static_cast<int>(lX1));
|
||||
oWriter.WriteString(L"\" y=\"");
|
||||
oWriter.AddInt(static_cast<int>(lY1));
|
||||
oWriter.WriteString(L"\"/>");
|
||||
oWriter.WriteString(L"<a:pt x=\"");
|
||||
oWriter.AddInt(static_cast<int>(lX2));
|
||||
oWriter.WriteString(L"\" y=\"");
|
||||
oWriter.AddInt(static_cast<int>(lY2));
|
||||
oWriter.WriteString(L"\"/>");
|
||||
oWriter.WriteString(L"<a:pt x=\"");
|
||||
oWriter.AddInt(static_cast<int>(lX3));
|
||||
oWriter.WriteString(L"\" y=\"");
|
||||
oWriter.AddInt(static_cast<int>(lY3));
|
||||
oWriter.WriteString(L"\"/>");
|
||||
|
||||
oWriter.WriteString(L"</a:cubicBezTo>");
|
||||
|
||||
nCurves++;
|
||||
nCount -= 7;
|
||||
break;
|
||||
}
|
||||
case CVectorGraphics::vgtClose:
|
||||
default:
|
||||
--nCount;
|
||||
break;
|
||||
}
|
||||
}
|
||||
oWriter.WriteString(L"<a:close/>");
|
||||
oWriter.WriteString(L"</a:path>");
|
||||
|
||||
m_strPath = oWriter.GetData();
|
||||
|
||||
DetermineGraphicsType(dWidth, dHeight, nPeacks, nCurves);
|
||||
|
||||
oWriter.ClearNoAttack();
|
||||
}
|
||||
|
||||
void CShape::DetermineGraphicsType(const double& dWidth, const double& dHeight,const size_t& nPeacks, const size_t& nCurves)
|
||||
{
|
||||
//note параллельно для каждой текстовой строки создается шейп, который содержит цвет фона для данного текста.
|
||||
if (m_oBrush.Color1 == c_iWhiteColor && m_oPen.Color == c_iWhiteColor)
|
||||
{
|
||||
m_eGraphicsType = eGraphicsType::gtNoGraphics;
|
||||
//заранее отбрасываем некоторые фигуры
|
||||
m_bIsNotNecessaryToUse = true;
|
||||
}
|
||||
else if (nPeacks == 5 && !nCurves) //1 move + 4 Peacks
|
||||
{
|
||||
m_eGraphicsType = eGraphicsType::gtRectangle;
|
||||
|
||||
//note Довольно сложно определить точку, т.к. для разных шрифтов она может быть чем угодно...
|
||||
if (abs(dWidth - dHeight) < 0.1)
|
||||
{
|
||||
m_eSimpleLineType = eSimpleLineType::sltDot;
|
||||
}
|
||||
else if (dHeight + c_GRAPHICS_ERROR_IN_LINES_MM < dWidth)
|
||||
{
|
||||
m_eSimpleLineType = eSimpleLineType::sltDash;
|
||||
}
|
||||
else
|
||||
{
|
||||
m_eSimpleLineType = eSimpleLineType::sltDot;
|
||||
}
|
||||
}
|
||||
else if (nCurves > 0 && nPeacks <= 1) //1 move
|
||||
{
|
||||
m_eGraphicsType = eGraphicsType::gtCurve;
|
||||
m_eSimpleLineType = eSimpleLineType::sltWave;
|
||||
}
|
||||
else if (nCurves > 0 && nPeacks > 1)
|
||||
{
|
||||
m_eGraphicsType = eGraphicsType::gtComplicatedFigure;
|
||||
}
|
||||
}
|
||||
|
||||
bool CShape::IsItFitLine()
|
||||
{
|
||||
return (m_eGraphicsType == eGraphicsType::gtRectangle && (m_eSimpleLineType == eSimpleLineType::sltDot || m_eSimpleLineType == eSimpleLineType::sltDash)) ||
|
||||
(m_eGraphicsType == eGraphicsType::gtCurve && m_eSimpleLineType == eSimpleLineType::sltWave);
|
||||
}
|
||||
|
||||
bool CShape::IsCorrelated(const CShape* pShape)
|
||||
{
|
||||
return m_eGraphicsType == pShape->m_eGraphicsType;
|
||||
}
|
||||
|
||||
void CShape::ChangeGeometryOfDesiredShape(CShape* pShape)
|
||||
{
|
||||
if (!pShape)
|
||||
{
|
||||
return;
|
||||
}
|
||||
|
||||
CShape* pModObject;
|
||||
CShape* pDataObject;
|
||||
|
||||
if (pShape->m_bIsNotNecessaryToUse)
|
||||
{
|
||||
pModObject = this;
|
||||
pDataObject = pShape;
|
||||
}
|
||||
else if (m_bIsNotNecessaryToUse)
|
||||
{
|
||||
pModObject = pShape;
|
||||
pDataObject = this;
|
||||
}
|
||||
else
|
||||
{
|
||||
return;
|
||||
}
|
||||
|
||||
double dModRight = pModObject->m_dLeft + pModObject->m_dWidth;
|
||||
double dDataRight = pDataObject->m_dLeft + pDataObject->m_dWidth;
|
||||
double dModBottom = pModObject->m_dTop + pModObject->m_dHeight;
|
||||
double dDataBottom = pDataObject->m_dTop + pDataObject->m_dHeight;
|
||||
|
||||
if (pModObject->m_dTop == pDataObject->m_dTop ||
|
||||
(pModObject->m_dTop < pDataObject->m_dTop && pModObject->m_dHeight > pDataObject->m_dHeight) ||
|
||||
(pModObject->m_dTop > pDataObject->m_dTop && pModObject->m_dHeight < pDataObject->m_dHeight))
|
||||
{
|
||||
pModObject->m_dHeight = std::max(pModObject->m_dHeight, pDataObject->m_dHeight);
|
||||
}
|
||||
else if (pModObject->m_dTop < pDataObject->m_dTop)
|
||||
{
|
||||
pModObject->m_dHeight += pDataObject->m_dHeight + pDataObject->m_dTop - dModBottom;
|
||||
}
|
||||
else
|
||||
{
|
||||
pModObject->m_dHeight += pDataObject->m_dHeight + dDataBottom - pModObject->m_dTop;
|
||||
}
|
||||
|
||||
if (pModObject->m_dLeft == pDataObject->m_dLeft ||
|
||||
(pModObject->m_dLeft < pDataObject->m_dLeft && dModRight > dDataRight) ||
|
||||
(pModObject->m_dLeft > pDataObject->m_dLeft && dModRight < dDataRight))
|
||||
{
|
||||
pModObject->m_dWidth = std::max(pModObject->m_dWidth, pDataObject->m_dWidth);
|
||||
}
|
||||
else if (pModObject->m_dLeft < pDataObject->m_dLeft)
|
||||
{
|
||||
pModObject->m_dWidth += pDataObject->m_dWidth + pDataObject->m_dLeft - dModRight;
|
||||
}
|
||||
else
|
||||
{
|
||||
pModObject->m_dWidth += pDataObject->m_dWidth + dDataRight - pModObject->m_dLeft;
|
||||
}
|
||||
|
||||
pModObject->m_dLeft = std::min(pModObject->m_dLeft, pDataObject->m_dLeft);
|
||||
pModObject->m_dTop = std::min(pModObject->m_dTop, pDataObject->m_dTop);
|
||||
}
|
||||
|
||||
void CShape::DetermineLineType(CShape* pShape)
|
||||
{
|
||||
if (!pShape)
|
||||
{
|
||||
//Если нашелся один шейп в линии
|
||||
if (m_eLineType == eLineType::ltUnknown && m_eSimpleLineType == eSimpleLineType::sltDash)
|
||||
{
|
||||
if (m_dHeight > 0.3)
|
||||
{
|
||||
m_eLineType = eLineType::ltThick;
|
||||
}
|
||||
else
|
||||
{
|
||||
m_eLineType = eLineType::ltSingle;
|
||||
}
|
||||
}
|
||||
else if (m_eLineType == eLineType::ltUnknown && m_eSimpleLineType == eSimpleLineType::sltWave)
|
||||
{
|
||||
if (m_oPen.Size > 0.3)
|
||||
{
|
||||
m_eLineType = eLineType::ltWavyHeavy;
|
||||
}
|
||||
else
|
||||
{
|
||||
m_eLineType = eLineType::ltWave;
|
||||
}
|
||||
}
|
||||
return;
|
||||
}
|
||||
|
||||
if (!IsItFitLine() || !pShape->IsItFitLine() || !IsCorrelated(pShape) ||
|
||||
std::abs(m_dHeight - pShape->m_dHeight) > c_GRAPHICS_ERROR_IN_LINES_MM) //линия должна быть одного размера по высоте
|
||||
{
|
||||
return;
|
||||
}
|
||||
|
||||
|
||||
//Проверка на двойную линию
|
||||
if (m_eLineType == eLineType::ltDouble || m_eLineType == eLineType::ltWavyDouble)
|
||||
{
|
||||
if (m_eLineType == eLineType::ltDouble)
|
||||
{
|
||||
if (m_dTop < pShape->m_dTop)
|
||||
{
|
||||
m_eLineType = eLineType::ltDouble;
|
||||
pShape->m_bIsNotNecessaryToUse = true;
|
||||
ChangeGeometryOfDesiredShape(pShape);
|
||||
}
|
||||
else
|
||||
{
|
||||
pShape->m_eLineType = eLineType::ltDouble;
|
||||
m_bIsNotNecessaryToUse = true;
|
||||
ChangeGeometryOfDesiredShape(pShape);
|
||||
}
|
||||
}
|
||||
else if (m_eLineType == eLineType::ltWavyDouble)
|
||||
{
|
||||
if (m_dTop < pShape->m_dTop)
|
||||
{
|
||||
m_eLineType = eLineType::ltWavyDouble;
|
||||
pShape->m_bIsNotNecessaryToUse = true;
|
||||
ChangeGeometryOfDesiredShape(pShape);
|
||||
}
|
||||
else
|
||||
{
|
||||
pShape->m_eLineType = eLineType::ltWavyDouble;
|
||||
m_bIsNotNecessaryToUse = true;
|
||||
ChangeGeometryOfDesiredShape(pShape);
|
||||
}
|
||||
}
|
||||
return;
|
||||
}
|
||||
else if (std::abs(m_dTop - pShape->m_dTop) < c_GRAPHICS_ERROR_IN_LINES_MM * 5 &&
|
||||
std::abs(m_dWidth - pShape->m_dWidth) < c_GRAPHICS_ERROR_IN_LINES_MM &&
|
||||
std::abs(m_dLeft - pShape->m_dLeft) < c_GRAPHICS_ERROR_IN_LINES_MM)
|
||||
{
|
||||
//Условие первого определения
|
||||
if (m_eSimpleLineType == eSimpleLineType::sltDash && pShape->m_eSimpleLineType == eSimpleLineType::sltDash)
|
||||
{
|
||||
if (m_dTop < pShape->m_dTop)
|
||||
{
|
||||
m_eLineType = eLineType::ltDouble;
|
||||
pShape->m_bIsNotNecessaryToUse = true;
|
||||
ChangeGeometryOfDesiredShape(pShape);
|
||||
}
|
||||
else
|
||||
{
|
||||
pShape->m_eLineType = eLineType::ltDouble;
|
||||
m_bIsNotNecessaryToUse = true;
|
||||
ChangeGeometryOfDesiredShape(pShape);
|
||||
}
|
||||
}
|
||||
else if (m_eSimpleLineType == eSimpleLineType::sltWave && pShape->m_eSimpleLineType == eSimpleLineType::sltWave)
|
||||
{
|
||||
if (m_dTop < pShape->m_dTop)
|
||||
{
|
||||
m_eLineType = eLineType::ltWavyDouble;
|
||||
pShape->m_bIsNotNecessaryToUse = true;
|
||||
ChangeGeometryOfDesiredShape(pShape);
|
||||
}
|
||||
else
|
||||
{
|
||||
pShape->m_eLineType = eLineType::ltWavyDouble;
|
||||
m_bIsNotNecessaryToUse = true;
|
||||
ChangeGeometryOfDesiredShape(pShape);
|
||||
}
|
||||
}
|
||||
return;
|
||||
}
|
||||
else if (std::abs(m_dTop - pShape->m_dTop) > c_GRAPHICS_ERROR_IN_LINES_MM)
|
||||
{
|
||||
//все должно быть на одной линии
|
||||
return;
|
||||
}
|
||||
|
||||
//Теперь считаем, что графика находится на одной линии
|
||||
if (std::abs(m_dLeft + m_dWidth - pShape->m_dLeft) > c_GRAPHICS_ERROR_IN_LINES_MM * 5)
|
||||
{
|
||||
//расстояние между объектами на одной линии должно быть небольшим
|
||||
return;
|
||||
}
|
||||
|
||||
bool bIsConditionPassed = false;
|
||||
|
||||
switch (m_eSimpleLineType)
|
||||
{
|
||||
case eSimpleLineType::sltDot:
|
||||
if (pShape->m_eSimpleLineType == eSimpleLineType::sltDot)
|
||||
{
|
||||
if ((m_eLineType == eLineType::ltUnknown || m_eLineType == eLineType::ltDotted ||
|
||||
m_eLineType == eLineType::ltDottedHeavy) && pShape->m_eLineType == eLineType::ltUnknown)
|
||||
{
|
||||
if (m_dHeight > 0.3)
|
||||
{
|
||||
m_eLineType = eLineType::ltDottedHeavy;
|
||||
}
|
||||
else
|
||||
{
|
||||
m_eLineType = eLineType::ltDotted;
|
||||
}
|
||||
bIsConditionPassed = true;
|
||||
}
|
||||
else if ((m_eLineType == eLineType::ltDotDash || m_eLineType == eLineType::ltDashDotHeavy) &&
|
||||
pShape->m_eLineType == eLineType::ltUnknown)
|
||||
{
|
||||
if (m_dHeight > 0.3)
|
||||
{
|
||||
m_eLineType = eLineType::ltDashDotDotHeavy;
|
||||
}
|
||||
else
|
||||
{
|
||||
m_eLineType = eLineType::ltDotDotDash;
|
||||
}
|
||||
m_eSimpleLineType = eSimpleLineType::sltDot;
|
||||
bIsConditionPassed = true;
|
||||
}
|
||||
}
|
||||
else if (pShape->m_eSimpleLineType == eSimpleLineType::sltDash)
|
||||
{
|
||||
if ((m_eLineType == eLineType::ltDotDash || m_eLineType == eLineType::ltDashDotHeavy) &&
|
||||
pShape->m_eLineType == eLineType::ltUnknown)
|
||||
{
|
||||
m_eSimpleLineType = eSimpleLineType::sltDash;
|
||||
bIsConditionPassed = true;
|
||||
}
|
||||
else if ((m_eLineType == eLineType::ltDotDotDash || m_eLineType == eLineType::ltDashDotDotHeavy) &&
|
||||
pShape->m_eLineType == eLineType::ltUnknown)
|
||||
{
|
||||
m_eSimpleLineType = eSimpleLineType::sltDash;
|
||||
bIsConditionPassed = true;
|
||||
}
|
||||
}
|
||||
|
||||
if (pShape->m_eLineType == eLineType::ltUnknown)
|
||||
{
|
||||
//Если не определились с типом, то считаем линией текущего типа
|
||||
bIsConditionPassed = true;
|
||||
}
|
||||
break;
|
||||
case eSimpleLineType::sltDash:
|
||||
if (pShape->m_eSimpleLineType == eSimpleLineType::sltDash)
|
||||
{
|
||||
if ((m_eLineType == eLineType::ltUnknown || m_eLineType == eLineType::ltDash ||
|
||||
m_eLineType == eLineType::ltDashLong || m_eLineType == eLineType::ltDashedHeavy ||
|
||||
m_eLineType == eLineType::ltDashLongHeavy) && pShape->m_eLineType == eLineType::ltUnknown)
|
||||
{
|
||||
if (pShape->m_dWidth > 2.0)
|
||||
{
|
||||
if (m_dHeight > 0.3)
|
||||
{
|
||||
m_eLineType = eLineType::ltDashLongHeavy;
|
||||
}
|
||||
else
|
||||
{
|
||||
m_eLineType = eLineType::ltDashLong;
|
||||
}
|
||||
}
|
||||
else
|
||||
{
|
||||
if (m_dHeight > 0.3)
|
||||
{
|
||||
m_eLineType = eLineType::ltDashedHeavy;
|
||||
}
|
||||
else
|
||||
{
|
||||
m_eLineType = eLineType::ltDash;
|
||||
}
|
||||
}
|
||||
bIsConditionPassed = true;
|
||||
}
|
||||
else if ((m_eLineType == eLineType::ltDotDash || m_eLineType == eLineType::ltDashDotHeavy) &&
|
||||
pShape->m_eLineType == eLineType::ltUnknown)
|
||||
{
|
||||
bIsConditionPassed = true;
|
||||
}
|
||||
}
|
||||
else if (pShape->m_eSimpleLineType == eSimpleLineType::sltDot)
|
||||
{
|
||||
if ((m_eLineType == eLineType::ltUnknown || m_eLineType == eLineType::ltDotDash ||
|
||||
m_eLineType == eLineType::ltDashDotHeavy) && pShape->m_eLineType == eLineType::ltUnknown)
|
||||
{
|
||||
if (m_dHeight > 0.3)
|
||||
{
|
||||
m_eLineType = eLineType::ltDashDotHeavy;
|
||||
}
|
||||
else
|
||||
{
|
||||
m_eLineType = eLineType::ltDotDash;
|
||||
}
|
||||
m_eSimpleLineType = eSimpleLineType::sltDot;
|
||||
bIsConditionPassed = true;
|
||||
}
|
||||
else if ((m_eLineType == eLineType::ltDotDotDash || m_eLineType == eLineType::ltDashDotDotHeavy) &&
|
||||
pShape->m_eLineType == eLineType::ltUnknown)
|
||||
{
|
||||
m_eSimpleLineType = eSimpleLineType::sltDot;
|
||||
bIsConditionPassed = true;
|
||||
}
|
||||
}
|
||||
|
||||
if (pShape->m_eLineType == eLineType::ltUnknown)
|
||||
{
|
||||
//Если не определились с типом, то считаем линией текущего типа
|
||||
bIsConditionPassed = true;
|
||||
}
|
||||
break;
|
||||
case eSimpleLineType::sltWave:
|
||||
if ((m_eLineType == eLineType::ltUnknown || m_eLineType == eLineType::ltWave ||
|
||||
m_eLineType == eLineType::ltWavyHeavy || m_eLineType == eLineType::ltWavyDouble) &&
|
||||
pShape->m_eLineType == eLineType::ltUnknown)
|
||||
{
|
||||
if (m_oPen.Size > 0.3)
|
||||
{
|
||||
m_eLineType = eLineType::ltWavyHeavy;
|
||||
}
|
||||
else
|
||||
{
|
||||
m_eLineType = eLineType::ltWave;
|
||||
}
|
||||
bIsConditionPassed = true;
|
||||
}
|
||||
break;
|
||||
default:
|
||||
break;
|
||||
}
|
||||
|
||||
if (bIsConditionPassed)
|
||||
{
|
||||
pShape->m_bIsNotNecessaryToUse = true;
|
||||
ChangeGeometryOfDesiredShape(pShape);
|
||||
}
|
||||
}
|
||||
|
||||
void CShape::ToXml(NSStringUtils::CStringBuilder &oWriter)
|
||||
{
|
||||
//todo для уменьшения размера каждого шейпа ипользовавать только то, что необходимо - для графики, текста, графика+текст
|
||||
//todo добавить все возможные параметры/атрибуты
|
||||
|
||||
//note Если обрабатывается много документов за раз, то iNumber сохраняется.
|
||||
static UINT iNumber = 1;
|
||||
oWriter.WriteString(L"<w:r>");
|
||||
|
||||
oWriter.WriteString(L"<w:rPr><w:noProof/></w:rPr>"); //отключение проверки орфографии
|
||||
|
||||
oWriter.WriteString(L"<mc:AlternateContent>");
|
||||
oWriter.WriteString(L"<mc:Choice Requires=\"wps\">");
|
||||
oWriter.WriteString(L"<w:drawing>");
|
||||
|
||||
oWriter.WriteString(L"<wp:anchor");
|
||||
oWriter.WriteString(L" distT=\"0\""); //Определяет минимальное расстояние, которое должно сохраняться между краем
|
||||
oWriter.WriteString(L" distB=\"0\""); //этого объекта рисования и любым последующим текстом в документе, когда
|
||||
oWriter.WriteString(L" distL=\"0\""); //этот графический объект объект отображается в содержимом документа.
|
||||
oWriter.WriteString(L" distR=\"0\"");
|
||||
oWriter.WriteString(L" simplePos=\"0\""); //true/1 Указывает, что этот объект должен быть позиционирован с использованием информации о позиционировании в дочернем элементе simplePos
|
||||
oWriter.WriteString(L" relativeHeight=\""); //Определяет относительное упорядочивание по Z всех объектов DrawingML в этом документе.
|
||||
oWriter.AddUInt(static_cast<UINT>(UINT_MAX - iNumber));
|
||||
oWriter.WriteString(L"\"");
|
||||
oWriter.WriteString(L" behindDoc=\""); //позади текста - 1, перед текстом - 0
|
||||
oWriter.AddUInt(static_cast<UINT>(m_bIsBehindDoc));
|
||||
oWriter.WriteString(L"\"");
|
||||
oWriter.WriteString(L" locked=\"0\""); //true/1 Указывает, что местоположение привязки для этого объекта не должно быть изменено во время выполнения, когда приложение редактирует содержимое этого документа.
|
||||
oWriter.WriteString(L" layoutInCell=\"0\""); //объект будет позиционирован, как указано, но таблица будет изменена в размерах и/или перемещена в документе, как это необходимо для размещения объекта.
|
||||
oWriter.WriteString(L" allowOverlap=\"1\""); //разрешается перекрывать содержимое другого объекта
|
||||
oWriter.WriteString(L" hidden=\"0\""); //Определяет, будет ли отображаться данный плавающий объект DrawingML.
|
||||
oWriter.WriteString(L">");
|
||||
|
||||
oWriter.WriteString(L"<wp:simplePos x=\"0\" y=\"0\"/>");
|
||||
|
||||
oWriter.WriteString(L"<wp:positionH relativeFrom=\"page\">");
|
||||
oWriter.WriteString(L"<wp:posOffset>");
|
||||
oWriter.AddInt(static_cast<int>(m_dLeft * c_dMMToEMU));
|
||||
oWriter.WriteString(L"</wp:posOffset>");
|
||||
oWriter.WriteString(L"</wp:positionH>");
|
||||
|
||||
oWriter.WriteString(L"<wp:positionV relativeFrom=\"page\">");
|
||||
oWriter.WriteString(L"<wp:posOffset>");
|
||||
oWriter.AddInt(static_cast<int>(m_dTop * c_dMMToEMU));
|
||||
oWriter.WriteString(L"</wp:posOffset>");
|
||||
oWriter.WriteString(L"</wp:positionV>");
|
||||
|
||||
//координаты конца границы шейпа
|
||||
oWriter.WriteString(L"<wp:extent");
|
||||
oWriter.WriteString(L" cx=\"");
|
||||
oWriter.AddInt(static_cast<int>(m_dWidth * c_dMMToEMU));
|
||||
oWriter.WriteString(L"\" cy=\"");
|
||||
oWriter.AddInt(static_cast<int>(m_dHeight * c_dMMToEMU));
|
||||
oWriter.WriteString(L"\"/>");
|
||||
|
||||
oWriter.WriteString(L"<wp:effectExtent l=\"0\" t=\"0\" r=\"0\" b=\"0\"/>"); //Этот элемент определяет дополнительное расстояние, которое должно быть добавлено к каждому краю изображения, чтобы компенсировать любые эффекты рисования, применяемые к объекту DrawingML
|
||||
|
||||
oWriter.WriteString(L"<wp:wrapNone/>");
|
||||
|
||||
oWriter.WriteString(L"<wp:docPr id=\"");
|
||||
oWriter.AddUInt(iNumber);
|
||||
oWriter.WriteString(L"\" name=\"Freeform: Shape ");
|
||||
oWriter.AddUInt(iNumber);
|
||||
oWriter.WriteString(L"\"/>");
|
||||
iNumber++;
|
||||
|
||||
oWriter.WriteString(L"<wp:cNvGraphicFramePr/>");
|
||||
|
||||
oWriter.WriteString(L"<a:graphic xmlns:a=\"http://schemas.openxmlformats.org/drawingml/2006/main\">");
|
||||
|
||||
oWriter.WriteString(L"<a:graphicData uri=\"http://schemas.microsoft.com/office/word/2010/wordprocessingShape\">");
|
||||
|
||||
oWriter.WriteString(L"<wps:wsp>");
|
||||
|
||||
oWriter.WriteString(L"<wps:cNvSpPr/>"); //non-visual shape properties. http://officeopenxml.com/drwSp-nvSpPr.php
|
||||
|
||||
oWriter.WriteString(L"<wps:spPr>"); //shape properties. http://officeopenxml.com/drwSp-SpPr.php
|
||||
//отвечает за размеры прямоугольного фрейма шейпа
|
||||
oWriter.WriteString(L"<a:xfrm>");
|
||||
oWriter.WriteString(L"<a:off x=\"0\" y=\"0\"/>");
|
||||
oWriter.WriteString(L"<a:ext");
|
||||
oWriter.WriteString(L" cx=\"");
|
||||
oWriter.AddInt(static_cast<int>(m_dWidth * c_dMMToEMU));
|
||||
oWriter.WriteString(L"\" cy=\"");
|
||||
oWriter.AddInt(static_cast<int>(m_dHeight * c_dMMToEMU));
|
||||
oWriter.WriteString(L"\"/>");
|
||||
oWriter.WriteString(L"</a:xfrm>");
|
||||
|
||||
//Если просто текст без графики
|
||||
if (m_strPath.empty())
|
||||
{
|
||||
oWriter.WriteString(L"<a:prstGeom prst=\"rect\">");
|
||||
oWriter.WriteString(L"<a:avLst/>");
|
||||
oWriter.WriteString(L"</a:prstGeom>");
|
||||
}
|
||||
else
|
||||
{
|
||||
//Рисуем сложный путь
|
||||
oWriter.WriteString(L"<a:custGeom>");
|
||||
oWriter.WriteString(L"<a:avLst/>");
|
||||
oWriter.WriteString(L"<a:gdLst/>");
|
||||
oWriter.WriteString(L"<a:ahLst/>");
|
||||
oWriter.WriteString(L"<a:cxnLst/>");
|
||||
oWriter.WriteString(L"<a:rect l=\"l\" t=\"t\" r=\"r\" b=\"b\"/>");
|
||||
oWriter.WriteString(L"<a:pathLst>");
|
||||
oWriter.WriteString(m_strPath);
|
||||
oWriter.WriteString(L"</a:pathLst>");
|
||||
oWriter.WriteString(L"</a:custGeom>");
|
||||
}
|
||||
|
||||
if (m_bIsNoFill)
|
||||
{
|
||||
//Нет заливки
|
||||
oWriter.WriteString(L"<a:noFill/>");
|
||||
}
|
||||
else
|
||||
{
|
||||
//Есть заливка
|
||||
oWriter.WriteString(L"<a:solidFill>");
|
||||
oWriter.WriteString(L"<a:srgbClr val=\"");
|
||||
oWriter.WriteHexInt3(static_cast<int>(ConvertColorBGRToRGB(m_oBrush.Color1)));
|
||||
if (0xFF != m_oBrush.TextureAlpha)
|
||||
{
|
||||
oWriter.WriteString(L"\"><a:alpha val=\"");
|
||||
oWriter.AddInt(static_cast<int>(m_oPen.Alpha / 255.0 * 100.0));
|
||||
oWriter.WriteString(L"%\"/></a:srgbClr>");
|
||||
}
|
||||
else
|
||||
{
|
||||
oWriter.WriteString(L"\"/>");
|
||||
}
|
||||
oWriter.WriteString(L"</a:solidFill>");
|
||||
}
|
||||
|
||||
if (m_bIsNoStroke)
|
||||
{
|
||||
oWriter.WriteString(L"<a:ln>"); // w - width по умолчанию 0.75pt = 9525
|
||||
oWriter.WriteString(L"<a:noFill/>");
|
||||
oWriter.WriteString(L"</a:ln>");
|
||||
}
|
||||
else
|
||||
{
|
||||
oWriter.WriteString(L"<a:ln w=\"");
|
||||
oWriter.AddInt(static_cast<int>(m_oPen.Size * c_dMMToEMU)); //note можно писать в мм
|
||||
oWriter.WriteString(L"\">");
|
||||
|
||||
oWriter.WriteString(L"<a:solidFill>");
|
||||
|
||||
oWriter.WriteString(L"<a:srgbClr val=\"");
|
||||
oWriter.WriteHexInt3(static_cast<int>(ConvertColorBGRToRGB(m_oPen.Color))); //note можно вместо цвета использовать слова типа "black"
|
||||
if (0xFF != m_oPen.Alpha)
|
||||
{
|
||||
oWriter.WriteString(L"\"><a:alpha val=\"");
|
||||
oWriter.AddInt(static_cast<int>(m_oPen.Alpha / 255.0 * 100.0));
|
||||
oWriter.WriteString(L"%\"/></a:srgbClr>");
|
||||
}
|
||||
else
|
||||
{
|
||||
oWriter.WriteString(L"\"/>");
|
||||
}
|
||||
|
||||
oWriter.WriteString(L"</a:solidFill>");
|
||||
oWriter.WriteString(L"</a:ln>");
|
||||
}
|
||||
|
||||
oWriter.WriteString(L"</wps:spPr>");
|
||||
|
||||
//не работает
|
||||
//oWriter.WriteString(L"<wps:style/>"); //shape styles. http://officeopenxml.com/drwSp-styles.php
|
||||
|
||||
if (!m_arParagraphs.empty())
|
||||
{
|
||||
oWriter.WriteString(L"<wps:txbx>"); //text within the shape. http://officeopenxml.com/drwSp-text.php
|
||||
oWriter.WriteString(L"<w:txbxContent>");
|
||||
for (auto pParagraph : m_arParagraphs)
|
||||
{
|
||||
pParagraph->ToXml(oWriter);
|
||||
}
|
||||
oWriter.WriteString(L"</w:txbxContent>");
|
||||
oWriter.WriteString(L"</wps:txbx>");
|
||||
}
|
||||
|
||||
oWriter.WriteString(L"<wps:bodyPr"); //определяет свойства тела текста внутри фигуры
|
||||
oWriter.WriteString(L" rot=\"0\""); //Определяет поворот, который применяется к тексту в пределах ограничивающей рамки.
|
||||
oWriter.WriteString(L" spcFirstLastPara=\"0\""); //должен ли соблюдаться интервал между абзацами до и после, заданный пользователем.
|
||||
oWriter.WriteString(L" vertOverflow=\"overflow\""); //может ли текст выходить за пределы ограничительной рамки по вертикали
|
||||
oWriter.WriteString(L" horzOverflow=\"overflow\""); //может ли текст выходить за пределы ограничительной рамки по горизонтали.
|
||||
oWriter.WriteString(L" vert=\"horz\"");
|
||||
//oWriter.WriteString(L" wrap=\"none\""); //граница шейпа по ширине текста
|
||||
oWriter.WriteString(L" wrap=\"square\""); //Определяет параметры обертки, которые будут использоваться для данного текстового тела.
|
||||
//на сколько граница текста отступает от границы шейпа
|
||||
oWriter.WriteString(L" lIns=\"0\""); //left по умолчанию 0.25см = 91440
|
||||
oWriter.WriteString(L" tIns=\"0\""); //top по умолчанию 0.13см = 45720
|
||||
oWriter.WriteString(L" rIns=\"0\""); //right по умолчанию 0.25см
|
||||
oWriter.WriteString(L" bIns=\"0\""); //bottom по умолчанию 0.13см
|
||||
oWriter.WriteString(L" numCol=\"1\""); //Определяет количество колонок текста в ограничивающем прямоугольнике.
|
||||
oWriter.WriteString(L" spcCol=\"0\""); //Определяет пространство между колонками текста в текстовой области (только если numCol >1)
|
||||
oWriter.WriteString(L" rtlCol=\"0\""); //используются ли столбцы в порядке справа налево (true) или слева направо (false).
|
||||
oWriter.WriteString(L" fromWordArt=\"0\""); //true/1 текст в этом текстовом поле является преобразованным текстом из объекта WordArt.
|
||||
oWriter.WriteString(L" anchor=\"t\""); //Вертикальное выравнивание текста в шейпе (t - top, b - bottom, ctr - middle) по умолчанию top
|
||||
oWriter.WriteString(L" anchorCtr=\"0\""); //true/1 Определяет центрирование текстового поля.
|
||||
oWriter.WriteString(L" forceAA=\"0\""); //true/1 Заставляет текст отображаться сглаженным независимо от размера шрифта.
|
||||
oWriter.WriteString(L" compatLnSpc=\"1\""); //межстрочный интервал для данного текста определяется упрощенным способом с помощью сцены шрифта.
|
||||
oWriter.WriteString(L">");
|
||||
|
||||
oWriter.WriteString(L"<a:prstTxWarp prst=\"textNoShape\">");
|
||||
oWriter.WriteString(L"<a:avLst/>");
|
||||
oWriter.WriteString(L"</a:prstTxWarp>");
|
||||
oWriter.WriteString(L"<a:noAutofit/>");
|
||||
oWriter.WriteString(L"</wps:bodyPr>");
|
||||
|
||||
oWriter.WriteString(L"</wps:wsp>");
|
||||
oWriter.WriteString(L"</a:graphicData>");
|
||||
oWriter.WriteString(L"</a:graphic>");
|
||||
oWriter.WriteString(L"</wp:anchor>");
|
||||
oWriter.WriteString(L"</w:drawing>");
|
||||
oWriter.WriteString(L"</mc:Choice>");
|
||||
|
||||
oWriter.WriteString(L"<mc:Fallback/>");
|
||||
//здесь можно вставить COldShape без <w:r>
|
||||
//
|
||||
//oWriter.WriteString(L"</mc:Fallback>");
|
||||
|
||||
oWriter.WriteString(L"</mc:AlternateContent>");
|
||||
oWriter.WriteString(L"</w:r>");
|
||||
}
|
||||
}; // namespace NSDocxRenderer
|
||||
@ -1,412 +1,65 @@
|
||||
#ifndef DOCX_RENDERER_ELEMENT_SHAPE_H
|
||||
#define DOCX_RENDERER_ELEMENT_SHAPE_H
|
||||
|
||||
#include "Common.h"
|
||||
#pragma once
|
||||
#include "ElementParagraph.h"
|
||||
#include "../resources/LinesTable.h"
|
||||
#include "../resources/VectorGraphics.h"
|
||||
|
||||
namespace NSDocxRenderer
|
||||
{
|
||||
class CVectorGraphics
|
||||
{
|
||||
public:
|
||||
double* m_pData;
|
||||
size_t m_lSize;
|
||||
enum class eGraphicsType
|
||||
{
|
||||
gtUnknown,
|
||||
gtRectangle,
|
||||
gtCurve,
|
||||
gtComplicatedFigure,
|
||||
gtNoGraphics,
|
||||
};
|
||||
|
||||
double* m_pDataCur;
|
||||
size_t m_lSizeCur;
|
||||
class CShape : public CBaseItem
|
||||
{
|
||||
public:
|
||||
std::wstring m_strPath {L""};
|
||||
NSStructures::CBrush m_oBrush;
|
||||
NSStructures::CPen m_oPen;
|
||||
|
||||
public:
|
||||
double m_dLeft;
|
||||
double m_dTop;
|
||||
double m_dRight;
|
||||
double m_dBottom;
|
||||
bool m_bIsNoFill {false};
|
||||
bool m_bIsNoStroke {false};
|
||||
bool m_bIsBehindDoc {true};
|
||||
|
||||
public:
|
||||
CVectorGraphics()
|
||||
{
|
||||
m_pData = NULL;
|
||||
m_lSize = 0;
|
||||
LONG m_lCoordSizeX {100000};
|
||||
LONG m_lCoordSizeY {100000};
|
||||
|
||||
m_pDataCur = m_pData;
|
||||
m_lSizeCur = m_lSize;
|
||||
LONG m_lTxId {-1};
|
||||
|
||||
End();
|
||||
}
|
||||
~CVectorGraphics()
|
||||
{
|
||||
RELEASEMEM(m_pData);
|
||||
}
|
||||
eGraphicsType m_eGraphicsType {eGraphicsType::gtUnknown};
|
||||
eSimpleLineType m_eSimpleLineType {eSimpleLineType::sltUnknown};
|
||||
eLineType m_eLineType {eLineType::ltUnknown};
|
||||
|
||||
inline void AddSize(size_t nSize)
|
||||
{
|
||||
if (NULL == m_pData)
|
||||
{
|
||||
m_lSize = std::max(nSize, (size_t)500);
|
||||
m_pData = (double*)malloc(m_lSize * sizeof(double));
|
||||
|
||||
m_lSizeCur = 0;
|
||||
m_pDataCur = m_pData;
|
||||
return;
|
||||
}
|
||||
std::vector<CParagraph*> m_arParagraphs;
|
||||
|
||||
if ((m_lSizeCur + nSize) > m_lSize)
|
||||
{
|
||||
while ((m_lSizeCur + nSize) > m_lSize)
|
||||
{
|
||||
m_lSize *= 2;
|
||||
}
|
||||
const CContText* m_pCont {nullptr};
|
||||
|
||||
double* pRealloc = (double*)realloc(m_pData, m_lSize * sizeof(double));
|
||||
if (NULL != pRealloc)
|
||||
{
|
||||
// реаллок сработал
|
||||
m_pData = pRealloc;
|
||||
m_pDataCur = m_pData + m_lSizeCur;
|
||||
}
|
||||
else
|
||||
{
|
||||
double* pMalloc = (double*)malloc(m_lSize * sizeof(double));
|
||||
memcpy(pMalloc, m_pData, m_lSizeCur * sizeof(double));
|
||||
public:
|
||||
CShape();
|
||||
virtual ~CShape();
|
||||
virtual void Clear() override final;
|
||||
|
||||
free(m_pData);
|
||||
m_pData = pMalloc;
|
||||
m_pDataCur = m_pData + m_lSizeCur;
|
||||
}
|
||||
}
|
||||
}
|
||||
CShape(const CShape& oSrc);
|
||||
//CShape(const CShape& oSrc1, const CShape& oSrc2);
|
||||
|
||||
public:
|
||||
inline void MoveTo(const double& x1, const double& y1)
|
||||
{
|
||||
AddSize(3);
|
||||
*m_pDataCur = 0; ++m_pDataCur;
|
||||
CShape& operator=(const CShape& oSrc);
|
||||
|
||||
*m_pDataCur = x1; ++m_pDataCur;
|
||||
*m_pDataCur = y1; ++m_pDataCur;
|
||||
void GetDataFromVector(const CVectorGraphics& oVector, const LONG& lType, const LONG& lCoordSize);
|
||||
|
||||
m_lSizeCur += 3;
|
||||
void WritePath(const CVectorGraphics& oVector);
|
||||
|
||||
CheckPoint(x1, y1);
|
||||
}
|
||||
inline void LineTo(const double& x1, const double& y1)
|
||||
{
|
||||
AddSize(3);
|
||||
*m_pDataCur = 1; ++m_pDataCur;
|
||||
void DetermineGraphicsType(const double& dWidth, const double& dHeight, const size_t& nPeacks, const size_t& nCurves);
|
||||
|
||||
*m_pDataCur = x1; ++m_pDataCur;
|
||||
*m_pDataCur = y1; ++m_pDataCur;
|
||||
bool IsItFitLine();
|
||||
bool IsCorrelated(const CShape* pShape);
|
||||
void ChangeGeometryOfDesiredShape(CShape* pShape);
|
||||
|
||||
m_lSizeCur += 3;
|
||||
void DetermineLineType(CShape* pShape = nullptr);
|
||||
|
||||
CheckPoint(x1, y1);
|
||||
}
|
||||
inline void CurveTo(const double& x1, const double& y1, const double& x2, const double& y2, const double& x3, const double& y3)
|
||||
{
|
||||
AddSize(7);
|
||||
*m_pDataCur = 2; ++m_pDataCur;
|
||||
|
||||
*m_pDataCur = x1; ++m_pDataCur;
|
||||
*m_pDataCur = y1; ++m_pDataCur;
|
||||
*m_pDataCur = x2; ++m_pDataCur;
|
||||
*m_pDataCur = y2; ++m_pDataCur;
|
||||
*m_pDataCur = x3; ++m_pDataCur;
|
||||
*m_pDataCur = y3; ++m_pDataCur;
|
||||
|
||||
m_lSizeCur += 7;
|
||||
|
||||
CheckPoint(x1, y1);
|
||||
CheckPoint(x2, y2);
|
||||
CheckPoint(x3, y3);
|
||||
}
|
||||
inline void Close()
|
||||
{
|
||||
AddSize(1);
|
||||
*m_pDataCur = 3; ++m_pDataCur;
|
||||
|
||||
m_lSizeCur += 1;
|
||||
}
|
||||
|
||||
inline size_t GetCurSize()
|
||||
{
|
||||
return m_lSizeCur;
|
||||
}
|
||||
|
||||
inline void Clear()
|
||||
{
|
||||
RELEASEMEM(m_pData);
|
||||
|
||||
m_pData = NULL;
|
||||
m_lSize = 0;
|
||||
|
||||
m_pDataCur = m_pData;
|
||||
m_lSizeCur = 0;
|
||||
}
|
||||
inline void ClearNoAttack()
|
||||
{
|
||||
m_pDataCur = m_pData;
|
||||
m_lSizeCur = 0;
|
||||
}
|
||||
|
||||
inline void End()
|
||||
{
|
||||
ClearNoAttack();
|
||||
|
||||
m_dLeft = 0xFFFFFF;
|
||||
m_dTop = 0xFFFFFF;
|
||||
m_dRight = -0xFFFFFF;
|
||||
m_dBottom = -0xFFFFFF;
|
||||
}
|
||||
|
||||
inline void CheckPoint(const double& x, const double& y)
|
||||
{
|
||||
if (m_dLeft > x)
|
||||
m_dLeft = x;
|
||||
if (m_dRight < x)
|
||||
m_dRight = x;
|
||||
if (m_dTop > y)
|
||||
m_dTop = y;
|
||||
if (m_dBottom < y)
|
||||
m_dBottom = y;
|
||||
}
|
||||
};
|
||||
|
||||
class CShape : public CBaseItem
|
||||
{
|
||||
public:
|
||||
std::wstring m_strPath;
|
||||
NSStructures::CBrush m_oBrush;
|
||||
NSStructures::CPen m_oPen;
|
||||
|
||||
double m_dLeft;
|
||||
double m_dTop;
|
||||
double m_dWidth;
|
||||
double m_dHeight;
|
||||
|
||||
bool m_bIsNoFill;
|
||||
bool m_bIsNoStroke;
|
||||
|
||||
LONG m_lCoordSizeX;
|
||||
LONG m_lCoordSizeY;
|
||||
|
||||
LONG m_lTxId;
|
||||
|
||||
public:
|
||||
CShape()
|
||||
{
|
||||
m_dLeft = 0;
|
||||
m_dTop = 0;
|
||||
m_dWidth = 0;
|
||||
m_dHeight = 0;
|
||||
|
||||
m_bIsNoFill = false;
|
||||
m_bIsNoStroke = false;
|
||||
|
||||
m_lCoordSizeX = 100000;
|
||||
m_lCoordSizeY = 100000;
|
||||
|
||||
m_lTxId = -1;
|
||||
}
|
||||
|
||||
CShape(const CShape& oSrc)
|
||||
{
|
||||
*this = oSrc;
|
||||
}
|
||||
|
||||
CShape& operator=(const CShape& oSrc)
|
||||
{
|
||||
m_eType = etShape;
|
||||
m_strPath = oSrc.m_strPath;
|
||||
|
||||
m_oBrush = oSrc.m_oBrush;
|
||||
m_oPen = oSrc.m_oPen;
|
||||
|
||||
m_dLeft = oSrc.m_dLeft;
|
||||
m_dTop = oSrc.m_dTop;
|
||||
m_dWidth = oSrc.m_dWidth;
|
||||
m_dHeight = oSrc.m_dHeight;
|
||||
|
||||
m_bIsNoFill = oSrc.m_bIsNoFill;
|
||||
m_bIsNoStroke = oSrc.m_bIsNoStroke;
|
||||
|
||||
m_lTxId = oSrc.m_lTxId;
|
||||
|
||||
return *this;
|
||||
}
|
||||
|
||||
void CreateFromVectorData(CVectorGraphics* pVector, NSStringUtils::CStringBuilder& oWriter, const LONG& lCoordSize, LONG lType)
|
||||
{
|
||||
m_dLeft = pVector->m_dLeft;
|
||||
m_dTop = pVector->m_dTop;
|
||||
m_dWidth = pVector->m_dRight - m_dLeft;
|
||||
m_dHeight = pVector->m_dBottom - m_dTop;
|
||||
|
||||
if (m_dWidth < 0.0001) m_dWidth = 0.0001;
|
||||
if (m_dHeight < 0.0001) m_dHeight = 0.0001;
|
||||
|
||||
m_lCoordSizeX = lCoordSize;
|
||||
m_lCoordSizeY = lCoordSize;
|
||||
|
||||
size_t nCount = pVector->GetCurSize();
|
||||
double* pData = pVector->m_pData;
|
||||
while (nCount > 0)
|
||||
{
|
||||
double dType = *pData++;
|
||||
if (0 == dType)
|
||||
{
|
||||
LONG lX = (LONG)((*pData - m_dLeft) * lCoordSize / m_dWidth);
|
||||
++pData;
|
||||
LONG lY = (LONG)((*pData - m_dTop) * lCoordSize / m_dHeight);
|
||||
++pData;
|
||||
|
||||
oWriter.AddCharSafe('m');
|
||||
oWriter.AddInt(lX);
|
||||
oWriter.AddCharSafe(',');
|
||||
oWriter.AddInt(lY);
|
||||
|
||||
nCount -= 3;
|
||||
}
|
||||
else if (1 == dType)
|
||||
{
|
||||
LONG lX = (LONG)((*pData - m_dLeft) * lCoordSize / m_dWidth);
|
||||
++pData;
|
||||
LONG lY = (LONG)((*pData - m_dTop) * lCoordSize / m_dHeight);
|
||||
++pData;
|
||||
|
||||
oWriter.AddCharSafe('l');
|
||||
oWriter.AddInt(lX);
|
||||
oWriter.AddCharSafe(',');
|
||||
oWriter.AddInt(lY);
|
||||
|
||||
nCount -= 3;
|
||||
}
|
||||
else if (2 == dType)
|
||||
{
|
||||
LONG lX1 = (LONG)((*pData - m_dLeft) * lCoordSize / m_dWidth);
|
||||
++pData;
|
||||
LONG lY1 = (LONG)((*pData - m_dTop) * lCoordSize / m_dHeight);
|
||||
++pData;
|
||||
|
||||
LONG lX2 = (LONG)((*pData - m_dLeft) * lCoordSize / m_dWidth);
|
||||
++pData;
|
||||
LONG lY2 = (LONG)((*pData - m_dTop) * lCoordSize / m_dHeight);
|
||||
++pData;
|
||||
|
||||
LONG lX3 = (LONG)((*pData - m_dLeft) * lCoordSize / m_dWidth);
|
||||
++pData;
|
||||
LONG lY3 = (LONG)((*pData - m_dTop) * lCoordSize / m_dHeight);
|
||||
++pData;
|
||||
|
||||
oWriter.AddCharSafe('c');
|
||||
oWriter.AddInt(lX1);
|
||||
oWriter.AddCharSafe(',');
|
||||
oWriter.AddInt(lY1);
|
||||
oWriter.AddCharSafe(',');
|
||||
oWriter.AddInt(lX2);
|
||||
oWriter.AddCharSafe(',');
|
||||
oWriter.AddInt(lY2);
|
||||
oWriter.AddCharSafe(',');
|
||||
oWriter.AddInt(lX3);
|
||||
oWriter.AddCharSafe(',');
|
||||
oWriter.AddInt(lY3);
|
||||
|
||||
nCount -= 7;
|
||||
}
|
||||
else
|
||||
{
|
||||
oWriter.AddCharSafe('x');
|
||||
--nCount;
|
||||
}
|
||||
}
|
||||
|
||||
if (0x00 == (lType & 0x01))
|
||||
{
|
||||
m_bIsNoStroke = true;
|
||||
oWriter.WriteString(L"ns");
|
||||
}
|
||||
if (0x00 == (lType >> 8))
|
||||
{
|
||||
m_bIsNoFill = true;
|
||||
oWriter.WriteString(L"nf");
|
||||
}
|
||||
|
||||
oWriter.AddCharSafe('e');
|
||||
|
||||
m_strPath = oWriter.GetData();
|
||||
oWriter.ClearNoAttack();
|
||||
}
|
||||
|
||||
virtual void ToXml(NSStringUtils::CStringBuilder& oWriter)
|
||||
{
|
||||
oWriter.WriteString(L"<w:r><w:pict><v:shape id=\"\" o:spid=\"\" style=\"position:absolute;");
|
||||
|
||||
oWriter.WriteString(L"margin-left:");
|
||||
oWriter.AddDouble(m_dLeft, 2);
|
||||
oWriter.WriteString(L"mm;margin-top:");
|
||||
oWriter.AddDouble(m_dTop, 2);
|
||||
oWriter.WriteString(L"mm;width:");
|
||||
oWriter.AddDouble(m_dWidth, 2);
|
||||
oWriter.WriteString(L"mm;height:");
|
||||
oWriter.AddDouble(m_dHeight, 2);
|
||||
oWriter.WriteString(L"mm;");
|
||||
|
||||
oWriter.WriteString(L"z-index:-1;mso-position-horizontal-relative:page;mso-position-vertical-relative:page;\"");
|
||||
|
||||
oWriter.WriteString(L" coordsize=\"");
|
||||
oWriter.AddInt((int)m_lCoordSizeX);
|
||||
oWriter.AddCharSafe(',');
|
||||
oWriter.AddInt((int)m_lCoordSizeY);
|
||||
oWriter.WriteString(L"\" path=\"");
|
||||
oWriter.WriteString(m_strPath);
|
||||
if (c_BrushTypeTexture == m_oBrush.Type)
|
||||
{
|
||||
// у нас нет таких шейпов в pdf/xps
|
||||
oWriter.WriteString(L"\" fillcolor=\"transparent");
|
||||
}
|
||||
else
|
||||
{
|
||||
oWriter.WriteString(L"\" fillcolor=\"#");
|
||||
oWriter.WriteHexInt3((int)ConvertColor(m_oBrush.Color1));
|
||||
}
|
||||
oWriter.WriteString(L"\" strokecolor=\"#");
|
||||
oWriter.WriteHexInt3((int)ConvertColor(m_oPen.Color));
|
||||
oWriter.WriteString(L"\" strokeweight=\"");
|
||||
oWriter.AddDouble(m_oPen.Size, 2);
|
||||
oWriter.WriteString(L"mm\">");
|
||||
|
||||
std::wstring g_string_fill_opacity = L"<v:fill opacity=\"%.2lf\"/>";
|
||||
std::wstring g_string_stroke_opacity = L"<v:stroke opacity=\"%.2lf\"/>";
|
||||
|
||||
if (c_BrushTypeTexture == m_oBrush.Type && !m_bIsNoFill)
|
||||
{
|
||||
oWriter.WriteString(L"<v:imagedata r:id=\"rId");
|
||||
oWriter.AddInt(10 + m_lTxId);
|
||||
oWriter.WriteString(L"\" o:title=\"\"/>");
|
||||
|
||||
if (0xFF != m_oBrush.TextureAlpha)
|
||||
{
|
||||
oWriter.WriteString(L"<v:fill opacity=\"");
|
||||
oWriter.AddDouble((double)m_oBrush.TextureAlpha / 255.0, 2);
|
||||
oWriter.WriteString(L"\"/>");
|
||||
}
|
||||
}
|
||||
else
|
||||
{
|
||||
if (0xFF != m_oBrush.Alpha1)
|
||||
{
|
||||
oWriter.WriteString(L"<v:fill opacity=\"");
|
||||
oWriter.AddDouble((double)m_oBrush.Alpha1 / 255.0, 2);
|
||||
oWriter.WriteString(L"\"/>");
|
||||
}
|
||||
if (0xFF != m_oPen.Alpha)
|
||||
{
|
||||
oWriter.WriteString(L"<v:stroke opacity=\"");
|
||||
oWriter.AddDouble((double)m_oPen.Alpha / 255.0, 2);
|
||||
oWriter.WriteString(L"\"/>");
|
||||
}
|
||||
}
|
||||
|
||||
oWriter.WriteString(L"<w10:wrap anchorx=\"page\" anchory=\"page\"/></v:shape></w:pict></w:r>");
|
||||
}
|
||||
};
|
||||
virtual void ToXml(NSStringUtils::CStringBuilder& oWriter) override final;
|
||||
};
|
||||
}
|
||||
|
||||
#endif // DOCX_RENDERER_ELEMENT_SHAPE_H
|
||||
|
||||
305
DocxRenderer/src/logic/ElementTextLine.cpp
Normal file
305
DocxRenderer/src/logic/ElementTextLine.cpp
Normal file
@ -0,0 +1,305 @@
|
||||
#include "ElementTextLine.h"
|
||||
#include "../resources/Constants.h"
|
||||
#include "../resources/SortElements.h"
|
||||
|
||||
namespace NSDocxRenderer
|
||||
{
|
||||
CTextLine::CTextLine() : CBaseItem(ElemType::etTextLine)
|
||||
{
|
||||
}
|
||||
|
||||
void CTextLine::Clear()
|
||||
{
|
||||
for (auto pCont : m_arConts)
|
||||
{
|
||||
RELEASEOBJECT(pCont);
|
||||
}
|
||||
m_arConts.clear();
|
||||
}
|
||||
|
||||
CTextLine::~CTextLine()
|
||||
{
|
||||
Clear();
|
||||
}
|
||||
|
||||
CTextLine::CTextLine(const CTextLine& oSrc) : CBaseItem(ElemType::etTextLine), m_arConts()
|
||||
{
|
||||
*this = oSrc;
|
||||
}
|
||||
|
||||
CTextLine& CTextLine::operator=(const CTextLine& oSrc)
|
||||
{
|
||||
if (this == &oSrc)
|
||||
{
|
||||
return *this;
|
||||
}
|
||||
|
||||
Clear();
|
||||
|
||||
CBaseItem::operator=(oSrc);
|
||||
|
||||
for (auto pCont : oSrc.m_arConts)
|
||||
{
|
||||
m_arConts.push_back(new CContText(*pCont));
|
||||
}
|
||||
|
||||
m_dBaselinePos = oSrc.m_dBaselinePos;
|
||||
m_dBaselineOffset = oSrc.m_dBaselineOffset;
|
||||
|
||||
m_eAlignmentType = oSrc.m_eAlignmentType;
|
||||
|
||||
m_pDominantShape = oSrc.m_pDominantShape;
|
||||
|
||||
return *this;
|
||||
}
|
||||
|
||||
void CTextLine::AddCont(CContText* pCont)
|
||||
{
|
||||
//if (0 == m_arConts.size())
|
||||
m_dBaselineOffset = fabs(m_dBaselineOffset) > fabs(pCont->m_dBaselineOffset) ? m_dBaselineOffset : pCont->m_dBaselineOffset;
|
||||
|
||||
if ( ( pCont->m_dLeft > 0 ) && ( ( m_dLeft == 0 ) || ( pCont->m_dLeft < m_dLeft ) ) )
|
||||
m_dLeft = pCont->m_dLeft;
|
||||
|
||||
if (m_dHeight < pCont->m_dHeight)
|
||||
m_dHeight = pCont->m_dHeight;
|
||||
|
||||
m_arConts.push_back(pCont);
|
||||
}
|
||||
|
||||
bool CTextLine::IsBigger(const CBaseItem* oSrc)
|
||||
{
|
||||
return (m_dBaselinePos > dynamic_cast<const CTextLine*>(oSrc)->m_dBaselinePos) ? true : false;
|
||||
}
|
||||
|
||||
bool CTextLine::IsBiggerOrEqual(const CBaseItem* oSrc)
|
||||
{
|
||||
return (m_dBaselinePos >= dynamic_cast<const CTextLine*>(oSrc)->m_dBaselinePos) ? true : false;
|
||||
}
|
||||
|
||||
void CTextLine::SortConts()
|
||||
{
|
||||
// сортировка непрерывных слов по m_dX
|
||||
SortElements(m_arConts);
|
||||
}
|
||||
|
||||
void CTextLine::Merge(CTextLine* pTextLine)
|
||||
{
|
||||
size_t nCount = pTextLine->m_arConts.size();
|
||||
if (0 != nCount)
|
||||
{
|
||||
if (pTextLine->m_dLeft < m_dLeft)
|
||||
{
|
||||
m_dLeft = pTextLine->m_dLeft;
|
||||
}
|
||||
if (pTextLine->m_dBaselinePos < m_dBaselinePos)
|
||||
{
|
||||
m_dHeight = (m_dBaselinePos - pTextLine->m_dBaselinePos + pTextLine->m_dHeight);
|
||||
}
|
||||
else
|
||||
{
|
||||
m_dHeight = (pTextLine->m_dBaselinePos - m_dBaselinePos + m_dHeight);
|
||||
}
|
||||
|
||||
for (size_t i = 0; i < nCount; ++i)
|
||||
{
|
||||
m_arConts.push_back(pTextLine->m_arConts[i]);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
void CTextLine::Analyze()
|
||||
{
|
||||
size_t nCountConts = m_arConts.size();
|
||||
|
||||
if (0 == nCountConts)
|
||||
return;
|
||||
|
||||
CContText* pFirst = m_arConts[0];
|
||||
|
||||
for (size_t i = 1; i < nCountConts; ++i)
|
||||
{
|
||||
CContText* pCurrent = m_arConts[i];
|
||||
|
||||
double dFirstRight = pFirst->m_dLeft + pFirst->m_dLeft;
|
||||
double dCurrLeft = pCurrent->m_dLeft;
|
||||
double dDelta = dFirstRight - dCurrLeft;
|
||||
|
||||
if (!pFirst->IsEqual(pCurrent) ||
|
||||
fabs(dDelta) > c_dTHE_STRING_X_PRECISION_MM)
|
||||
{
|
||||
if (i < nCountConts - 1)
|
||||
{
|
||||
//переходим на
|
||||
pFirst = pCurrent;
|
||||
}
|
||||
continue;
|
||||
}
|
||||
|
||||
// продолжаем слово
|
||||
pFirst->m_oText += pCurrent->m_oText;
|
||||
pFirst->m_dWidth += pCurrent->m_dWidth + fabs(dDelta);
|
||||
|
||||
m_arConts.erase(m_arConts.begin() + i);
|
||||
--i;
|
||||
--nCountConts;
|
||||
}
|
||||
}
|
||||
|
||||
void CTextLine::CalculateWidth()
|
||||
{
|
||||
m_dWidth = m_arConts[0]->m_dWidth;
|
||||
|
||||
for (size_t i = 1; i < m_arConts.size(); ++i)
|
||||
{
|
||||
m_dWidth += m_arConts[i]->m_dLeft - (m_arConts[i-1]->m_dLeft + m_arConts[i-1]->m_dWidth);
|
||||
m_dWidth += m_arConts[i]->m_dWidth;
|
||||
}
|
||||
}
|
||||
|
||||
void CTextLine::AddSpaceToEnd()
|
||||
{
|
||||
if (m_arConts.empty())
|
||||
{
|
||||
return;
|
||||
}
|
||||
|
||||
CContText* pCurrent = m_arConts.back();
|
||||
|
||||
if (pCurrent->m_oText[pCurrent->m_oText.length()-1] != uint32_t(' '))
|
||||
{
|
||||
pCurrent->AddSpaceToEnd();
|
||||
m_dWidth += pCurrent->m_dSpaceWidthMM;
|
||||
}
|
||||
}
|
||||
|
||||
void CTextLine::DetermineAssumedTextAlignmentType(double dWidthOfPage)
|
||||
{
|
||||
//рассматриваем строки, которые короче трети ширины страницы
|
||||
double maxTextLineWidth = dWidthOfPage/3; //нужна какая-нибудь отправная точка...
|
||||
double delta = 2 * c_dCENTER_POSITION_ERROR_MM; //координата m_dWidth/2 +- c_dCENTER_POSITION_ERROR_MM
|
||||
|
||||
if (fabs(dWidthOfPage/2 - m_dLeft - m_dWidth/2) <= delta && //если середины линий по x одинаковы
|
||||
m_dWidth < maxTextLineWidth )
|
||||
{
|
||||
m_eAlignmentType = atatByCenter;
|
||||
}
|
||||
else if ((m_dLeft + m_dWidth/2) > (dWidthOfPage/2 + c_dCENTER_POSITION_ERROR_MM) && //середина строки правее центра страницы
|
||||
m_dWidth < maxTextLineWidth)
|
||||
{
|
||||
m_eAlignmentType = atatByRightEdge;
|
||||
}
|
||||
else if ((m_dLeft + m_dWidth/2) < (dWidthOfPage/2 - c_dCENTER_POSITION_ERROR_MM) && //середина строки левее центра страницы
|
||||
m_dWidth < maxTextLineWidth)
|
||||
{
|
||||
m_eAlignmentType = atatByLeftEdge;
|
||||
}
|
||||
else if (fabs(dWidthOfPage/2 - m_dLeft - m_dWidth/2) <= delta &&
|
||||
m_dWidth > maxTextLineWidth + maxTextLineWidth/2 )
|
||||
{
|
||||
m_eAlignmentType = atatByWidth;
|
||||
}
|
||||
else
|
||||
{
|
||||
m_eAlignmentType = atatUnknown;
|
||||
}
|
||||
}
|
||||
|
||||
bool CTextLine::AreAlignmentsAppropriate(const CTextLine* oSrc)
|
||||
{
|
||||
if ((m_eAlignmentType == oSrc->m_eAlignmentType && m_eAlignmentType!= atatByLeftEdge) ||
|
||||
(m_eAlignmentType == atatByWidth && oSrc->m_eAlignmentType == atatByLeftEdge) ||
|
||||
(m_eAlignmentType == atatByWidth && oSrc->m_eAlignmentType == atatUnknown) ||
|
||||
(m_eAlignmentType == atatUnknown && oSrc->m_eAlignmentType == atatByWidth))
|
||||
{
|
||||
return true;
|
||||
}
|
||||
return false;
|
||||
}
|
||||
|
||||
bool CTextLine::AreLinesCrossing(const CTextLine* oSrc)
|
||||
{
|
||||
double dCurrentTop = m_dBaselinePos - m_dHeight - m_dBaselineOffset;
|
||||
double dNextTop = oSrc->m_dBaselinePos - oSrc->m_dHeight - oSrc->m_dBaselineOffset;
|
||||
|
||||
if ((oSrc->m_dBaselinePos < m_dBaselinePos && dCurrentTop < oSrc->m_dBaselinePos) ||
|
||||
(oSrc->m_dBaselinePos > m_dBaselinePos && dNextTop < m_dBaselinePos))
|
||||
{
|
||||
return true;
|
||||
}
|
||||
return false;
|
||||
}
|
||||
|
||||
double CTextLine::CalculateBeforeSpacing(const double* pPreviousStringOffset)
|
||||
{
|
||||
return m_dBaselinePos - *pPreviousStringOffset - m_dHeight - m_dBaselineOffset;
|
||||
}
|
||||
|
||||
double CTextLine::CalculateStringOffset()
|
||||
{
|
||||
return m_dBaselinePos - m_dBaselineOffset;
|
||||
}
|
||||
|
||||
double CTextLine::CalculateRightBorder(const double& dPageWidth)
|
||||
{
|
||||
return dPageWidth - (m_dLeft + m_dWidth);
|
||||
}
|
||||
|
||||
bool CTextLine::IsForceBlock()
|
||||
{
|
||||
// линия отсортирована, так что сравниваем только соседние conts
|
||||
size_t nCount = m_arConts.size();
|
||||
if (nCount <= 1)
|
||||
return false;
|
||||
|
||||
for (size_t i = 0; i < nCount; i++)
|
||||
{
|
||||
for (size_t j = i + 1; j < nCount; j++)
|
||||
{
|
||||
if (m_arConts[i]->GetIntersect(m_arConts[j]) > 10)
|
||||
return true;
|
||||
}
|
||||
}
|
||||
return false;
|
||||
}
|
||||
|
||||
void CTextLine::ToXml(NSStringUtils::CStringBuilder& oWriter)
|
||||
{
|
||||
size_t nCountConts = m_arConts.size();
|
||||
|
||||
if (0 == nCountConts)
|
||||
return;
|
||||
|
||||
CContText* pPrev = m_arConts[0];
|
||||
double dDelta = 0;
|
||||
|
||||
for (size_t i = 1; i < nCountConts; ++i)
|
||||
{
|
||||
CContText* pCurrent = m_arConts[i];
|
||||
|
||||
dDelta = pCurrent->m_dLeft - (pPrev->m_dLeft + pPrev->m_dWidth);
|
||||
|
||||
if (dDelta < c_dTHE_STRING_X_PRECISION_MM)
|
||||
{
|
||||
// просто текст на тексте или сменились настройки (font/brush)
|
||||
pPrev->ToXml(oWriter);
|
||||
pPrev = pCurrent;
|
||||
}
|
||||
//else if (dDelta < 2 * pPrev->m_dSpaceWidthMM)
|
||||
//{
|
||||
// // сменились настройки, но пробел все-таки вставить нужно
|
||||
// pPrev->Write(oWriter, pManagerLight, true);
|
||||
// pPrev = pCurrent;
|
||||
//}
|
||||
else
|
||||
{
|
||||
// расстояние слишком большое. нужно сделать большой пробел
|
||||
pPrev->ToXml(oWriter);
|
||||
pPrev->AddWideSpaceToXml(dDelta, oWriter, pPrev->IsEqual(pCurrent));
|
||||
pPrev = pCurrent;
|
||||
}
|
||||
}
|
||||
|
||||
pPrev->ToXml(oWriter);
|
||||
}
|
||||
}
|
||||
64
DocxRenderer/src/logic/ElementTextLine.h
Normal file
64
DocxRenderer/src/logic/ElementTextLine.h
Normal file
@ -0,0 +1,64 @@
|
||||
#pragma once
|
||||
#include "ElementContText.h"
|
||||
|
||||
namespace NSDocxRenderer
|
||||
{
|
||||
class CTextLine : public CBaseItem
|
||||
{
|
||||
public:
|
||||
enum AssumedTextAlignmentType
|
||||
{
|
||||
atatUnknown,
|
||||
atatByLeftEdge,
|
||||
atatByCenter,
|
||||
atatByRightEdge,
|
||||
atatByWidth
|
||||
};
|
||||
|
||||
std::vector<CContText*> m_arConts;
|
||||
|
||||
double m_dBaselinePos {0.0};
|
||||
double m_dBaselineOffset {0.0};
|
||||
|
||||
AssumedTextAlignmentType m_eAlignmentType {atatUnknown};
|
||||
|
||||
const CShape* m_pDominantShape {nullptr};
|
||||
|
||||
public:
|
||||
CTextLine();
|
||||
void Clear() override final;
|
||||
|
||||
~CTextLine();
|
||||
|
||||
CTextLine(const CTextLine& oSrc);
|
||||
CTextLine& operator=(const CTextLine& oSrc);
|
||||
|
||||
void AddCont(CContText* pCont);
|
||||
bool IsBigger(const CBaseItem* oSrc) override final;
|
||||
bool IsBiggerOrEqual(const CBaseItem* oSrc) override final;
|
||||
void SortConts();
|
||||
|
||||
//Объединяем слова из двух строк
|
||||
void Merge(CTextLine* pTextLine);
|
||||
//Объединяем подходящие слова в текущей строке, если возможно
|
||||
void Analyze();
|
||||
bool IsForceBlock();
|
||||
void ToXml(NSStringUtils::CStringBuilder& oWriter) override final;
|
||||
|
||||
//Вычисляем ширину сложной строки
|
||||
void CalculateWidth();
|
||||
//Добавляем символ пробела в конец строки для связывания строк в параграфе
|
||||
void AddSpaceToEnd();
|
||||
//Пытаемся понять тип выравнивания для текущей строки
|
||||
void DetermineAssumedTextAlignmentType(double dWidthOfPage);
|
||||
//Определяем на основании выравнивания подходят ли текущая и следующая строки для добавления в параграф
|
||||
bool AreAlignmentsAppropriate(const CTextLine* oSrc);
|
||||
//Определяем пересекаются ли линии
|
||||
bool AreLinesCrossing(const CTextLine* oSrc);
|
||||
|
||||
//Вычисляем
|
||||
double CalculateBeforeSpacing(const double* pPreviousStringOffset);
|
||||
double CalculateStringOffset();
|
||||
double CalculateRightBorder(const double& dPageWidth);
|
||||
};
|
||||
}
|
||||
261
DocxRenderer/src/logic/FontManager.cpp
Normal file
261
DocxRenderer/src/logic/FontManager.cpp
Normal file
@ -0,0 +1,261 @@
|
||||
#include "FontManager.h"
|
||||
#include "../resources/Constants.h"
|
||||
|
||||
namespace NSDocxRenderer
|
||||
{
|
||||
CFontTableEntry::CFontTableEntry(const CFontTableEntry& oSrc)
|
||||
{
|
||||
*this = oSrc;
|
||||
}
|
||||
|
||||
CFontTableEntry& CFontTableEntry::operator =(const CFontTableEntry& oSrc)
|
||||
{
|
||||
if (this == &oSrc)
|
||||
{
|
||||
return *this;
|
||||
}
|
||||
|
||||
m_strFamilyName = oSrc.m_strFamilyName;
|
||||
m_strPANOSE = oSrc.m_strPANOSE;
|
||||
m_lStyle = oSrc.m_lStyle;
|
||||
m_arSignature = oSrc.m_arSignature;
|
||||
m_bIsFixedWidth = oSrc.m_bIsFixedWidth;
|
||||
|
||||
return *this;
|
||||
}
|
||||
|
||||
CFontManager::CFontManager(NSFonts::IApplicationFonts* pFonts) : CFontManagerBase(pFonts)
|
||||
{
|
||||
}
|
||||
|
||||
void CFontManager::Init()
|
||||
{
|
||||
m_oFontTable.m_mapTable.clear();
|
||||
}
|
||||
|
||||
void CFontManager::AddFontToMap()
|
||||
{
|
||||
if (m_oFontTable.m_mapTable.end() != m_oFontTable.m_mapTable.find(m_oFont.m_strFamilyName))
|
||||
{
|
||||
CFontTableEntry oEntry;
|
||||
oEntry.m_strFamilyName = m_oFont.m_strFamilyName;
|
||||
oEntry.m_strPANOSE = m_oFont.m_strPANOSE;
|
||||
oEntry.m_lStyle = m_oFont.m_lStyle;
|
||||
oEntry.m_bIsFixedWidth = m_oFont.m_bIsFixedWidth;
|
||||
oEntry.m_arSignature = m_oFont.m_arSignature;
|
||||
|
||||
m_oFontTable.m_mapTable.insert(std::pair<std::wstring, CFontTableEntry>(m_oFont.m_strFamilyName, oEntry));
|
||||
}
|
||||
}
|
||||
|
||||
void CFontManager::LoadFont(long lFaceIndex, bool bNeedAddToMap)
|
||||
{
|
||||
if (nullptr == m_pManager)
|
||||
return;
|
||||
|
||||
double dSize = m_pFont->Size;
|
||||
double dSizeFont = dSize * ((m_pTransform->sx() + m_pTransform->sy()) / 2);
|
||||
|
||||
double dPix = m_pFont->CharSpace / c_dPixToMM;
|
||||
|
||||
m_pFont->Size = dSizeFont;
|
||||
|
||||
if (m_pFont->IsEqual2(&m_oFont.m_oFont))
|
||||
{
|
||||
m_pFont->Size = dSize;
|
||||
m_pManager->SetCharSpacing(dPix);
|
||||
return;
|
||||
}
|
||||
|
||||
m_oFont.m_oFont = *m_pFont;
|
||||
m_pFont->Size = dSize;
|
||||
|
||||
bool bIsPath = false;
|
||||
|
||||
if (m_pFont->Path.empty())
|
||||
{
|
||||
CFontManagerBase::LoadFontByName(m_oFont.m_oFont.Name, m_oFont.m_oFont.Size, m_oFont.m_oFont.GetStyle(), c_dDpiX, c_dDpiY);
|
||||
}
|
||||
else
|
||||
{
|
||||
CFontManagerBase::LoadFontByFile(m_oFont.m_oFont.Path, m_oFont.m_oFont.Size, c_dDpiX, c_dDpiY, lFaceIndex);
|
||||
|
||||
m_pFont->SetStyle(m_oFont.m_lStyle);
|
||||
m_oFont.m_oFont.SetStyle(m_oFont.m_lStyle);
|
||||
|
||||
bIsPath = true;
|
||||
}
|
||||
|
||||
int bIsGID = m_pManager->GetStringGID();
|
||||
m_pManager->SetStringGID(FALSE);
|
||||
|
||||
m_pManager->LoadString2(L" ", 0, 0);
|
||||
TBBox bbox = m_pManager->MeasureString2();
|
||||
|
||||
m_dSpaceWidthMM = (double)(bbox.fMaxX - bbox.fMinX) * c_dPixToMM;
|
||||
if (0 >= m_dSpaceWidthMM)
|
||||
{
|
||||
m_dSpaceWidthMM = 1.0;
|
||||
}
|
||||
|
||||
m_pManager->SetStringGID(bIsGID);
|
||||
|
||||
if (bNeedAddToMap)
|
||||
AddFontToMap();
|
||||
}
|
||||
|
||||
void CFontManager::MeasureString(std::wstring sText, double x, double y, double& dBoxX, double& dBoxY, double& dBoxWidth, double& dBoxHeight, MeasureType measureType)
|
||||
{
|
||||
LoadFont();
|
||||
|
||||
dBoxX = 0;
|
||||
dBoxY = 0;
|
||||
dBoxWidth = 0;
|
||||
dBoxHeight = 0;
|
||||
|
||||
if (nullptr == m_pManager)
|
||||
return;
|
||||
|
||||
m_pManager->LoadString1(sText, (float)x, (float)y);
|
||||
|
||||
TBBox bbox;
|
||||
if (mtGlyph == measureType)
|
||||
{
|
||||
bbox = m_pManager->MeasureString();
|
||||
}
|
||||
else if (mtPosition == measureType)
|
||||
{
|
||||
bbox = m_pManager->MeasureString2();
|
||||
}
|
||||
|
||||
dBoxX = (double)bbox.fMinX;
|
||||
dBoxY = (double)bbox.fMinY;
|
||||
dBoxWidth = (double)(bbox.fMaxX - bbox.fMinX);
|
||||
dBoxHeight = (double)(bbox.fMaxY - bbox.fMinY);
|
||||
|
||||
// переводим в миллиметры
|
||||
dBoxX *= c_dPixToMM;
|
||||
dBoxY *= c_dPixToMM;
|
||||
dBoxWidth *= c_dPixToMM;
|
||||
dBoxHeight *= c_dPixToMM;
|
||||
}
|
||||
|
||||
void CFontManager::MeasureStringGids(unsigned int* pGids, unsigned int count, double x, double y, double& dBoxX, double& dBoxY, double& dBoxWidth, double& dBoxHeight, MeasureType measureType)
|
||||
{
|
||||
LoadFont();
|
||||
|
||||
dBoxX = 0;
|
||||
dBoxY = 0;
|
||||
dBoxWidth = 0;
|
||||
dBoxHeight = 0;
|
||||
|
||||
if (nullptr == m_pManager)
|
||||
return;
|
||||
|
||||
m_pManager->LoadString1(pGids, count, (float)x, (float)y);
|
||||
|
||||
TBBox bbox;
|
||||
if (mtGlyph == measureType)
|
||||
{
|
||||
bbox = m_pManager->MeasureString();
|
||||
}
|
||||
else if (mtPosition == measureType)
|
||||
{
|
||||
bbox = m_pManager->MeasureString2();
|
||||
}
|
||||
|
||||
dBoxX = (double)bbox.fMinX;
|
||||
dBoxY = (double)bbox.fMinY;
|
||||
dBoxWidth = (double)(bbox.fMaxX - bbox.fMinX);
|
||||
dBoxHeight = (double)(bbox.fMaxY - bbox.fMinY);
|
||||
|
||||
// переводим в миллиметры
|
||||
dBoxX *= c_dPixToMM;
|
||||
dBoxY *= c_dPixToMM;
|
||||
dBoxWidth *= c_dPixToMM;
|
||||
dBoxHeight *= c_dPixToMM;
|
||||
}
|
||||
|
||||
double CFontManager::GetBaseLineOffset()
|
||||
{
|
||||
LoadFont();
|
||||
|
||||
double d1 = 3 * (m_oFont.m_dLineSpacing - m_oFont.m_dDescent) - m_oFont.m_dAscent;
|
||||
d1 /= 2.0;
|
||||
|
||||
d1 *= (m_oFont.m_oFont.Size / m_oFont.m_dEmHeight);
|
||||
return d1;
|
||||
}
|
||||
|
||||
double CFontManager::GetFontHeight()
|
||||
{
|
||||
return c_dPtToMM * (m_oFont.m_dLineSpacing * m_oFont.m_oFont.Size ) / m_oFont.m_dEmHeight;
|
||||
}
|
||||
|
||||
void CFontManager::SetStringGid(const LONG& lGid)
|
||||
{
|
||||
if (nullptr != m_pManager)
|
||||
m_pManager->SetStringGID(lGid);
|
||||
}
|
||||
|
||||
void CFontManager::GenerateFontName2(NSStringUtils::CStringUTF32& oText)
|
||||
{
|
||||
bool bIsNeedAddToMap = CFontManagerBase::GenerateFontName(oText);
|
||||
|
||||
if (bIsNeedAddToMap)
|
||||
{
|
||||
if (m_oFontTable.m_mapTable.end() != m_oFontTable.m_mapTable.find(m_strCurrentPickFont))
|
||||
{
|
||||
CFontTableEntry oEntry;
|
||||
oEntry.m_strFamilyName = m_strCurrentPickFont;
|
||||
oEntry.m_strPANOSE = m_oFont.m_strPANOSE;
|
||||
oEntry.m_lStyle = m_oFont.m_lStyle;
|
||||
oEntry.m_bIsFixedWidth = m_oFont.m_bIsFixedWidth;
|
||||
oEntry.m_arSignature = m_oFont.m_arSignature;
|
||||
|
||||
m_oFontTable.m_mapTable.insert(std::pair<std::wstring, CFontTableEntry>(m_oFont.m_strFamilyName, oEntry));
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
CFontManagerLight::CFontManagerLight(NSFonts::IApplicationFonts* pFonts)
|
||||
{
|
||||
m_pManager = NSFontManager::CreateFontManager(pFonts);
|
||||
}
|
||||
|
||||
CFontManagerLight::~CFontManagerLight()
|
||||
{
|
||||
RELEASEINTERFACE(m_pManager);
|
||||
}
|
||||
|
||||
double CFontManagerLight::GetSpaceWidth()
|
||||
{
|
||||
return m_dSpaceWidth;
|
||||
}
|
||||
|
||||
void CFontManagerLight::LoadFont(std::wstring& strFontName, LONG& lStyle, double& dSize, const bool& bIsGID)
|
||||
{
|
||||
if ((strFontName == m_strFontName) && (lStyle == m_lFontStyle) && (dSize == m_dSize))
|
||||
{
|
||||
m_pManager->SetStringGID(bIsGID);
|
||||
return;
|
||||
}
|
||||
|
||||
m_strFontName = strFontName;
|
||||
m_lFontStyle = lStyle;
|
||||
m_dSize = dSize;
|
||||
|
||||
m_pManager->LoadFontByName(strFontName, (float)m_dSize, m_lFontStyle, c_dDpiX, c_dDpiY);
|
||||
m_dSpaceWidth = MeasureStringWidth(L" ");
|
||||
|
||||
m_pManager->SetStringGID(bIsGID);
|
||||
}
|
||||
|
||||
double CFontManagerLight::MeasureStringWidth(const std::wstring& sText)
|
||||
{
|
||||
m_pManager->LoadString2(sText, (float)0, (float)0);
|
||||
TBBox bbox = m_pManager->MeasureString2();
|
||||
|
||||
return (bbox.fMaxX - bbox.fMinX) * c_dPixToMM;
|
||||
}
|
||||
}
|
||||
@ -1,330 +1,96 @@
|
||||
#pragma once
|
||||
#include "Common.h"
|
||||
#include "FontManagerBase.h"
|
||||
#include "../../DocxRenderer.h"
|
||||
#include "../DesktopEditor/graphics/Matrix.h"
|
||||
|
||||
namespace NSDocxRenderer
|
||||
{
|
||||
using namespace NSFontManager;
|
||||
using namespace NSFontManager;
|
||||
|
||||
const double c_dDpiX = 72.0;
|
||||
const double c_dDpiY = 72.0;
|
||||
class CFontTableEntry
|
||||
{
|
||||
public:
|
||||
std::wstring m_strFamilyName {L""};
|
||||
std::wstring m_strPANOSE {L""};
|
||||
LONG m_lStyle {0};
|
||||
std::vector<UINT> m_arSignature;
|
||||
bool m_bIsFixedWidth {false};
|
||||
|
||||
class CFontTableEntry
|
||||
{
|
||||
public:
|
||||
std::wstring m_strFamilyName;
|
||||
std::wstring m_strPANOSE;
|
||||
LONG m_lStyle;
|
||||
std::vector<UINT> m_arSignature;
|
||||
bool m_bIsFixedWidth;
|
||||
public:
|
||||
CFontTableEntry(){}
|
||||
virtual ~CFontTableEntry(){}
|
||||
|
||||
public:
|
||||
CFontTableEntry() : m_arSignature()
|
||||
{
|
||||
m_strFamilyName = L"";
|
||||
m_strPANOSE = L"";
|
||||
m_lStyle = 0;
|
||||
m_bIsFixedWidth = false;
|
||||
}
|
||||
~CFontTableEntry()
|
||||
{
|
||||
}
|
||||
CFontTableEntry(const CFontTableEntry& oSrc)
|
||||
{
|
||||
*this = oSrc;
|
||||
}
|
||||
CFontTableEntry& operator =(const CFontTableEntry& oSrc)
|
||||
{
|
||||
m_strFamilyName = oSrc.m_strFamilyName;
|
||||
m_strPANOSE = oSrc.m_strPANOSE;
|
||||
m_lStyle = oSrc.m_lStyle;
|
||||
m_arSignature = oSrc.m_arSignature;
|
||||
m_bIsFixedWidth = oSrc.m_bIsFixedWidth;
|
||||
CFontTableEntry(const CFontTableEntry& oSrc);
|
||||
|
||||
return *this;
|
||||
}
|
||||
};
|
||||
CFontTableEntry& operator =(const CFontTableEntry& oSrc);
|
||||
};
|
||||
|
||||
class CFontTable
|
||||
{
|
||||
public:
|
||||
std::map<std::wstring, CFontTableEntry> m_mapTable;
|
||||
class CFontTable
|
||||
{
|
||||
public:
|
||||
std::map<std::wstring, CFontTableEntry> m_mapTable;
|
||||
|
||||
public:
|
||||
CFontTable() : m_mapTable()
|
||||
{
|
||||
}
|
||||
};
|
||||
public:
|
||||
CFontTable() : m_mapTable(){}
|
||||
};
|
||||
|
||||
class CFontManager : public CFontManagerBase
|
||||
{
|
||||
public:
|
||||
NSStructures::CFont* m_pFont;
|
||||
Aggplus::CMatrix* m_pTransform;
|
||||
double m_dSpaceWidthMM;
|
||||
class CFontManager : public CFontManagerBase
|
||||
{
|
||||
public:
|
||||
NSStructures::CFont* m_pFont {nullptr};
|
||||
Aggplus::CMatrix* m_pTransform {nullptr};
|
||||
double m_dSpaceWidthMM {0.0};
|
||||
|
||||
public:
|
||||
CFontTable m_oFontTable;
|
||||
public:
|
||||
CFontTable m_oFontTable;
|
||||
|
||||
public:
|
||||
CFontManager(NSFonts::IApplicationFonts* pFonts) : m_pFont(NULL), CFontManagerBase(pFonts)
|
||||
{
|
||||
m_pTransform = NULL;
|
||||
m_dSpaceWidthMM = 0;
|
||||
}
|
||||
virtual ~CFontManager()
|
||||
{
|
||||
}
|
||||
public:
|
||||
CFontManager(NSFonts::IApplicationFonts* pFonts);
|
||||
virtual ~CFontManager(){}
|
||||
|
||||
public:
|
||||
void Init()
|
||||
{
|
||||
m_oFontTable.m_mapTable.clear();
|
||||
}
|
||||
void AddFontToMap()
|
||||
{
|
||||
if (m_oFontTable.m_mapTable.end() != m_oFontTable.m_mapTable.find(m_oFont.m_strFamilyName))
|
||||
{
|
||||
CFontTableEntry oEntry;
|
||||
oEntry.m_strFamilyName = m_oFont.m_strFamilyName;
|
||||
oEntry.m_strPANOSE = m_oFont.m_strPANOSE;
|
||||
oEntry.m_lStyle = m_oFont.m_lStyle;
|
||||
oEntry.m_bIsFixedWidth = m_oFont.m_bIsFixedWidth;
|
||||
oEntry.m_arSignature = m_oFont.m_arSignature;
|
||||
public:
|
||||
void Init();
|
||||
|
||||
m_oFontTable.m_mapTable.insert(std::pair<std::wstring, CFontTableEntry>(m_oFont.m_strFamilyName, oEntry));
|
||||
}
|
||||
}
|
||||
void AddFontToMap();
|
||||
|
||||
public:
|
||||
virtual void LoadFont(long lFaceIndex = 0, bool bNeedAddToMap = true)
|
||||
{
|
||||
if (NULL == m_pManager)
|
||||
return;
|
||||
public:
|
||||
virtual void LoadFont(long lFaceIndex = 0, bool bNeedAddToMap = true);
|
||||
|
||||
double dSize = m_pFont->Size;
|
||||
double dSizeFont = dSize * ((m_pTransform->sx() + m_pTransform->sy()) / 2);
|
||||
void MeasureString(std::wstring sText, double x, double y, double& dBoxX, double& dBoxY,
|
||||
double& dBoxWidth, double& dBoxHeight, MeasureType measureType);
|
||||
|
||||
double dPix = m_pFont->CharSpace / c_dPixToMM;
|
||||
void MeasureStringGids(unsigned int* pGids, unsigned int count, double x, double y,
|
||||
double& dBoxX, double& dBoxY, double& dBoxWidth, double& dBoxHeight, MeasureType measureType);
|
||||
|
||||
m_pFont->Size = dSizeFont;
|
||||
double GetBaseLineOffset();
|
||||
|
||||
if (m_pFont->IsEqual2(&m_oFont.m_oFont))
|
||||
{
|
||||
m_pFont->Size = dSize;
|
||||
m_pManager->SetCharSpacing(dPix);
|
||||
return;
|
||||
}
|
||||
double GetFontHeight();
|
||||
|
||||
m_oFont.m_oFont = *m_pFont;
|
||||
m_pFont->Size = dSize;
|
||||
void SetStringGid(const LONG& lGid);
|
||||
|
||||
bool bIsPath = false;
|
||||
void GenerateFontName2(NSStringUtils::CStringUTF32& oText);
|
||||
};
|
||||
|
||||
if (m_pFont->Path.empty())
|
||||
{
|
||||
CFontManagerBase::LoadFontByName(m_oFont.m_oFont.Name, m_oFont.m_oFont.Size, m_oFont.m_oFont.GetStyle(), c_dDpiX, c_dDpiY);
|
||||
}
|
||||
else
|
||||
{
|
||||
CFontManagerBase::LoadFontByFile(m_oFont.m_oFont.Path, m_oFont.m_oFont.Size, c_dDpiX, c_dDpiY, lFaceIndex);
|
||||
class CFontManagerLight
|
||||
{
|
||||
private:
|
||||
std::wstring m_strFontName {L""};
|
||||
LONG m_lFontStyle {0};
|
||||
double m_dSize {0.0};
|
||||
|
||||
m_pFont->SetStyle(m_oFont.m_lStyle);
|
||||
m_oFont.m_oFont.SetStyle(m_oFont.m_lStyle);
|
||||
double m_dSpaceWidth {0.0};
|
||||
|
||||
bIsPath = true;
|
||||
}
|
||||
NSFonts::IFontManager* m_pManager {nullptr};
|
||||
|
||||
int bIsGID = m_pManager->GetStringGID();
|
||||
m_pManager->SetStringGID(FALSE);
|
||||
|
||||
m_pManager->LoadString2(L" ", 0, 0);
|
||||
TBBox bbox = m_pManager->MeasureString2();
|
||||
public:
|
||||
CFontManagerLight(NSFonts::IApplicationFonts* pFonts);
|
||||
virtual ~CFontManagerLight();
|
||||
|
||||
m_dSpaceWidthMM = (double)(bbox.fMaxX - bbox.fMinX) * c_dPixToMM;
|
||||
if (0 >= m_dSpaceWidthMM)
|
||||
{
|
||||
m_dSpaceWidthMM = 1.0;
|
||||
}
|
||||
double GetSpaceWidth();
|
||||
|
||||
m_pManager->SetStringGID(bIsGID);
|
||||
public:
|
||||
void LoadFont(std::wstring& strFontName, LONG& lStyle, double& dSize, const bool& bIsGID);
|
||||
|
||||
if (bNeedAddToMap)
|
||||
AddFontToMap();
|
||||
}
|
||||
|
||||
void MeasureString(std::wstring sText, double x, double y, double& dBoxX, double& dBoxY, double& dBoxWidth, double& dBoxHeight, MeasureType measureType)
|
||||
{
|
||||
LoadFont();
|
||||
|
||||
dBoxX = 0;
|
||||
dBoxY = 0;
|
||||
dBoxWidth = 0;
|
||||
dBoxHeight = 0;
|
||||
|
||||
if (NULL == m_pManager)
|
||||
return;
|
||||
|
||||
m_pManager->LoadString1(sText, (float)x, (float)y);
|
||||
|
||||
TBBox bbox;
|
||||
if (MeasureTypeGlyph == measureType)
|
||||
{
|
||||
bbox = m_pManager->MeasureString();
|
||||
}
|
||||
else if (MeasureTypePosition == measureType)
|
||||
{
|
||||
bbox = m_pManager->MeasureString2();
|
||||
}
|
||||
|
||||
dBoxX = (double)bbox.fMinX;
|
||||
dBoxY = (double)bbox.fMinY;
|
||||
dBoxWidth = (double)(bbox.fMaxX - bbox.fMinX);
|
||||
dBoxHeight = (double)(bbox.fMaxY - bbox.fMinY);
|
||||
|
||||
// переводим в миллиметры
|
||||
dBoxX *= c_dPixToMM;
|
||||
dBoxY *= c_dPixToMM;
|
||||
dBoxWidth *= c_dPixToMM;
|
||||
dBoxHeight *= c_dPixToMM;
|
||||
}
|
||||
void MeasureStringGids(unsigned int* pGids, unsigned int count, double x, double y, double& dBoxX, double& dBoxY, double& dBoxWidth, double& dBoxHeight, MeasureType measureType)
|
||||
{
|
||||
LoadFont();
|
||||
|
||||
dBoxX = 0;
|
||||
dBoxY = 0;
|
||||
dBoxWidth = 0;
|
||||
dBoxHeight = 0;
|
||||
|
||||
if (NULL == m_pManager)
|
||||
return;
|
||||
|
||||
m_pManager->LoadString1(pGids, count, (float)x, (float)y);
|
||||
|
||||
TBBox bbox;
|
||||
if (MeasureTypeGlyph == measureType)
|
||||
{
|
||||
bbox = m_pManager->MeasureString();
|
||||
}
|
||||
else if (MeasureTypePosition == measureType)
|
||||
{
|
||||
bbox = m_pManager->MeasureString2();
|
||||
}
|
||||
|
||||
dBoxX = (double)bbox.fMinX;
|
||||
dBoxY = (double)bbox.fMinY;
|
||||
dBoxWidth = (double)(bbox.fMaxX - bbox.fMinX);
|
||||
dBoxHeight = (double)(bbox.fMaxY - bbox.fMinY);
|
||||
|
||||
// переводим в миллиметры
|
||||
dBoxX *= c_dPixToMM;
|
||||
dBoxY *= c_dPixToMM;
|
||||
dBoxWidth *= c_dPixToMM;
|
||||
dBoxHeight *= c_dPixToMM;
|
||||
}
|
||||
|
||||
inline double GetBaseLineOffset()
|
||||
{
|
||||
LoadFont();
|
||||
|
||||
double d1 = 3 * (m_oFont.m_dLineSpacing - m_oFont.m_dDescent) - m_oFont.m_dAscent;
|
||||
d1 /= 2.0;
|
||||
|
||||
d1 *= (m_oFont.m_oFont.Size / m_oFont.m_dEmHeight);
|
||||
return d1;
|
||||
}
|
||||
|
||||
inline double GetFontHeight()
|
||||
{
|
||||
return c_dPtToMM * (m_oFont.m_dLineSpacing * m_oFont.m_oFont.Size ) / m_oFont.m_dEmHeight;
|
||||
}
|
||||
|
||||
inline void SetStringGid(const LONG& lGid)
|
||||
{
|
||||
if (NULL != m_pManager)
|
||||
m_pManager->SetStringGID(lGid);
|
||||
}
|
||||
|
||||
inline void GenerateFontName2(NSStringUtils::CStringUTF32& oText)
|
||||
{
|
||||
bool bIsNeedAddToMap = CFontManagerBase::GenerateFontName(oText);
|
||||
|
||||
if (bIsNeedAddToMap)
|
||||
{
|
||||
if (m_oFontTable.m_mapTable.end() != m_oFontTable.m_mapTable.find(m_strCurrentPickFont))
|
||||
{
|
||||
CFontTableEntry oEntry;
|
||||
oEntry.m_strFamilyName = m_strCurrentPickFont;
|
||||
oEntry.m_strPANOSE = m_oFont.m_strPANOSE;
|
||||
oEntry.m_lStyle = m_oFont.m_lStyle;
|
||||
oEntry.m_bIsFixedWidth = m_oFont.m_bIsFixedWidth;
|
||||
oEntry.m_arSignature = m_oFont.m_arSignature;
|
||||
|
||||
m_oFontTable.m_mapTable.insert(std::pair<std::wstring, CFontTableEntry>(m_oFont.m_strFamilyName, oEntry));
|
||||
}
|
||||
}
|
||||
}
|
||||
};
|
||||
|
||||
class CFontManagerLight
|
||||
{
|
||||
private:
|
||||
std::wstring m_strFontName;
|
||||
LONG m_lFontStyle;
|
||||
double m_dSize;
|
||||
|
||||
double m_dSpaceWidth;
|
||||
|
||||
NSFonts::IFontManager* m_pManager;
|
||||
|
||||
public:
|
||||
CFontManagerLight(NSFonts::IApplicationFonts* pFonts)
|
||||
{
|
||||
m_strFontName = L"";
|
||||
m_lFontStyle = 0;
|
||||
m_dSize = 0;
|
||||
m_dSpaceWidth = 0;
|
||||
|
||||
m_pManager = NSFontManager::CreateFontManager(pFonts);
|
||||
}
|
||||
~CFontManagerLight()
|
||||
{
|
||||
RELEASEINTERFACE(m_pManager);
|
||||
}
|
||||
|
||||
inline double GetSpaceWidth()
|
||||
{
|
||||
return m_dSpaceWidth;
|
||||
}
|
||||
|
||||
public:
|
||||
void LoadFont(std::wstring& strFontName, LONG& lStyle, double& dSize, const bool& bIsGID)
|
||||
{
|
||||
if ((strFontName == m_strFontName) && (lStyle == m_lFontStyle) && (dSize == m_dSize))
|
||||
{
|
||||
m_pManager->SetStringGID(bIsGID);
|
||||
return;
|
||||
}
|
||||
|
||||
m_strFontName = strFontName;
|
||||
m_lFontStyle = lStyle;
|
||||
m_dSize = dSize;
|
||||
|
||||
m_pManager->LoadFontByName(strFontName, (float)m_dSize, m_lFontStyle, c_dDpiX, c_dDpiY);
|
||||
m_dSpaceWidth = MeasureStringWidth(L" ");
|
||||
|
||||
m_pManager->SetStringGID(bIsGID);
|
||||
}
|
||||
|
||||
double MeasureStringWidth(const std::wstring& sText)
|
||||
{
|
||||
m_pManager->LoadString2(sText, (float)0, (float)0);
|
||||
TBBox bbox = m_pManager->MeasureString2();
|
||||
|
||||
return (bbox.fMaxX - bbox.fMinX) * c_dPixToMM;
|
||||
}
|
||||
};
|
||||
double MeasureStringWidth(const std::wstring& sText);
|
||||
};
|
||||
|
||||
}
|
||||
|
||||
703
DocxRenderer/src/logic/FontManagerBase.cpp
Normal file
703
DocxRenderer/src/logic/FontManagerBase.cpp
Normal file
@ -0,0 +1,703 @@
|
||||
#include "FontManagerBase.h"
|
||||
#include "../DesktopEditor/common/Directory.h"
|
||||
#include "../DesktopEditor/xml/include/xmlutils.h"
|
||||
#include "src/resources/Constants.h"
|
||||
|
||||
namespace NSFontManager
|
||||
{
|
||||
CUnicodeRange::CUnicodeRange(const int& _start, const int& _end,
|
||||
const BYTE& _range, const BYTE& _rangenum):
|
||||
RangeNum(_rangenum), Range(_range), Start(_start), End(_end)
|
||||
{
|
||||
}
|
||||
|
||||
CUnicodeRanges::CUnicodeRanges()
|
||||
{
|
||||
// https://docs.microsoft.com/en-us/typography/opentype/spec/os2#ur
|
||||
|
||||
m_arRanges.push_back(CUnicodeRange(0x0000, 0x007F, 0, 0)); // Basic Latin
|
||||
m_arRanges.push_back(CUnicodeRange(0x0080, 0x00FF, 1, 0)); // Latin-1 Supplement
|
||||
m_arRanges.push_back(CUnicodeRange(0x0100, 0x017F, 2, 0)); // Latin Extended-A
|
||||
m_arRanges.push_back(CUnicodeRange(0x0180, 0x024F, 3, 0)); // Latin Extended-B
|
||||
m_arRanges.push_back(CUnicodeRange(0x0250, 0x02AF, 4, 0)); // IPA Extensions
|
||||
m_arRanges.push_back(CUnicodeRange(0x1D00, 0x1D7F, 4, 0)); // Phonetic Extensions
|
||||
m_arRanges.push_back(CUnicodeRange(0x1D80, 0x1DBF, 4, 0)); // Phonetic Extensions Supplement
|
||||
m_arRanges.push_back(CUnicodeRange(0x02B0, 0x02FF, 5, 0)); // Spacing Modifier Letters
|
||||
m_arRanges.push_back(CUnicodeRange(0xA700, 0xA71F, 5, 0)); // Modifier Tone Letters
|
||||
m_arRanges.push_back(CUnicodeRange(0x0300, 0x036F, 6, 0)); // Combining Diacritical Marks
|
||||
m_arRanges.push_back(CUnicodeRange(0x1DC0, 0x1DFF, 6, 0)); // Combining Diacritical Marks Supplement
|
||||
m_arRanges.push_back(CUnicodeRange(0x0370, 0x03FF, 7, 0)); // Greek and Coptic
|
||||
m_arRanges.push_back(CUnicodeRange(0x2C80, 0x2CFF, 8, 0)); // Coptic
|
||||
m_arRanges.push_back(CUnicodeRange(0x0400, 0x04FF, 9, 0)); // Cyrillic
|
||||
m_arRanges.push_back(CUnicodeRange(0x0500, 0x052F, 9, 0)); // Cyrillic Supplement
|
||||
m_arRanges.push_back(CUnicodeRange(0x2DE0, 0x2DFF, 9, 0)); // Cyrillic Extended-A
|
||||
m_arRanges.push_back(CUnicodeRange(0xA640, 0xA69F, 9, 0)); // Cyrillic Extended-B
|
||||
m_arRanges.push_back(CUnicodeRange(0x0530, 0x058F, 10, 0)); // Armenian
|
||||
m_arRanges.push_back(CUnicodeRange(0x0590, 0x05FF, 11, 0)); // Hebrew
|
||||
m_arRanges.push_back(CUnicodeRange(0xA500, 0xA63F, 12, 0)); // Vai
|
||||
m_arRanges.push_back(CUnicodeRange(0x0600, 0x06FF, 13, 0)); // Arabic
|
||||
m_arRanges.push_back(CUnicodeRange(0x0750, 0x077F, 13, 0)); // Arabic Supplement
|
||||
m_arRanges.push_back(CUnicodeRange(0x07C0, 0x07FF, 14, 0)); // NKo
|
||||
m_arRanges.push_back(CUnicodeRange(0x0900, 0x097F, 15, 0)); // Devanagari
|
||||
m_arRanges.push_back(CUnicodeRange(0x0980, 0x09FF, 16, 0)); // Bengali
|
||||
m_arRanges.push_back(CUnicodeRange(0x0A00, 0x0A7F, 17, 0)); // Gurmukhi
|
||||
m_arRanges.push_back(CUnicodeRange(0x0A80, 0x0AFF, 18, 0)); // Gujarati
|
||||
m_arRanges.push_back(CUnicodeRange(0x0B00, 0x0B7F, 19, 0)); // Oriya
|
||||
m_arRanges.push_back(CUnicodeRange(0x0B80, 0x0BFF, 20, 0)); // Tamil
|
||||
m_arRanges.push_back(CUnicodeRange(0x0C00, 0x0C7F, 21, 0)); // Telugu
|
||||
m_arRanges.push_back(CUnicodeRange(0x0C80, 0x0CFF, 22, 0)); // Kannada
|
||||
m_arRanges.push_back(CUnicodeRange(0x0D00, 0x0D7F, 23, 0)); // Malayalam
|
||||
m_arRanges.push_back(CUnicodeRange(0x0E00, 0x0E7F, 24, 0)); // Thai
|
||||
m_arRanges.push_back(CUnicodeRange(0x0E80, 0x0EFF, 25, 0)); // Lao
|
||||
m_arRanges.push_back(CUnicodeRange(0x10A0, 0x10FF, 26, 0)); // Georgian
|
||||
m_arRanges.push_back(CUnicodeRange(0x2D00, 0x2D2F, 26, 0)); // Georgian Supplement
|
||||
m_arRanges.push_back(CUnicodeRange(0x1B00, 0x1B7F, 27, 0)); // Balinese
|
||||
m_arRanges.push_back(CUnicodeRange(0x1100, 0x11FF, 28, 0)); // Hangul Jamo
|
||||
m_arRanges.push_back(CUnicodeRange(0x1E00, 0x1EFF, 29, 0)); // Latin Extended Additional
|
||||
m_arRanges.push_back(CUnicodeRange(0x2C60, 0x2C7F, 29, 0)); // Latin Extended-C
|
||||
m_arRanges.push_back(CUnicodeRange(0xA720, 0xA7FF, 29, 0)); // Latin Extended-D
|
||||
m_arRanges.push_back(CUnicodeRange(0x1F00, 0x1FFF, 30, 0)); // Greek Extended
|
||||
m_arRanges.push_back(CUnicodeRange(0x2000, 0x206F, 31, 0)); // General Punctuation
|
||||
m_arRanges.push_back(CUnicodeRange(0x2E00, 0x2E7F, 31, 0)); // Supplemental Punctuation
|
||||
|
||||
m_arRanges.push_back(CUnicodeRange(0x2070, 0x209F, 0, 1)); // Superscripts And Subscripts
|
||||
m_arRanges.push_back(CUnicodeRange(0x20A0, 0x20CF, 1, 1)); // Currency Symbols
|
||||
m_arRanges.push_back(CUnicodeRange(0x20D0, 0x20FF, 2, 1)); // Combining Diacritical Marks For Symbols
|
||||
m_arRanges.push_back(CUnicodeRange(0x2100, 0x214F, 3, 1)); // Letterlike Symbols
|
||||
m_arRanges.push_back(CUnicodeRange(0x2150, 0x218F, 4, 1)); // Number Forms
|
||||
m_arRanges.push_back(CUnicodeRange(0x2190, 0x21FF, 5, 1)); // Arrows
|
||||
m_arRanges.push_back(CUnicodeRange(0x27F0, 0x27FF, 5, 1)); // Supplemental Arrows-A
|
||||
m_arRanges.push_back(CUnicodeRange(0x2900, 0x297F, 5, 1)); // Supplemental Arrows-B
|
||||
m_arRanges.push_back(CUnicodeRange(0x2B00, 0x2BFF, 5, 1)); // Miscellaneous Symbols and Arrows
|
||||
m_arRanges.push_back(CUnicodeRange(0x2200, 0x22FF, 6, 1)); // Mathematical Operators
|
||||
m_arRanges.push_back(CUnicodeRange(0x2A00, 0x2AFF, 6, 1)); // Supplemental Mathematical Operators
|
||||
m_arRanges.push_back(CUnicodeRange(0x27C0, 0x27EF, 6, 1)); // Miscellaneous Mathematical Symbols-A
|
||||
m_arRanges.push_back(CUnicodeRange(0x2980, 0x29FF, 6, 1)); // Miscellaneous Mathematical Symbols-B
|
||||
m_arRanges.push_back(CUnicodeRange(0x2300, 0x23FF, 7, 1)); // Miscellaneous Technical
|
||||
m_arRanges.push_back(CUnicodeRange(0x2400, 0x243F, 8, 1)); // Control Pictures
|
||||
m_arRanges.push_back(CUnicodeRange(0x2440, 0x245F, 9, 1)); // Optical Character Recognition
|
||||
m_arRanges.push_back(CUnicodeRange(0x2460, 0x24FF, 10, 1)); // Enclosed Alphanumerics
|
||||
m_arRanges.push_back(CUnicodeRange(0x2500, 0x257F, 11, 1)); // Box Drawing
|
||||
m_arRanges.push_back(CUnicodeRange(0x2580, 0x259F, 12, 1)); // Block Elements
|
||||
m_arRanges.push_back(CUnicodeRange(0x25A0, 0x25FF, 13, 1)); // Geometric Shapes
|
||||
m_arRanges.push_back(CUnicodeRange(0x2600, 0x26FF, 14, 1)); // Miscellaneous Symbols
|
||||
m_arRanges.push_back(CUnicodeRange(0x2700, 0x27BF, 15, 1)); // Dingbats
|
||||
m_arRanges.push_back(CUnicodeRange(0x3000, 0x303F, 16, 1)); // CJK Symbols And Punctuation
|
||||
m_arRanges.push_back(CUnicodeRange(0x3040, 0x309F, 17, 1)); // Hiragana
|
||||
m_arRanges.push_back(CUnicodeRange(0x30A0, 0x30FF, 18, 1)); // Katakana
|
||||
m_arRanges.push_back(CUnicodeRange(0x31F0, 0x31FF, 18, 1)); // Katakana Phonetic Extensions
|
||||
m_arRanges.push_back(CUnicodeRange(0x3100, 0x312F, 19, 1)); // Bopomofo
|
||||
m_arRanges.push_back(CUnicodeRange(0x31A0, 0x31BF, 19, 1)); // Bopomofo Extended
|
||||
m_arRanges.push_back(CUnicodeRange(0x3130, 0x318F, 20, 1)); // Hangul Compatibility Jamo
|
||||
m_arRanges.push_back(CUnicodeRange(0xA840, 0xA87F, 21, 1)); // Phags-pa
|
||||
m_arRanges.push_back(CUnicodeRange(0x3200, 0x32FF, 22, 1)); // Enclosed CJK Letters And Months
|
||||
m_arRanges.push_back(CUnicodeRange(0x3300, 0x33FF, 23, 1)); // CJK Compatibility
|
||||
m_arRanges.push_back(CUnicodeRange(0xAC00, 0xD7AF, 24, 1)); // Hangul Syllables
|
||||
m_arRanges.push_back(CUnicodeRange(0x10000, 0x10FFFF, 25, 1)); // Non-Plane 0
|
||||
m_arRanges.push_back(CUnicodeRange(0x10900, 0x1091F, 26, 1)); // Phoenician
|
||||
m_arRanges.push_back(CUnicodeRange(0x4E00, 0x9FFF, 27, 1)); // CJK Unified Ideographs
|
||||
m_arRanges.push_back(CUnicodeRange(0x2E80, 0x2EFF, 27, 1)); // CJK Radicals Supplement
|
||||
m_arRanges.push_back(CUnicodeRange(0x2F00, 0x2FDF, 27, 1)); // Kangxi Radicals
|
||||
m_arRanges.push_back(CUnicodeRange(0x2FF0, 0x2FFF, 27, 1)); // Ideographic Description Characters
|
||||
m_arRanges.push_back(CUnicodeRange(0x3400, 0x4DBF, 27, 1)); // CJK Unified Ideographs Extension A
|
||||
m_arRanges.push_back(CUnicodeRange(0x3190, 0x319F, 27, 1)); // Kanbun
|
||||
m_arRanges.push_back(CUnicodeRange(0x20000, 0x2A6DF, 27, 1)); // CJK Unified Ideographs Extension B
|
||||
m_arRanges.push_back(CUnicodeRange(0xE000, 0xF8FF, 28, 1)); // Private Use Area (plane 0)
|
||||
m_arRanges.push_back(CUnicodeRange(0x31C0, 0x31EF, 29, 1)); // CJK Strokes
|
||||
m_arRanges.push_back(CUnicodeRange(0xF900, 0xFAFF, 29, 1)); // CJK Compatibility Ideographs
|
||||
m_arRanges.push_back(CUnicodeRange(0x2F800, 0x2FA1F, 29, 1)); // CJK Compatibility Ideographs Supplement
|
||||
m_arRanges.push_back(CUnicodeRange(0xFB00, 0xFB4F, 30, 1)); // Alphabetic Presentation Forms
|
||||
m_arRanges.push_back(CUnicodeRange(0xFB50, 0xFDFF, 31, 1)); // Arabic Presentation Forms-A
|
||||
|
||||
m_arRanges.push_back(CUnicodeRange(0xFE20, 0xFE2F, 0, 2)); // Combining Half Marks
|
||||
m_arRanges.push_back(CUnicodeRange(0xFE10, 0xFE1F, 1, 2)); // Vertical Forms
|
||||
m_arRanges.push_back(CUnicodeRange(0xFE30, 0xFE4F, 1, 2)); // CJK Compatibility Forms
|
||||
m_arRanges.push_back(CUnicodeRange(0xFE50, 0xFE6F, 2, 2)); // Small Form Variants
|
||||
m_arRanges.push_back(CUnicodeRange(0xFE70, 0xFEFF, 3, 2)); // Arabic Presentation Forms-B
|
||||
m_arRanges.push_back(CUnicodeRange(0xFF00, 0xFFEF, 4, 2)); // Halfwidth And Fullwidth Forms
|
||||
m_arRanges.push_back(CUnicodeRange(0xFFF0, 0xFFFF, 5, 2)); // Specials
|
||||
m_arRanges.push_back(CUnicodeRange(0x0F00, 0x0FFF, 6, 2)); // Tibetan
|
||||
m_arRanges.push_back(CUnicodeRange(0x0700, 0x074F, 7, 2)); // Syriac
|
||||
m_arRanges.push_back(CUnicodeRange(0x0780, 0x07BF, 8, 2)); // Thaana
|
||||
m_arRanges.push_back(CUnicodeRange(0x0D80, 0x0DFF, 9, 2)); // Sinhala
|
||||
m_arRanges.push_back(CUnicodeRange(0x1000, 0x109F, 10, 2)); // Myanmar
|
||||
m_arRanges.push_back(CUnicodeRange(0x1200, 0x137F, 11, 2)); // Ethiopic
|
||||
m_arRanges.push_back(CUnicodeRange(0x1380, 0x139F, 11, 2)); // Ethiopic Supplement
|
||||
m_arRanges.push_back(CUnicodeRange(0x2D80, 0x2DDF, 11, 2)); // Ethiopic Extended
|
||||
m_arRanges.push_back(CUnicodeRange(0x13A0, 0x13FF, 12, 2)); // Cherokee
|
||||
m_arRanges.push_back(CUnicodeRange(0x1400, 0x167F, 13, 2)); // Unified Canadian Aboriginal Syllabics
|
||||
m_arRanges.push_back(CUnicodeRange(0x1680, 0x169F, 14, 2)); // Ogham
|
||||
m_arRanges.push_back(CUnicodeRange(0x16A0, 0x16FF, 15, 2)); // Runic
|
||||
m_arRanges.push_back(CUnicodeRange(0x1780, 0x17FF, 16, 2)); // Khmer
|
||||
m_arRanges.push_back(CUnicodeRange(0x19E0, 0x19FF, 16, 2)); // Khmer Symbols
|
||||
m_arRanges.push_back(CUnicodeRange(0x1800, 0x18AF, 17, 2)); // Mongolian
|
||||
m_arRanges.push_back(CUnicodeRange(0x2800, 0x28FF, 18, 2)); // Braille Patterns
|
||||
m_arRanges.push_back(CUnicodeRange(0xA000, 0xA48F, 19, 2)); // Yi Syllables
|
||||
m_arRanges.push_back(CUnicodeRange(0xA490, 0xA4CF, 19, 2)); // Yi Radicals
|
||||
m_arRanges.push_back(CUnicodeRange(0x1700, 0x171F, 20, 2)); // Tagalog
|
||||
m_arRanges.push_back(CUnicodeRange(0x1720, 0x173F, 20, 2)); // Hanunoo
|
||||
m_arRanges.push_back(CUnicodeRange(0x1740, 0x175F, 20, 2)); // Buhid
|
||||
m_arRanges.push_back(CUnicodeRange(0x1760, 0x177F, 20, 2)); // Tagbanwa
|
||||
m_arRanges.push_back(CUnicodeRange(0x10300, 0x1032F, 21, 2)); // Old Italic
|
||||
m_arRanges.push_back(CUnicodeRange(0x10330, 0x1034F, 22, 2)); // Gothic
|
||||
m_arRanges.push_back(CUnicodeRange(0x10400, 0x1044F, 23, 2)); // Deseret
|
||||
m_arRanges.push_back(CUnicodeRange(0x1D000, 0x1D0FF, 24, 2)); // Byzantine Musical Symbols
|
||||
m_arRanges.push_back(CUnicodeRange(0x1D100, 0x1D1FF, 24, 2)); // Musical Symbols
|
||||
m_arRanges.push_back(CUnicodeRange(0x1D200, 0x1D24F, 24, 2)); // Ancient Greek Musical Notation
|
||||
m_arRanges.push_back(CUnicodeRange(0x1D400, 0x1D7FF, 25, 2)); // Mathematical Alphanumeric Symbols
|
||||
m_arRanges.push_back(CUnicodeRange(0xF0000, 0xFFFFD, 26, 2)); // Private Use (plane 15)
|
||||
m_arRanges.push_back(CUnicodeRange(0x100000, 0x10FFFD, 26, 2)); // Private Use (plane 16)
|
||||
m_arRanges.push_back(CUnicodeRange(0xFE00, 0xFE0F, 27, 2)); // Variation Selectors
|
||||
m_arRanges.push_back(CUnicodeRange(0xE0100, 0xE01EF, 27, 2)); // Variation Selectors Supplement
|
||||
m_arRanges.push_back(CUnicodeRange(0xE0000, 0xE007F, 28, 2)); // Tags
|
||||
m_arRanges.push_back(CUnicodeRange(0x1900, 0x194F, 29, 2)); // Limbu
|
||||
m_arRanges.push_back(CUnicodeRange(0x1950, 0x197F, 30, 2)); // Tai Le
|
||||
m_arRanges.push_back(CUnicodeRange(0x1980, 0x19DF, 31, 2)); // New Tai Lue
|
||||
|
||||
m_arRanges.push_back(CUnicodeRange(0x1A00, 0x1A1F, 0, 3)); // Buginese
|
||||
m_arRanges.push_back(CUnicodeRange(0x2C00, 0x2C5F, 1, 3)); // Glagolitic
|
||||
m_arRanges.push_back(CUnicodeRange(0x2D30, 0x2D7F, 2, 3)); // Tifinagh
|
||||
m_arRanges.push_back(CUnicodeRange(0x4DC0, 0x4DFF, 3, 3)); // Yijing Hexagram Symbols
|
||||
m_arRanges.push_back(CUnicodeRange(0xA800, 0xA82F, 4, 3)); // Syloti Nagri
|
||||
m_arRanges.push_back(CUnicodeRange(0x10000, 0x1007F, 5, 3)); // Linear B Syllabary
|
||||
m_arRanges.push_back(CUnicodeRange(0x10080, 0x100FF, 5, 3)); // Linear B Ideograms
|
||||
m_arRanges.push_back(CUnicodeRange(0x10100, 0x1013F, 5, 3)); // Aegean Numbers
|
||||
m_arRanges.push_back(CUnicodeRange(0x10140, 0x1018F, 6, 3)); // Ancient Greek Numbers
|
||||
m_arRanges.push_back(CUnicodeRange(0x10380, 0x1039F, 7, 3)); // Ugaritic
|
||||
m_arRanges.push_back(CUnicodeRange(0x103A0, 0x103DF, 8, 3)); // Old Persian
|
||||
m_arRanges.push_back(CUnicodeRange(0x10450, 0x1047F, 9, 3)); // Shavian
|
||||
m_arRanges.push_back(CUnicodeRange(0x10480, 0x104AF, 10, 3)); // Osmanya
|
||||
m_arRanges.push_back(CUnicodeRange(0x10800, 0x1083F, 11, 3)); // Cypriot Syllabary
|
||||
m_arRanges.push_back(CUnicodeRange(0x10A00, 0x10A5F, 12, 3)); // Kharoshthi
|
||||
m_arRanges.push_back(CUnicodeRange(0x1D300, 0x1D35F, 13, 3)); // Tai Xuan Jing Symbols
|
||||
m_arRanges.push_back(CUnicodeRange(0x12000, 0x123FF, 14, 3)); // Cuneiform
|
||||
m_arRanges.push_back(CUnicodeRange(0x12400, 0x1247F, 14, 3)); // Cuneiform Numbers and Punctuation
|
||||
m_arRanges.push_back(CUnicodeRange(0x1D360, 0x1D37F, 15, 3)); // Counting Rod Numerals
|
||||
m_arRanges.push_back(CUnicodeRange(0x1B80, 0x1BBF, 16, 3)); // Sundanese
|
||||
m_arRanges.push_back(CUnicodeRange(0x1C00, 0x1C4F, 17, 3)); // Lepcha
|
||||
m_arRanges.push_back(CUnicodeRange(0x1C50, 0x1C7F, 18, 3)); // Ol Chiki
|
||||
m_arRanges.push_back(CUnicodeRange(0xA880, 0xA8DF, 19, 3)); // Saurashtra
|
||||
m_arRanges.push_back(CUnicodeRange(0xA900, 0xA92F, 20, 3)); // Kayah Li
|
||||
m_arRanges.push_back(CUnicodeRange(0xA930, 0xA95F, 21, 3)); // Rejang
|
||||
m_arRanges.push_back(CUnicodeRange(0xAA00, 0xAA5F, 22, 3)); // Cham
|
||||
m_arRanges.push_back(CUnicodeRange(0x10190, 0x101CF, 23, 3)); // Ancient Symbols
|
||||
m_arRanges.push_back(CUnicodeRange(0x101D0, 0x101FF, 24, 3)); // Phaistos Disc
|
||||
m_arRanges.push_back(CUnicodeRange(0x102A0, 0x102DF, 25, 3)); // Carian
|
||||
m_arRanges.push_back(CUnicodeRange(0x10280, 0x1029F, 25, 3)); // Lycian
|
||||
m_arRanges.push_back(CUnicodeRange(0x10920, 0x1093F, 25, 3)); // Lydian
|
||||
m_arRanges.push_back(CUnicodeRange(0x1F030, 0x1F09F, 26, 3)); // Domino Tiles
|
||||
m_arRanges.push_back(CUnicodeRange(0x1F000, 0x1F02F, 26, 3)); // Mahjong Tiles
|
||||
// 27: "Reserved for process-internal usage"
|
||||
// 28: "Reserved for process-internal usage"
|
||||
// 29: "Reserved for process-internal usage"
|
||||
// 30: "Reserved for process-internal usage"
|
||||
// 31: "Reserved for process-internal usage"
|
||||
}
|
||||
|
||||
void CUnicodeRanges::CheckRange(const int& symbol, BYTE& Range, BYTE& RangeNum)
|
||||
{
|
||||
// определяем range и двигаем его в начало.
|
||||
std::list<CUnicodeRange>::iterator iter = m_arRanges.begin();
|
||||
while (iter != m_arRanges.end())
|
||||
{
|
||||
CUnicodeRange& range = *iter;
|
||||
if (symbol >= range.Start && symbol <= range.End)
|
||||
{
|
||||
Range = range.Range;
|
||||
RangeNum = range.RangeNum;
|
||||
|
||||
m_arRanges.splice(m_arRanges.begin(), m_arRanges, iter);
|
||||
return;
|
||||
}
|
||||
iter++;
|
||||
}
|
||||
}
|
||||
|
||||
void CUnicodeRanges::CheckRange(const int& symbol, int& Range1, int& Range2, int& Range3, int& Range4)
|
||||
{
|
||||
BYTE nRange = 0xFF;
|
||||
BYTE nRangeNum = 0xFF;
|
||||
CheckRange(symbol, nRange, nRangeNum);
|
||||
|
||||
switch (nRangeNum)
|
||||
{
|
||||
case 0: Range1 |= (1 << nRange); break;
|
||||
case 1: Range2 |= (1 << nRange); break;
|
||||
case 2: Range3 |= (1 << nRange); break;
|
||||
case 3: Range4 |= (1 << nRange); break;
|
||||
default:
|
||||
break;
|
||||
}
|
||||
}
|
||||
|
||||
CFontAdvanced::CFontAdvanced()
|
||||
{
|
||||
m_oFont.SetDefaultParams();
|
||||
m_arSignature.clear();
|
||||
}
|
||||
|
||||
CFontAdvanced::CFontAdvanced(const CFontAdvanced& oSrc)
|
||||
{
|
||||
*this = oSrc;
|
||||
}
|
||||
|
||||
CFontAdvanced& CFontAdvanced::operator=(const CFontAdvanced& oSrc)
|
||||
{
|
||||
if (this == &oSrc)
|
||||
{
|
||||
return *this;
|
||||
}
|
||||
|
||||
m_oFont = oSrc.m_oFont;
|
||||
|
||||
m_dAscent = oSrc.m_dAscent;
|
||||
m_dDescent = oSrc.m_dDescent;
|
||||
m_dLineSpacing = oSrc.m_dLineSpacing;
|
||||
m_dEmHeight = oSrc.m_dEmHeight;
|
||||
|
||||
m_dBaselineOffset = oSrc.m_dBaselineOffset;
|
||||
|
||||
m_dSpaceWidthMM = oSrc.m_dSpaceWidthMM;
|
||||
|
||||
m_strFamilyName = oSrc.m_strFamilyName;
|
||||
m_strPANOSE = oSrc.m_strPANOSE;
|
||||
m_lStyle = oSrc.m_lStyle;
|
||||
m_arSignature = m_arSignature;
|
||||
m_bIsFixedWidth = oSrc.m_bIsFixedWidth;
|
||||
m_lAvgWidth = oSrc.m_lAvgWidth;
|
||||
|
||||
return *this;
|
||||
}
|
||||
|
||||
CFontPickUp::CFontPickUp() : m_oFont()
|
||||
{
|
||||
}
|
||||
|
||||
CFontPickUp::CFontPickUp(const CFontPickUp& oSrc)
|
||||
{
|
||||
*this = oSrc;
|
||||
}
|
||||
|
||||
CFontPickUp& CFontPickUp::operator=(const CFontPickUp& oSrc)
|
||||
{
|
||||
if (this == &oSrc)
|
||||
{
|
||||
return *this;
|
||||
}
|
||||
|
||||
m_oFont = oSrc.m_oFont;
|
||||
m_lRange = oSrc.m_lRange;
|
||||
m_lRangeNum = oSrc.m_lRangeNum;
|
||||
m_strPickFont = oSrc.m_strPickFont;
|
||||
m_lPickStyle = oSrc.m_lPickStyle;
|
||||
|
||||
return *this;
|
||||
}
|
||||
|
||||
CFontManagerBase::CFontManagerBase(NSFonts::IApplicationFonts* pFonts)
|
||||
{
|
||||
m_pManager = NSFontManager::CreateFontManager(pFonts);
|
||||
|
||||
SetDefaultFont(L"Arial");
|
||||
|
||||
ClearPickUps();
|
||||
}
|
||||
|
||||
CFontManagerBase::~CFontManagerBase()
|
||||
{
|
||||
RELEASEINTERFACE(m_pManager);
|
||||
}
|
||||
|
||||
void CFontManagerBase::ClearPickUps()
|
||||
{
|
||||
m_arListPicUps.clear();
|
||||
m_strCurrentPickFont = L"";
|
||||
m_lCurrentPictFontStyle = 0;
|
||||
}
|
||||
|
||||
void CFontManagerBase::SetDefaultFont(const std::wstring& strName)
|
||||
{
|
||||
m_strDefaultFont = strName;
|
||||
}
|
||||
|
||||
std::wstring CFontManagerBase::GetDefaultFont()
|
||||
{
|
||||
return m_strDefaultFont;
|
||||
}
|
||||
|
||||
void CFontManagerBase::LoadFont(long lFaceIndex, bool bIsNeedAddToMap)
|
||||
{
|
||||
}
|
||||
|
||||
void CFontManagerBase::LoadFontByName(const std::wstring& strName, const double& dSize, const LONG& lStyle, const double& dDpiX, const double& dDpiY)
|
||||
{
|
||||
m_pManager->LoadFontByName(strName, (float)dSize, lStyle, dDpiX, dDpiY);
|
||||
m_pManager->AfterLoad();
|
||||
|
||||
LoadFontMetrics();
|
||||
LoadFontParams();
|
||||
|
||||
m_oFont.m_lAvgWidth = -1;
|
||||
}
|
||||
|
||||
void CFontManagerBase::LoadFontByFile(const std::wstring& strPath, const double& dSize, const double& dDpiX, const double& dDpiY, const LONG& lFaceIndex)
|
||||
{
|
||||
m_pManager->LoadFontFromFile(strPath, (int)lFaceIndex, (float)dSize, dDpiX, dDpiY);
|
||||
m_pManager->AfterLoad();
|
||||
|
||||
LoadFontMetrics();
|
||||
LoadFontParams();
|
||||
m_oFont.m_oFont.Name = m_pManager->GetName();
|
||||
m_oFont.m_strFamilyName = m_oFont.m_oFont.Name;
|
||||
|
||||
m_oFont.m_lAvgWidth = -1;
|
||||
|
||||
bool bIsCID = false;
|
||||
std::wstring sFileExt = NSFile::GetFileExtention(strPath);
|
||||
if (std::wstring::npos != sFileExt.find(L"cid"))
|
||||
bIsCID = true;
|
||||
|
||||
std::wstring sFileName = NSFile::GetFileName(strPath);
|
||||
std::wstring::size_type pos = sFileName.rfind('.');
|
||||
if (std::wstring::npos != pos)
|
||||
sFileName = sFileName.substr(0, pos);
|
||||
std::wstring sEncFilePath = NSFile::GetDirectoryName(strPath) + L"/" + sFileName + L".enc";
|
||||
|
||||
XmlUtils::CXmlNode oMainNode;
|
||||
oMainNode.FromXmlFile(sEncFilePath);
|
||||
|
||||
if (L"PDF-resources" == oMainNode.GetName())
|
||||
{
|
||||
if (bIsCID)
|
||||
{
|
||||
XmlUtils::CXmlNode oType0Node;
|
||||
if ( oMainNode.GetNode( L"Type0", oType0Node ) )
|
||||
{
|
||||
XmlUtils::CXmlNode oNode;
|
||||
if ( oType0Node.GetNode( L"DescendantFonts", oNode ) )
|
||||
{
|
||||
XmlUtils::CXmlNode oDescNode;
|
||||
if ( oNode.GetNode( L"FontDescriptor", oDescNode ) )
|
||||
{
|
||||
XmlUtils::CXmlNode oCurNode;
|
||||
if ( oNode.GetNode( L"AvgWidth", oCurNode ) )
|
||||
{
|
||||
std::wstring sValue = oCurNode.GetAttribute(L"value");
|
||||
try {
|
||||
m_oFont.m_lAvgWidth = (SHORT)std::stol(sValue);
|
||||
} catch (std::invalid_argument &) {}
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
else
|
||||
{
|
||||
XmlUtils::CXmlNode oNode;
|
||||
if ( oMainNode.GetNode( L"FontDescriptor", oNode ) )
|
||||
{
|
||||
XmlUtils::CXmlNode oCurNode;
|
||||
if ( oNode.GetNode( L"AvgWidth", oCurNode ) )
|
||||
{
|
||||
std::wstring sValue = oCurNode.GetAttribute(L"value");
|
||||
try {
|
||||
m_oFont.m_lAvgWidth = (SHORT)std::stol(sValue);
|
||||
} catch (std::invalid_argument &) {}
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
void CFontManagerBase::MeasureString(const std::wstring& sText, double x, double y, double& dBoxX, double& dBoxY, double& dBoxWidth, double& dBoxHeight, MeasureType measureType)
|
||||
{
|
||||
}
|
||||
|
||||
void CFontManagerBase::CalculateBaselineOffset()
|
||||
{
|
||||
LoadFont();
|
||||
|
||||
double d1 = 3 * (m_oFont.m_dLineSpacing - m_oFont.m_dDescent) - m_oFont.m_dAscent;
|
||||
d1 /= 2.0;
|
||||
|
||||
d1 *= (m_oFont.m_oFont.Size / m_oFont.m_dEmHeight);
|
||||
m_oFont.m_dBaselineOffset = d1;
|
||||
}
|
||||
|
||||
void CFontManagerBase::LoadFontMetrics()
|
||||
{
|
||||
m_oFont.m_dAscent = m_pManager->GetAscender();
|
||||
m_oFont.m_dDescent = m_pManager->GetDescender();
|
||||
m_oFont.m_dLineSpacing = m_pManager->GetLineHeight();
|
||||
m_oFont.m_dEmHeight = m_pManager->GetUnitsPerEm();
|
||||
|
||||
m_oFont.m_dBaselineOffset = (c_dPtToMM * m_oFont.m_dDescent * m_oFont.m_oFont.Size / m_oFont.m_dEmHeight);
|
||||
}
|
||||
|
||||
std::wstring CFontManagerBase::ToHexString( BYTE uc )
|
||||
{
|
||||
std::wstring sRet = L"";
|
||||
char c1 = (char)(uc >> 4);
|
||||
char c2 = (char)(uc & 0x0F);
|
||||
sRet += (wchar_t)((c1 < 10) ? ('0' + c1) : ('A' + c1 - 10));
|
||||
sRet += (wchar_t)((c2 < 10) ? ('0' + c2) : ('A' + c2 - 10));
|
||||
return sRet;
|
||||
}
|
||||
|
||||
BYTE CFontManagerBase::FromHexString( wchar_t c1, wchar_t c2 )
|
||||
{
|
||||
BYTE res = 0;
|
||||
res |= ((c1 >= 'A') ? (c1 - 'A' + 10) : (c1 - '0'));
|
||||
res <<= 4;
|
||||
res |= ((c2 >= 'A') ? (c2 - 'A' + 10) : (c2 - '0'));
|
||||
return res;
|
||||
}
|
||||
|
||||
void CFontManagerBase::LoadFontParams(bool bIsPath)
|
||||
{
|
||||
// читаем и выставляем все настройки шрифта
|
||||
if (nullptr == m_pManager || nullptr == m_pManager->GetFile())
|
||||
return;
|
||||
|
||||
m_oFont.m_strFamilyName = m_oFont.m_oFont.Name;
|
||||
|
||||
m_oFont.m_lStyle = 0x00;
|
||||
if (m_pManager->GetFile()->IsBold())
|
||||
{
|
||||
m_oFont.m_lStyle |= 0x01;
|
||||
}
|
||||
if (m_pManager->GetFile()->IsItalic())
|
||||
{
|
||||
m_oFont.m_lStyle |= 0x02;
|
||||
}
|
||||
|
||||
// PANOSE
|
||||
BYTE pPanose[10];
|
||||
m_pManager->GetFile()->GetPanose(pPanose);
|
||||
for ( int i = 0; i < 10; i++ )
|
||||
{
|
||||
m_oFont.m_strPANOSE += ToHexString(pPanose[i]);
|
||||
}
|
||||
|
||||
// IsFixed
|
||||
m_oFont.m_bIsFixedWidth = m_pManager->GetFile()->IsFixedWidth();
|
||||
|
||||
// Signature
|
||||
m_oFont.m_arSignature.clear();
|
||||
|
||||
for ( unsigned int i = 0; i < 6; i++ )
|
||||
{
|
||||
DWORD value = 0;
|
||||
|
||||
for ( unsigned long bit = 0; bit < 32; bit++ )
|
||||
{
|
||||
if (m_pManager->GetFile()->IsUnicodeRangeAvailable(bit, i))
|
||||
{
|
||||
value |= ( 1 << bit );
|
||||
}
|
||||
}
|
||||
|
||||
m_oFont.m_arSignature.push_back(value);
|
||||
}
|
||||
}
|
||||
|
||||
void CFontManagerBase::CheckRanges(UINT& lRange1, UINT& lRange2, UINT& lRange3, UINT& lRange4, BYTE& lRangeNum, BYTE& lRange)
|
||||
{
|
||||
if (0 == lRangeNum)
|
||||
lRange1 |= 1 << lRange;
|
||||
else if (1 == lRangeNum)
|
||||
lRange2 |= 1 << lRange;
|
||||
else if (2 == lRangeNum)
|
||||
lRange3 |= 1 << lRange;
|
||||
else
|
||||
lRange4 |= 1 << lRange;
|
||||
}
|
||||
|
||||
bool CFontManagerBase::GenerateFontName(NSStringUtils::CStringUTF32& oText)
|
||||
{
|
||||
if (m_oFont.m_oFont.Path.empty() || oText.empty())
|
||||
{
|
||||
m_strCurrentPickFont = m_oFont.m_strFamilyName;
|
||||
m_lCurrentPictFontStyle = m_oFont.m_lStyle;
|
||||
return false;
|
||||
}
|
||||
|
||||
BYTE lRangeNum = 0xFF;
|
||||
BYTE lRange = 0xFF;
|
||||
|
||||
m_oRanges.CheckRange(oText[0], lRange, lRangeNum);
|
||||
std::list<CFontPickUp>::iterator posStart, pos;
|
||||
posStart = pos = m_arListPicUps.begin();
|
||||
|
||||
while (m_arListPicUps.end() != pos)
|
||||
{
|
||||
std::list<CFontPickUp>::iterator posOld = pos;
|
||||
CFontPickUp& oPick = *(pos++);
|
||||
if ((oPick.m_oFont.m_oFont.IsEqual2(&m_oFont.m_oFont)) && (lRangeNum == oPick.m_lRangeNum) && (lRange == oPick.m_lRange))
|
||||
{
|
||||
// нашли! ничего подбирать не нужно
|
||||
// нужно просто выкинуть этот шрифт наверх
|
||||
m_arListPicUps.splice(m_arListPicUps.begin(), m_arListPicUps, posOld);
|
||||
m_strCurrentPickFont = oPick.m_strPickFont;
|
||||
m_lCurrentPictFontStyle = oPick.m_lPickStyle;
|
||||
return false;
|
||||
}
|
||||
}
|
||||
|
||||
// не нашли...
|
||||
CFontPickUp oPick;
|
||||
oPick.m_lRangeNum = lRangeNum;
|
||||
oPick.m_lRange = lRange;
|
||||
oPick.m_oFont = m_oFont;
|
||||
oPick.m_strPickFont = m_oFont.m_strFamilyName;
|
||||
oPick.m_lPickStyle = m_oFont.m_lStyle;
|
||||
|
||||
UINT dwR1 = m_oFont.m_arSignature[0];
|
||||
UINT dwR2 = m_oFont.m_arSignature[1];
|
||||
UINT dwR3 = m_oFont.m_arSignature[2];
|
||||
UINT dwR4 = m_oFont.m_arSignature[3];
|
||||
UINT dwCodePage1 = 0;
|
||||
UINT dwCodePage2 = 0;
|
||||
|
||||
if ((lRangeNum == 1) && (lRange == 28))
|
||||
{
|
||||
dwCodePage1 = 0x80000000;
|
||||
//strText = (WCHAR)(strText[0] - 0xF000);
|
||||
}
|
||||
else if (((lRangeNum == 2) && (lRange == 3)) || ((lRangeNum == 1) && (lRange == 31)) || ((lRangeNum == 0) && (lRange == 13)))
|
||||
{
|
||||
// арабский язык!!!
|
||||
dwR1 = 1 << 13;
|
||||
dwR2 = 1 << 31;
|
||||
dwR3 = 1 << 3;
|
||||
}
|
||||
else
|
||||
{
|
||||
CheckRanges(dwR1, dwR2, dwR3, dwR4, lRangeNum, lRange);
|
||||
}
|
||||
|
||||
NSFonts::CFontSelectFormat oFormat;
|
||||
|
||||
std::wstring sFontNameSelect = L"";
|
||||
if (m_oFont.m_strFamilyName.empty() && !m_oFont.m_oFont.Path.empty())
|
||||
sFontNameSelect = m_strDefaultFont;
|
||||
else
|
||||
sFontNameSelect = m_oFont.m_strFamilyName;
|
||||
|
||||
bool bSelectBold = false;
|
||||
bool bSelectItalic = false;
|
||||
CheckFontNamePDF(sFontNameSelect, bSelectBold, bSelectItalic);
|
||||
|
||||
oFormat.wsName = new std::wstring(sFontNameSelect);
|
||||
|
||||
if (!m_oFont.m_strPANOSE.empty())
|
||||
{
|
||||
oFormat.pPanose = new BYTE[10];
|
||||
|
||||
const wchar_t* pPanoseStr = m_oFont.m_strPANOSE.c_str();
|
||||
for (int i = 0; i < 10; ++i)
|
||||
{
|
||||
oFormat.pPanose[i] = FromHexString(pPanoseStr[0], pPanoseStr[1]);
|
||||
pPanoseStr += 2;
|
||||
}
|
||||
}
|
||||
|
||||
oFormat.bBold = new INT(((m_oFont.m_lStyle & 0x01) == 0x01) ? 1 : 0);
|
||||
oFormat.bItalic = new INT(((m_oFont.m_lStyle & 0x02) == 0x02) ? 1 : 0);
|
||||
oFormat.bFixedWidth = new INT(m_oFont.m_bIsFixedWidth ? 1 : 0);
|
||||
if (-1 != m_oFont.m_lAvgWidth)
|
||||
oFormat.shAvgCharWidth = new SHORT((SHORT)m_oFont.m_lAvgWidth);
|
||||
oFormat.ulRange1 = new UINT(dwR1);
|
||||
oFormat.ulRange2 = new UINT(dwR2);
|
||||
oFormat.ulRange3 = new UINT(dwR3);
|
||||
oFormat.ulRange4 = new UINT(dwR4);
|
||||
oFormat.ulCodeRange1 = new UINT(dwCodePage1);
|
||||
oFormat.ulCodeRange2 = new UINT(dwCodePage2);
|
||||
|
||||
if (oFormat.bBold && *(oFormat.bBold) == 1 && oFormat.pPanose && oFormat.pPanose[2] < 7)
|
||||
oFormat.pPanose[2] = 7;
|
||||
|
||||
oFormat.wsDefaultName = new std::wstring(L"Arial");
|
||||
|
||||
NSFonts::CFontInfo* pInfo = m_pManager->GetFontInfoByParams(oFormat);
|
||||
|
||||
oPick.m_strPickFont = pInfo->m_wsFontName;
|
||||
oPick.m_lPickStyle = 0;
|
||||
if (pInfo->m_bBold)
|
||||
oPick.m_lPickStyle |= 0x01;
|
||||
if (pInfo->m_bItalic)
|
||||
oPick.m_lPickStyle |= 0x02;
|
||||
|
||||
m_strCurrentPickFont = oPick.m_strPickFont;
|
||||
m_lCurrentPictFontStyle = oPick.m_lPickStyle;
|
||||
|
||||
m_arListPicUps.push_front(oPick);
|
||||
return true;
|
||||
}
|
||||
|
||||
bool CFontManagerBase::CheckFontNameStyle(std::wstring& sName, const std::wstring& sStyle)
|
||||
{
|
||||
size_t nPos = 0;
|
||||
size_t nLenReplace = sStyle.length();
|
||||
bool bRet = false;
|
||||
|
||||
std::wstring sName2 = sName;
|
||||
NSStringExt::ToLower(sName2);
|
||||
|
||||
while (std::wstring::npos != (nPos = sName2.find(sStyle, nPos)))
|
||||
{
|
||||
size_t nOffset = 0;
|
||||
if ((nPos > 0) && sName2.at(nPos - 1) == '-')
|
||||
{
|
||||
--nPos;
|
||||
++nOffset;
|
||||
}
|
||||
|
||||
bRet = true;
|
||||
sName.erase(nPos, nLenReplace + nOffset);
|
||||
sName2.erase(nPos, nLenReplace + nOffset);
|
||||
}
|
||||
return bRet;
|
||||
}
|
||||
|
||||
void CFontManagerBase::CheckFontNamePDF(std::wstring& sName, bool& bBold, bool& bItalic)
|
||||
{
|
||||
if (sName.length() > 7 && sName.at(6) == '+')
|
||||
{
|
||||
bool bIsRemove = true;
|
||||
for (int nIndex = 0; nIndex < 6; nIndex++)
|
||||
{
|
||||
wchar_t nChar = sName.at(nIndex);
|
||||
if (nChar < 'A' || nChar > 'Z')
|
||||
{
|
||||
bIsRemove = false;
|
||||
break;
|
||||
}
|
||||
}
|
||||
if (bIsRemove)
|
||||
{
|
||||
sName.erase(0, 7);
|
||||
}
|
||||
}
|
||||
|
||||
CheckFontNameStyle(sName, L"regular");
|
||||
CheckFontNameStyle(sName, L"condensed");
|
||||
CheckFontNameStyle(sName, L"condensedlight");
|
||||
//CheckFontNameStyle(sName, L"light");
|
||||
|
||||
CheckFontNameStyle(sName, L"condensedbold");
|
||||
CheckFontNameStyle(sName, L"semibold");
|
||||
if (CheckFontNameStyle(sName, L"boldmt")) bBold = true;
|
||||
if (CheckFontNameStyle(sName, L"bold")) bBold = true;
|
||||
|
||||
if (CheckFontNameStyle(sName, L"italicmt")) bItalic = true;
|
||||
if (CheckFontNameStyle(sName, L"italic")) bItalic = true;
|
||||
if (CheckFontNameStyle(sName, L"oblique")) bItalic = true;
|
||||
|
||||
if (CheckFontNameStyle(sName, L"bolditalicmt")) { bBold = true; bItalic = true; }
|
||||
if (CheckFontNameStyle(sName, L"bolditalic")) { bBold = true; bItalic = true; }
|
||||
if (CheckFontNameStyle(sName, L"bold_italic")) { bBold = true; bItalic = true; }
|
||||
if (CheckFontNameStyle(sName, L"boldoblique")) { bBold = true; bItalic = true; }
|
||||
if (CheckFontNameStyle(sName, L"bold_oblique")) { bBold = true; bItalic = true; }
|
||||
}
|
||||
}
|
||||
@ -1,8 +1,7 @@
|
||||
#ifndef DOCX_RENDERER_FMB_H
|
||||
#define DOCX_RENDERER_FMB_H
|
||||
|
||||
#include "Common.h"
|
||||
#pragma once
|
||||
#include "../DesktopEditor/graphics/structures.h"
|
||||
#include "../DesktopEditor/graphics/pro/Fonts.h"
|
||||
#include "../DesktopEditor/common/StringUTF32.h"
|
||||
#include <list>
|
||||
|
||||
namespace NSFontManager
|
||||
@ -14,800 +13,143 @@ namespace NSFontManager
|
||||
return pManager;
|
||||
}
|
||||
|
||||
const double c_dInchToMM = 25.4;
|
||||
const double c_dPixToMM = 25.4 / 72.0;
|
||||
const double c_dPtToMM = 25.4 / 72.0;
|
||||
const double c_dMMToPt = 72.0 / 25.4;
|
||||
|
||||
class CUnicodeRange
|
||||
{
|
||||
public:
|
||||
BYTE RangeNum;
|
||||
BYTE Range;
|
||||
public:
|
||||
BYTE RangeNum {0};
|
||||
BYTE Range {0};
|
||||
|
||||
int Start;
|
||||
int End;
|
||||
int Start {0};
|
||||
int End {0};
|
||||
|
||||
CUnicodeRange(const int& _start = 0,
|
||||
const int& _end = 0,
|
||||
const BYTE& _range = 0,
|
||||
const BYTE& _rangenum = 0)
|
||||
{
|
||||
Range = _range;
|
||||
RangeNum = _rangenum;
|
||||
Start = _start;
|
||||
End = _end;
|
||||
}
|
||||
CUnicodeRange(const int& _start = 0,
|
||||
const int& _end = 0,
|
||||
const BYTE& _range = 0,
|
||||
const BYTE& _rangenum = 0);
|
||||
};
|
||||
|
||||
// класс для проставления Ranges для подбора шрифта по символу
|
||||
class CUnicodeRanges
|
||||
{
|
||||
public:
|
||||
std::list<CUnicodeRange> m_arRanges;
|
||||
public:
|
||||
std::list<CUnicodeRange> m_arRanges;
|
||||
|
||||
public:
|
||||
CUnicodeRanges()
|
||||
{
|
||||
// https://docs.microsoft.com/en-us/typography/opentype/spec/os2#ur
|
||||
public:
|
||||
CUnicodeRanges();
|
||||
|
||||
m_arRanges.push_back(CUnicodeRange(0x0000, 0x007F, 0, 0)); // Basic Latin
|
||||
m_arRanges.push_back(CUnicodeRange(0x0080, 0x00FF, 1, 0)); // Latin-1 Supplement
|
||||
m_arRanges.push_back(CUnicodeRange(0x0100, 0x017F, 2, 0)); // Latin Extended-A
|
||||
m_arRanges.push_back(CUnicodeRange(0x0180, 0x024F, 3, 0)); // Latin Extended-B
|
||||
m_arRanges.push_back(CUnicodeRange(0x0250, 0x02AF, 4, 0)); // IPA Extensions
|
||||
m_arRanges.push_back(CUnicodeRange(0x1D00, 0x1D7F, 4, 0)); // Phonetic Extensions
|
||||
m_arRanges.push_back(CUnicodeRange(0x1D80, 0x1DBF, 4, 0)); // Phonetic Extensions Supplement
|
||||
m_arRanges.push_back(CUnicodeRange(0x02B0, 0x02FF, 5, 0)); // Spacing Modifier Letters
|
||||
m_arRanges.push_back(CUnicodeRange(0xA700, 0xA71F, 5, 0)); // Modifier Tone Letters
|
||||
m_arRanges.push_back(CUnicodeRange(0x0300, 0x036F, 6, 0)); // Combining Diacritical Marks
|
||||
m_arRanges.push_back(CUnicodeRange(0x1DC0, 0x1DFF, 6, 0)); // Combining Diacritical Marks Supplement
|
||||
m_arRanges.push_back(CUnicodeRange(0x0370, 0x03FF, 7, 0)); // Greek and Coptic
|
||||
m_arRanges.push_back(CUnicodeRange(0x2C80, 0x2CFF, 8, 0)); // Coptic
|
||||
m_arRanges.push_back(CUnicodeRange(0x0400, 0x04FF, 9, 0)); // Cyrillic
|
||||
m_arRanges.push_back(CUnicodeRange(0x0500, 0x052F, 9, 0)); // Cyrillic Supplement
|
||||
m_arRanges.push_back(CUnicodeRange(0x2DE0, 0x2DFF, 9, 0)); // Cyrillic Extended-A
|
||||
m_arRanges.push_back(CUnicodeRange(0xA640, 0xA69F, 9, 0)); // Cyrillic Extended-B
|
||||
m_arRanges.push_back(CUnicodeRange(0x0530, 0x058F, 10, 0)); // Armenian
|
||||
m_arRanges.push_back(CUnicodeRange(0x0590, 0x05FF, 11, 0)); // Hebrew
|
||||
m_arRanges.push_back(CUnicodeRange(0xA500, 0xA63F, 12, 0)); // Vai
|
||||
m_arRanges.push_back(CUnicodeRange(0x0600, 0x06FF, 13, 0)); // Arabic
|
||||
m_arRanges.push_back(CUnicodeRange(0x0750, 0x077F, 13, 0)); // Arabic Supplement
|
||||
m_arRanges.push_back(CUnicodeRange(0x07C0, 0x07FF, 14, 0)); // NKo
|
||||
m_arRanges.push_back(CUnicodeRange(0x0900, 0x097F, 15, 0)); // Devanagari
|
||||
m_arRanges.push_back(CUnicodeRange(0x0980, 0x09FF, 16, 0)); // Bengali
|
||||
m_arRanges.push_back(CUnicodeRange(0x0A00, 0x0A7F, 17, 0)); // Gurmukhi
|
||||
m_arRanges.push_back(CUnicodeRange(0x0A80, 0x0AFF, 18, 0)); // Gujarati
|
||||
m_arRanges.push_back(CUnicodeRange(0x0B00, 0x0B7F, 19, 0)); // Oriya
|
||||
m_arRanges.push_back(CUnicodeRange(0x0B80, 0x0BFF, 20, 0)); // Tamil
|
||||
m_arRanges.push_back(CUnicodeRange(0x0C00, 0x0C7F, 21, 0)); // Telugu
|
||||
m_arRanges.push_back(CUnicodeRange(0x0C80, 0x0CFF, 22, 0)); // Kannada
|
||||
m_arRanges.push_back(CUnicodeRange(0x0D00, 0x0D7F, 23, 0)); // Malayalam
|
||||
m_arRanges.push_back(CUnicodeRange(0x0E00, 0x0E7F, 24, 0)); // Thai
|
||||
m_arRanges.push_back(CUnicodeRange(0x0E80, 0x0EFF, 25, 0)); // Lao
|
||||
m_arRanges.push_back(CUnicodeRange(0x10A0, 0x10FF, 26, 0)); // Georgian
|
||||
m_arRanges.push_back(CUnicodeRange(0x2D00, 0x2D2F, 26, 0)); // Georgian Supplement
|
||||
m_arRanges.push_back(CUnicodeRange(0x1B00, 0x1B7F, 27, 0)); // Balinese
|
||||
m_arRanges.push_back(CUnicodeRange(0x1100, 0x11FF, 28, 0)); // Hangul Jamo
|
||||
m_arRanges.push_back(CUnicodeRange(0x1E00, 0x1EFF, 29, 0)); // Latin Extended Additional
|
||||
m_arRanges.push_back(CUnicodeRange(0x2C60, 0x2C7F, 29, 0)); // Latin Extended-C
|
||||
m_arRanges.push_back(CUnicodeRange(0xA720, 0xA7FF, 29, 0)); // Latin Extended-D
|
||||
m_arRanges.push_back(CUnicodeRange(0x1F00, 0x1FFF, 30, 0)); // Greek Extended
|
||||
m_arRanges.push_back(CUnicodeRange(0x2000, 0x206F, 31, 0)); // General Punctuation
|
||||
m_arRanges.push_back(CUnicodeRange(0x2E00, 0x2E7F, 31, 0)); // Supplemental Punctuation
|
||||
void CheckRange(const int& symbol, BYTE& Range, BYTE& RangeNum);
|
||||
|
||||
m_arRanges.push_back(CUnicodeRange(0x2070, 0x209F, 0, 1)); // Superscripts And Subscripts
|
||||
m_arRanges.push_back(CUnicodeRange(0x20A0, 0x20CF, 1, 1)); // Currency Symbols
|
||||
m_arRanges.push_back(CUnicodeRange(0x20D0, 0x20FF, 2, 1)); // Combining Diacritical Marks For Symbols
|
||||
m_arRanges.push_back(CUnicodeRange(0x2100, 0x214F, 3, 1)); // Letterlike Symbols
|
||||
m_arRanges.push_back(CUnicodeRange(0x2150, 0x218F, 4, 1)); // Number Forms
|
||||
m_arRanges.push_back(CUnicodeRange(0x2190, 0x21FF, 5, 1)); // Arrows
|
||||
m_arRanges.push_back(CUnicodeRange(0x27F0, 0x27FF, 5, 1)); // Supplemental Arrows-A
|
||||
m_arRanges.push_back(CUnicodeRange(0x2900, 0x297F, 5, 1)); // Supplemental Arrows-B
|
||||
m_arRanges.push_back(CUnicodeRange(0x2B00, 0x2BFF, 5, 1)); // Miscellaneous Symbols and Arrows
|
||||
m_arRanges.push_back(CUnicodeRange(0x2200, 0x22FF, 6, 1)); // Mathematical Operators
|
||||
m_arRanges.push_back(CUnicodeRange(0x2A00, 0x2AFF, 6, 1)); // Supplemental Mathematical Operators
|
||||
m_arRanges.push_back(CUnicodeRange(0x27C0, 0x27EF, 6, 1)); // Miscellaneous Mathematical Symbols-A
|
||||
m_arRanges.push_back(CUnicodeRange(0x2980, 0x29FF, 6, 1)); // Miscellaneous Mathematical Symbols-B
|
||||
m_arRanges.push_back(CUnicodeRange(0x2300, 0x23FF, 7, 1)); // Miscellaneous Technical
|
||||
m_arRanges.push_back(CUnicodeRange(0x2400, 0x243F, 8, 1)); // Control Pictures
|
||||
m_arRanges.push_back(CUnicodeRange(0x2440, 0x245F, 9, 1)); // Optical Character Recognition
|
||||
m_arRanges.push_back(CUnicodeRange(0x2460, 0x24FF, 10, 1)); // Enclosed Alphanumerics
|
||||
m_arRanges.push_back(CUnicodeRange(0x2500, 0x257F, 11, 1)); // Box Drawing
|
||||
m_arRanges.push_back(CUnicodeRange(0x2580, 0x259F, 12, 1)); // Block Elements
|
||||
m_arRanges.push_back(CUnicodeRange(0x25A0, 0x25FF, 13, 1)); // Geometric Shapes
|
||||
m_arRanges.push_back(CUnicodeRange(0x2600, 0x26FF, 14, 1)); // Miscellaneous Symbols
|
||||
m_arRanges.push_back(CUnicodeRange(0x2700, 0x27BF, 15, 1)); // Dingbats
|
||||
m_arRanges.push_back(CUnicodeRange(0x3000, 0x303F, 16, 1)); // CJK Symbols And Punctuation
|
||||
m_arRanges.push_back(CUnicodeRange(0x3040, 0x309F, 17, 1)); // Hiragana
|
||||
m_arRanges.push_back(CUnicodeRange(0x30A0, 0x30FF, 18, 1)); // Katakana
|
||||
m_arRanges.push_back(CUnicodeRange(0x31F0, 0x31FF, 18, 1)); // Katakana Phonetic Extensions
|
||||
m_arRanges.push_back(CUnicodeRange(0x3100, 0x312F, 19, 1)); // Bopomofo
|
||||
m_arRanges.push_back(CUnicodeRange(0x31A0, 0x31BF, 19, 1)); // Bopomofo Extended
|
||||
m_arRanges.push_back(CUnicodeRange(0x3130, 0x318F, 20, 1)); // Hangul Compatibility Jamo
|
||||
m_arRanges.push_back(CUnicodeRange(0xA840, 0xA87F, 21, 1)); // Phags-pa
|
||||
m_arRanges.push_back(CUnicodeRange(0x3200, 0x32FF, 22, 1)); // Enclosed CJK Letters And Months
|
||||
m_arRanges.push_back(CUnicodeRange(0x3300, 0x33FF, 23, 1)); // CJK Compatibility
|
||||
m_arRanges.push_back(CUnicodeRange(0xAC00, 0xD7AF, 24, 1)); // Hangul Syllables
|
||||
m_arRanges.push_back(CUnicodeRange(0x10000, 0x10FFFF, 25, 1)); // Non-Plane 0
|
||||
m_arRanges.push_back(CUnicodeRange(0x10900, 0x1091F, 26, 1)); // Phoenician
|
||||
m_arRanges.push_back(CUnicodeRange(0x4E00, 0x9FFF, 27, 1)); // CJK Unified Ideographs
|
||||
m_arRanges.push_back(CUnicodeRange(0x2E80, 0x2EFF, 27, 1)); // CJK Radicals Supplement
|
||||
m_arRanges.push_back(CUnicodeRange(0x2F00, 0x2FDF, 27, 1)); // Kangxi Radicals
|
||||
m_arRanges.push_back(CUnicodeRange(0x2FF0, 0x2FFF, 27, 1)); // Ideographic Description Characters
|
||||
m_arRanges.push_back(CUnicodeRange(0x3400, 0x4DBF, 27, 1)); // CJK Unified Ideographs Extension A
|
||||
m_arRanges.push_back(CUnicodeRange(0x3190, 0x319F, 27, 1)); // Kanbun
|
||||
m_arRanges.push_back(CUnicodeRange(0x20000, 0x2A6DF, 27, 1)); // CJK Unified Ideographs Extension B
|
||||
m_arRanges.push_back(CUnicodeRange(0xE000, 0xF8FF, 28, 1)); // Private Use Area (plane 0)
|
||||
m_arRanges.push_back(CUnicodeRange(0x31C0, 0x31EF, 29, 1)); // CJK Strokes
|
||||
m_arRanges.push_back(CUnicodeRange(0xF900, 0xFAFF, 29, 1)); // CJK Compatibility Ideographs
|
||||
m_arRanges.push_back(CUnicodeRange(0x2F800, 0x2FA1F, 29, 1)); // CJK Compatibility Ideographs Supplement
|
||||
m_arRanges.push_back(CUnicodeRange(0xFB00, 0xFB4F, 30, 1)); // Alphabetic Presentation Forms
|
||||
m_arRanges.push_back(CUnicodeRange(0xFB50, 0xFDFF, 31, 1)); // Arabic Presentation Forms-A
|
||||
|
||||
m_arRanges.push_back(CUnicodeRange(0xFE20, 0xFE2F, 0, 2)); // Combining Half Marks
|
||||
m_arRanges.push_back(CUnicodeRange(0xFE10, 0xFE1F, 1, 2)); // Vertical Forms
|
||||
m_arRanges.push_back(CUnicodeRange(0xFE30, 0xFE4F, 1, 2)); // CJK Compatibility Forms
|
||||
m_arRanges.push_back(CUnicodeRange(0xFE50, 0xFE6F, 2, 2)); // Small Form Variants
|
||||
m_arRanges.push_back(CUnicodeRange(0xFE70, 0xFEFF, 3, 2)); // Arabic Presentation Forms-B
|
||||
m_arRanges.push_back(CUnicodeRange(0xFF00, 0xFFEF, 4, 2)); // Halfwidth And Fullwidth Forms
|
||||
m_arRanges.push_back(CUnicodeRange(0xFFF0, 0xFFFF, 5, 2)); // Specials
|
||||
m_arRanges.push_back(CUnicodeRange(0x0F00, 0x0FFF, 6, 2)); // Tibetan
|
||||
m_arRanges.push_back(CUnicodeRange(0x0700, 0x074F, 7, 2)); // Syriac
|
||||
m_arRanges.push_back(CUnicodeRange(0x0780, 0x07BF, 8, 2)); // Thaana
|
||||
m_arRanges.push_back(CUnicodeRange(0x0D80, 0x0DFF, 9, 2)); // Sinhala
|
||||
m_arRanges.push_back(CUnicodeRange(0x1000, 0x109F, 10, 2)); // Myanmar
|
||||
m_arRanges.push_back(CUnicodeRange(0x1200, 0x137F, 11, 2)); // Ethiopic
|
||||
m_arRanges.push_back(CUnicodeRange(0x1380, 0x139F, 11, 2)); // Ethiopic Supplement
|
||||
m_arRanges.push_back(CUnicodeRange(0x2D80, 0x2DDF, 11, 2)); // Ethiopic Extended
|
||||
m_arRanges.push_back(CUnicodeRange(0x13A0, 0x13FF, 12, 2)); // Cherokee
|
||||
m_arRanges.push_back(CUnicodeRange(0x1400, 0x167F, 13, 2)); // Unified Canadian Aboriginal Syllabics
|
||||
m_arRanges.push_back(CUnicodeRange(0x1680, 0x169F, 14, 2)); // Ogham
|
||||
m_arRanges.push_back(CUnicodeRange(0x16A0, 0x16FF, 15, 2)); // Runic
|
||||
m_arRanges.push_back(CUnicodeRange(0x1780, 0x17FF, 16, 2)); // Khmer
|
||||
m_arRanges.push_back(CUnicodeRange(0x19E0, 0x19FF, 16, 2)); // Khmer Symbols
|
||||
m_arRanges.push_back(CUnicodeRange(0x1800, 0x18AF, 17, 2)); // Mongolian
|
||||
m_arRanges.push_back(CUnicodeRange(0x2800, 0x28FF, 18, 2)); // Braille Patterns
|
||||
m_arRanges.push_back(CUnicodeRange(0xA000, 0xA48F, 19, 2)); // Yi Syllables
|
||||
m_arRanges.push_back(CUnicodeRange(0xA490, 0xA4CF, 19, 2)); // Yi Radicals
|
||||
m_arRanges.push_back(CUnicodeRange(0x1700, 0x171F, 20, 2)); // Tagalog
|
||||
m_arRanges.push_back(CUnicodeRange(0x1720, 0x173F, 20, 2)); // Hanunoo
|
||||
m_arRanges.push_back(CUnicodeRange(0x1740, 0x175F, 20, 2)); // Buhid
|
||||
m_arRanges.push_back(CUnicodeRange(0x1760, 0x177F, 20, 2)); // Tagbanwa
|
||||
m_arRanges.push_back(CUnicodeRange(0x10300, 0x1032F, 21, 2)); // Old Italic
|
||||
m_arRanges.push_back(CUnicodeRange(0x10330, 0x1034F, 22, 2)); // Gothic
|
||||
m_arRanges.push_back(CUnicodeRange(0x10400, 0x1044F, 23, 2)); // Deseret
|
||||
m_arRanges.push_back(CUnicodeRange(0x1D000, 0x1D0FF, 24, 2)); // Byzantine Musical Symbols
|
||||
m_arRanges.push_back(CUnicodeRange(0x1D100, 0x1D1FF, 24, 2)); // Musical Symbols
|
||||
m_arRanges.push_back(CUnicodeRange(0x1D200, 0x1D24F, 24, 2)); // Ancient Greek Musical Notation
|
||||
m_arRanges.push_back(CUnicodeRange(0x1D400, 0x1D7FF, 25, 2)); // Mathematical Alphanumeric Symbols
|
||||
m_arRanges.push_back(CUnicodeRange(0xF0000, 0xFFFFD, 26, 2)); // Private Use (plane 15)
|
||||
m_arRanges.push_back(CUnicodeRange(0x100000, 0x10FFFD, 26, 2)); // Private Use (plane 16)
|
||||
m_arRanges.push_back(CUnicodeRange(0xFE00, 0xFE0F, 27, 2)); // Variation Selectors
|
||||
m_arRanges.push_back(CUnicodeRange(0xE0100, 0xE01EF, 27, 2)); // Variation Selectors Supplement
|
||||
m_arRanges.push_back(CUnicodeRange(0xE0000, 0xE007F, 28, 2)); // Tags
|
||||
m_arRanges.push_back(CUnicodeRange(0x1900, 0x194F, 29, 2)); // Limbu
|
||||
m_arRanges.push_back(CUnicodeRange(0x1950, 0x197F, 30, 2)); // Tai Le
|
||||
m_arRanges.push_back(CUnicodeRange(0x1980, 0x19DF, 31, 2)); // New Tai Lue
|
||||
|
||||
m_arRanges.push_back(CUnicodeRange(0x1A00, 0x1A1F, 0, 3)); // Buginese
|
||||
m_arRanges.push_back(CUnicodeRange(0x2C00, 0x2C5F, 1, 3)); // Glagolitic
|
||||
m_arRanges.push_back(CUnicodeRange(0x2D30, 0x2D7F, 2, 3)); // Tifinagh
|
||||
m_arRanges.push_back(CUnicodeRange(0x4DC0, 0x4DFF, 3, 3)); // Yijing Hexagram Symbols
|
||||
m_arRanges.push_back(CUnicodeRange(0xA800, 0xA82F, 4, 3)); // Syloti Nagri
|
||||
m_arRanges.push_back(CUnicodeRange(0x10000, 0x1007F, 5, 3)); // Linear B Syllabary
|
||||
m_arRanges.push_back(CUnicodeRange(0x10080, 0x100FF, 5, 3)); // Linear B Ideograms
|
||||
m_arRanges.push_back(CUnicodeRange(0x10100, 0x1013F, 5, 3)); // Aegean Numbers
|
||||
m_arRanges.push_back(CUnicodeRange(0x10140, 0x1018F, 6, 3)); // Ancient Greek Numbers
|
||||
m_arRanges.push_back(CUnicodeRange(0x10380, 0x1039F, 7, 3)); // Ugaritic
|
||||
m_arRanges.push_back(CUnicodeRange(0x103A0, 0x103DF, 8, 3)); // Old Persian
|
||||
m_arRanges.push_back(CUnicodeRange(0x10450, 0x1047F, 9, 3)); // Shavian
|
||||
m_arRanges.push_back(CUnicodeRange(0x10480, 0x104AF, 10, 3)); // Osmanya
|
||||
m_arRanges.push_back(CUnicodeRange(0x10800, 0x1083F, 11, 3)); // Cypriot Syllabary
|
||||
m_arRanges.push_back(CUnicodeRange(0x10A00, 0x10A5F, 12, 3)); // Kharoshthi
|
||||
m_arRanges.push_back(CUnicodeRange(0x1D300, 0x1D35F, 13, 3)); // Tai Xuan Jing Symbols
|
||||
m_arRanges.push_back(CUnicodeRange(0x12000, 0x123FF, 14, 3)); // Cuneiform
|
||||
m_arRanges.push_back(CUnicodeRange(0x12400, 0x1247F, 14, 3)); // Cuneiform Numbers and Punctuation
|
||||
m_arRanges.push_back(CUnicodeRange(0x1D360, 0x1D37F, 15, 3)); // Counting Rod Numerals
|
||||
m_arRanges.push_back(CUnicodeRange(0x1B80, 0x1BBF, 16, 3)); // Sundanese
|
||||
m_arRanges.push_back(CUnicodeRange(0x1C00, 0x1C4F, 17, 3)); // Lepcha
|
||||
m_arRanges.push_back(CUnicodeRange(0x1C50, 0x1C7F, 18, 3)); // Ol Chiki
|
||||
m_arRanges.push_back(CUnicodeRange(0xA880, 0xA8DF, 19, 3)); // Saurashtra
|
||||
m_arRanges.push_back(CUnicodeRange(0xA900, 0xA92F, 20, 3)); // Kayah Li
|
||||
m_arRanges.push_back(CUnicodeRange(0xA930, 0xA95F, 21, 3)); // Rejang
|
||||
m_arRanges.push_back(CUnicodeRange(0xAA00, 0xAA5F, 22, 3)); // Cham
|
||||
m_arRanges.push_back(CUnicodeRange(0x10190, 0x101CF, 23, 3)); // Ancient Symbols
|
||||
m_arRanges.push_back(CUnicodeRange(0x101D0, 0x101FF, 24, 3)); // Phaistos Disc
|
||||
m_arRanges.push_back(CUnicodeRange(0x102A0, 0x102DF, 25, 3)); // Carian
|
||||
m_arRanges.push_back(CUnicodeRange(0x10280, 0x1029F, 25, 3)); // Lycian
|
||||
m_arRanges.push_back(CUnicodeRange(0x10920, 0x1093F, 25, 3)); // Lydian
|
||||
m_arRanges.push_back(CUnicodeRange(0x1F030, 0x1F09F, 26, 3)); // Domino Tiles
|
||||
m_arRanges.push_back(CUnicodeRange(0x1F000, 0x1F02F, 26, 3)); // Mahjong Tiles
|
||||
// 27: "Reserved for process-internal usage"
|
||||
// 28: "Reserved for process-internal usage"
|
||||
// 29: "Reserved for process-internal usage"
|
||||
// 30: "Reserved for process-internal usage"
|
||||
// 31: "Reserved for process-internal usage"
|
||||
}
|
||||
|
||||
void CheckRange(const int& symbol, BYTE& Range, BYTE& RangeNum)
|
||||
{
|
||||
// определяем range и двигаем его в начало.
|
||||
std::list<CUnicodeRange>::iterator iter = m_arRanges.begin();
|
||||
while (iter != m_arRanges.end())
|
||||
{
|
||||
CUnicodeRange& range = *iter;
|
||||
if (symbol >= range.Start && symbol <= range.End)
|
||||
{
|
||||
Range = range.Range;
|
||||
RangeNum = range.RangeNum;
|
||||
|
||||
m_arRanges.splice(m_arRanges.begin(), m_arRanges, iter);
|
||||
return;
|
||||
}
|
||||
iter++;
|
||||
}
|
||||
}
|
||||
|
||||
void CheckRange(const int& symbol, int& Range1, int& Range2, int& Range3, int& Range4)
|
||||
{
|
||||
BYTE nRange = 0xFF;
|
||||
BYTE nRangeNum = 0xFF;
|
||||
CheckRange(symbol, nRange, nRangeNum);
|
||||
|
||||
switch (nRangeNum)
|
||||
{
|
||||
case 0: Range1 |= (1 << nRange); break;
|
||||
case 1: Range2 |= (1 << nRange); break;
|
||||
case 2: Range3 |= (1 << nRange); break;
|
||||
case 3: Range4 |= (1 << nRange); break;
|
||||
default:
|
||||
break;
|
||||
}
|
||||
}
|
||||
void CheckRange(const int& symbol, int& Range1, int& Range2, int& Range3, int& Range4);
|
||||
};
|
||||
|
||||
class CFontAdvanced
|
||||
{
|
||||
public:
|
||||
NSStructures::CFont m_oFont;
|
||||
class CFontAdvanced
|
||||
{
|
||||
public:
|
||||
NSStructures::CFont m_oFont;
|
||||
|
||||
// font metrics
|
||||
double m_dAscent;
|
||||
double m_dDescent;
|
||||
double m_dLineSpacing;
|
||||
double m_dEmHeight;
|
||||
// font metrics
|
||||
double m_dAscent {0.0};
|
||||
double m_dDescent {0.0};
|
||||
double m_dLineSpacing {0.0};
|
||||
double m_dEmHeight {0.0};
|
||||
|
||||
double m_dBaselineOffset;
|
||||
double m_dBaselineOffset {0.0};
|
||||
|
||||
double m_dSpaceWidthMM;
|
||||
double m_dSpaceWidthMM {0.0};
|
||||
|
||||
// font params
|
||||
std::wstring m_strFamilyName;
|
||||
std::wstring m_strPANOSE;
|
||||
LONG m_lStyle;
|
||||
std::vector<UINT> m_arSignature;
|
||||
bool m_bIsFixedWidth;
|
||||
SHORT m_lAvgWidth;
|
||||
// font params
|
||||
std::wstring m_strFamilyName {L""};
|
||||
std::wstring m_strPANOSE {L""};
|
||||
LONG m_lStyle {0};
|
||||
std::vector<UINT> m_arSignature;
|
||||
bool m_bIsFixedWidth {false};
|
||||
SHORT m_lAvgWidth {-1};
|
||||
|
||||
public:
|
||||
CFontAdvanced()
|
||||
{
|
||||
m_oFont.SetDefaultParams();
|
||||
public:
|
||||
CFontAdvanced();
|
||||
|
||||
m_dAscent = 0;
|
||||
m_dDescent = 0;
|
||||
m_dLineSpacing = 0;
|
||||
m_dEmHeight = 0;
|
||||
CFontAdvanced(const CFontAdvanced& oSrc);
|
||||
|
||||
m_dBaselineOffset = 0;
|
||||
CFontAdvanced& operator=(const CFontAdvanced& oSrc);
|
||||
};
|
||||
|
||||
m_dSpaceWidthMM = 0;
|
||||
class CFontPickUp
|
||||
{
|
||||
public:
|
||||
CFontAdvanced m_oFont;
|
||||
BYTE m_lRangeNum {0xFF};
|
||||
BYTE m_lRange {0xFF};
|
||||
std::wstring m_strPickFont {L""};
|
||||
LONG m_lPickStyle {0};
|
||||
|
||||
m_strFamilyName = L"";
|
||||
m_strPANOSE = L"";
|
||||
m_lStyle = 0;
|
||||
m_arSignature.clear();
|
||||
m_bIsFixedWidth = false;
|
||||
m_lAvgWidth = -1;
|
||||
}
|
||||
public:
|
||||
CFontPickUp();
|
||||
CFontPickUp(const CFontPickUp& oSrc);
|
||||
CFontPickUp& operator=(const CFontPickUp& oSrc);
|
||||
};
|
||||
|
||||
CFontAdvanced(const CFontAdvanced& oSrc)
|
||||
{
|
||||
*this = oSrc;
|
||||
}
|
||||
|
||||
CFontAdvanced& operator=(const CFontAdvanced& oSrc)
|
||||
{
|
||||
m_oFont = oSrc.m_oFont;
|
||||
|
||||
m_dAscent = oSrc.m_dAscent;
|
||||
m_dDescent = oSrc.m_dDescent;
|
||||
m_dLineSpacing = oSrc.m_dLineSpacing;
|
||||
m_dEmHeight = oSrc.m_dEmHeight;
|
||||
|
||||
m_dBaselineOffset = oSrc.m_dBaselineOffset;
|
||||
|
||||
m_dSpaceWidthMM = oSrc.m_dSpaceWidthMM;
|
||||
|
||||
m_strFamilyName = oSrc.m_strFamilyName;
|
||||
m_strPANOSE = oSrc.m_strPANOSE;
|
||||
m_lStyle = oSrc.m_lStyle;
|
||||
m_arSignature = m_arSignature;
|
||||
m_bIsFixedWidth = oSrc.m_bIsFixedWidth;
|
||||
m_lAvgWidth = oSrc.m_lAvgWidth;
|
||||
|
||||
return *this;
|
||||
}
|
||||
};
|
||||
|
||||
class CFontPickUp
|
||||
{
|
||||
public:
|
||||
CFontAdvanced m_oFont;
|
||||
BYTE m_lRangeNum;
|
||||
BYTE m_lRange;
|
||||
std::wstring m_strPickFont;
|
||||
LONG m_lPickStyle;
|
||||
|
||||
public:
|
||||
CFontPickUp() : m_oFont()
|
||||
{
|
||||
m_lRangeNum = 0xFF;
|
||||
m_lRange = 0xFF;
|
||||
m_strPickFont = L"";
|
||||
m_lPickStyle = 0;
|
||||
}
|
||||
CFontPickUp(const CFontPickUp& oSrc)
|
||||
{
|
||||
*this = oSrc;
|
||||
}
|
||||
CFontPickUp& operator=(const CFontPickUp& oSrc)
|
||||
{
|
||||
m_oFont = oSrc.m_oFont;
|
||||
m_lRange = oSrc.m_lRange;
|
||||
m_lRangeNum = oSrc.m_lRangeNum;
|
||||
m_strPickFont = oSrc.m_strPickFont;
|
||||
m_lPickStyle = oSrc.m_lPickStyle;
|
||||
|
||||
return *this;
|
||||
}
|
||||
};
|
||||
|
||||
class CFontManagerBase
|
||||
{
|
||||
public:
|
||||
enum MeasureType
|
||||
{
|
||||
MeasureTypeGlyph = 0,
|
||||
MeasureTypePosition = 1
|
||||
};
|
||||
|
||||
protected:
|
||||
NSFonts::IFontManager* m_pManager;
|
||||
std::wstring m_strDefaultFont;
|
||||
|
||||
public:
|
||||
|
||||
CFontAdvanced m_oFont;
|
||||
|
||||
//для подбора шрифтов
|
||||
CUnicodeRanges m_oRanges;
|
||||
|
||||
std::list<CFontPickUp> m_arListPicUps;
|
||||
std::wstring m_strCurrentPickFont;
|
||||
LONG m_lCurrentPictFontStyle;
|
||||
|
||||
public:
|
||||
CFontManagerBase(NSFonts::IApplicationFonts* pFonts) : m_oFont()
|
||||
{
|
||||
m_pManager = NSFontManager::CreateFontManager(pFonts);
|
||||
|
||||
SetDefaultFont(L"Arial");
|
||||
|
||||
ClearPickUps();
|
||||
}
|
||||
virtual ~CFontManagerBase()
|
||||
{
|
||||
RELEASEINTERFACE(m_pManager);
|
||||
}
|
||||
|
||||
void ClearPickUps()
|
||||
{
|
||||
m_arListPicUps.clear();
|
||||
m_strCurrentPickFont = L"";
|
||||
m_lCurrentPictFontStyle = 0;
|
||||
}
|
||||
|
||||
public:
|
||||
void SetDefaultFont(const std::wstring& strName)
|
||||
{
|
||||
m_strDefaultFont = strName;
|
||||
}
|
||||
std::wstring GetDefaultFont()
|
||||
{
|
||||
return m_strDefaultFont;
|
||||
}
|
||||
|
||||
virtual void LoadFont(long lFaceIndex = 0, bool bIsNeedAddToMap = true)
|
||||
{
|
||||
}
|
||||
|
||||
void LoadFontByName(const std::wstring& strName, const double& dSize, const LONG& lStyle, const double& dDpiX, const double& dDpiY)
|
||||
{
|
||||
m_pManager->LoadFontByName(strName, (float)dSize, lStyle, dDpiX, dDpiY);
|
||||
m_pManager->AfterLoad();
|
||||
|
||||
LoadFontMetrics();
|
||||
LoadFontParams();
|
||||
|
||||
m_oFont.m_lAvgWidth = -1;
|
||||
}
|
||||
|
||||
void LoadFontByFile(const std::wstring& strPath, const double& dSize, const double& dDpiX, const double& dDpiY, const LONG& lFaceIndex)
|
||||
{
|
||||
m_pManager->LoadFontFromFile(strPath, (int)lFaceIndex, (float)dSize, dDpiX, dDpiY);
|
||||
m_pManager->AfterLoad();
|
||||
|
||||
LoadFontMetrics();
|
||||
LoadFontParams();
|
||||
m_oFont.m_oFont.Name = m_pManager->GetName();
|
||||
m_oFont.m_strFamilyName = m_oFont.m_oFont.Name;
|
||||
|
||||
m_oFont.m_lAvgWidth = -1;
|
||||
|
||||
bool bIsCID = false;
|
||||
std::wstring sFileExt = NSFile::GetFileExtention(strPath);
|
||||
if (std::wstring::npos != sFileExt.find(L"cid"))
|
||||
bIsCID = true;
|
||||
|
||||
std::wstring sFileName = NSFile::GetFileName(strPath);
|
||||
std::wstring::size_type pos = sFileName.rfind('.');
|
||||
if (std::wstring::npos != pos)
|
||||
sFileName = sFileName.substr(0, pos);
|
||||
std::wstring sEncFilePath = NSFile::GetDirectoryName(strPath) + L"/" + sFileName + L".enc";
|
||||
|
||||
XmlUtils::CXmlNode oMainNode;
|
||||
oMainNode.FromXmlFile(sEncFilePath);
|
||||
|
||||
if (L"PDF-resources" == oMainNode.GetName())
|
||||
{
|
||||
if (bIsCID)
|
||||
{
|
||||
XmlUtils::CXmlNode oType0Node;
|
||||
if ( oMainNode.GetNode( L"Type0", oType0Node ) )
|
||||
{
|
||||
XmlUtils::CXmlNode oNode;
|
||||
if ( oType0Node.GetNode( L"DescendantFonts", oNode ) )
|
||||
{
|
||||
XmlUtils::CXmlNode oDescNode;
|
||||
if ( oNode.GetNode( L"FontDescriptor", oDescNode ) )
|
||||
{
|
||||
XmlUtils::CXmlNode oCurNode;
|
||||
if ( oNode.GetNode( L"AvgWidth", oCurNode ) )
|
||||
{
|
||||
std::wstring sValue = oCurNode.GetAttribute(L"value");
|
||||
try {
|
||||
m_oFont.m_lAvgWidth = (SHORT)std::stol(sValue);
|
||||
} catch (std::invalid_argument &) {}
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
else
|
||||
{
|
||||
XmlUtils::CXmlNode oNode;
|
||||
if ( oMainNode.GetNode( L"FontDescriptor", oNode ) )
|
||||
{
|
||||
XmlUtils::CXmlNode oCurNode;
|
||||
if ( oNode.GetNode( L"AvgWidth", oCurNode ) )
|
||||
{
|
||||
std::wstring sValue = oCurNode.GetAttribute(L"value");
|
||||
try {
|
||||
m_oFont.m_lAvgWidth = (SHORT)std::stol(sValue);
|
||||
} catch (std::invalid_argument &) {}
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
public:
|
||||
virtual void MeasureString(const std::wstring& sText, double x, double y, double& dBoxX, double& dBoxY, double& dBoxWidth, double& dBoxHeight, MeasureType measureType)
|
||||
{
|
||||
}
|
||||
virtual void CalculateBaselineOffset()
|
||||
{
|
||||
LoadFont();
|
||||
|
||||
double d1 = 3 * (m_oFont.m_dLineSpacing - m_oFont.m_dDescent) - m_oFont.m_dAscent;
|
||||
d1 /= 2.0;
|
||||
|
||||
d1 *= (m_oFont.m_oFont.Size / m_oFont.m_dEmHeight);
|
||||
m_oFont.m_dBaselineOffset = d1;
|
||||
}
|
||||
|
||||
public:
|
||||
void LoadFontMetrics()
|
||||
{
|
||||
m_oFont.m_dAscent = m_pManager->GetAscender();
|
||||
m_oFont.m_dDescent = m_pManager->GetDescender();
|
||||
m_oFont.m_dLineSpacing = m_pManager->GetLineHeight();
|
||||
m_oFont.m_dEmHeight = m_pManager->GetUnitsPerEm();
|
||||
|
||||
m_oFont.m_dBaselineOffset = (c_dPtToMM * m_oFont.m_dDescent * m_oFont.m_oFont.Size / m_oFont.m_dEmHeight);
|
||||
}
|
||||
|
||||
std::wstring ToHexString( BYTE uc )
|
||||
{
|
||||
std::wstring sRet = L"";
|
||||
char c1 = (char)(uc >> 4);
|
||||
char c2 = (char)(uc & 0x0F);
|
||||
sRet += (wchar_t)((c1 < 10) ? ('0' + c1) : ('A' + c1 - 10));
|
||||
sRet += (wchar_t)((c2 < 10) ? ('0' + c2) : ('A' + c2 - 10));
|
||||
return sRet;
|
||||
}
|
||||
BYTE FromHexString( wchar_t c1, wchar_t c2 )
|
||||
{
|
||||
BYTE res = 0;
|
||||
res |= ((c1 >= 'A') ? (c1 - 'A' + 10) : (c1 - '0'));
|
||||
res <<= 4;
|
||||
res |= ((c2 >= 'A') ? (c2 - 'A' + 10) : (c2 - '0'));
|
||||
return res;
|
||||
}
|
||||
|
||||
void LoadFontParams(bool bIsPath = true)
|
||||
{
|
||||
// читаем и выставляем все настройки шрифта
|
||||
if (NULL == m_pManager || NULL == m_pManager->GetFile())
|
||||
return;
|
||||
|
||||
m_oFont.m_strFamilyName = m_oFont.m_oFont.Name;
|
||||
|
||||
m_oFont.m_lStyle = 0x00;
|
||||
if (m_pManager->GetFile()->IsBold())
|
||||
{
|
||||
m_oFont.m_lStyle |= 0x01;
|
||||
}
|
||||
if (m_pManager->GetFile()->IsItalic())
|
||||
{
|
||||
m_oFont.m_lStyle |= 0x02;
|
||||
}
|
||||
|
||||
// PANOSE
|
||||
BYTE pPanose[10];
|
||||
m_pManager->GetFile()->GetPanose(pPanose);
|
||||
for ( int i = 0; i < 10; i++ )
|
||||
class CFontManagerBase
|
||||
{
|
||||
public:
|
||||
enum MeasureType
|
||||
{
|
||||
m_oFont.m_strPANOSE += ToHexString(pPanose[i]);
|
||||
}
|
||||
mtGlyph = 0,
|
||||
mtPosition = 1
|
||||
};
|
||||
|
||||
// IsFixed
|
||||
m_oFont.m_bIsFixedWidth = m_pManager->GetFile()->IsFixedWidth();
|
||||
protected:
|
||||
NSFonts::IFontManager* m_pManager;
|
||||
std::wstring m_strDefaultFont;
|
||||
|
||||
// Signature
|
||||
m_oFont.m_arSignature.clear();
|
||||
public:
|
||||
|
||||
for ( unsigned int i = 0; i < 6; i++ )
|
||||
{
|
||||
DWORD value = 0;
|
||||
CFontAdvanced m_oFont;
|
||||
|
||||
for ( unsigned long bit = 0; bit < 32; bit++ )
|
||||
{
|
||||
if (m_pManager->GetFile()->IsUnicodeRangeAvailable(bit, i))
|
||||
{
|
||||
value |= ( 1 << bit );
|
||||
}
|
||||
}
|
||||
//для подбора шрифтов
|
||||
CUnicodeRanges m_oRanges;
|
||||
|
||||
m_oFont.m_arSignature.push_back(value);
|
||||
}
|
||||
}
|
||||
std::list<CFontPickUp> m_arListPicUps;
|
||||
std::wstring m_strCurrentPickFont;
|
||||
LONG m_lCurrentPictFontStyle;
|
||||
|
||||
private:
|
||||
inline void CheckRanges(UINT& lRange1, UINT& lRange2, UINT& lRange3, UINT& lRange4, BYTE& lRangeNum, BYTE& lRange)
|
||||
{
|
||||
if (0 == lRangeNum)
|
||||
lRange1 |= 1 << lRange;
|
||||
else if (1 == lRangeNum)
|
||||
lRange2 |= 1 << lRange;
|
||||
else if (2 == lRangeNum)
|
||||
lRange3 |= 1 << lRange;
|
||||
else
|
||||
lRange4 |= 1 << lRange;
|
||||
}
|
||||
public:
|
||||
CFontManagerBase(NSFonts::IApplicationFonts* pFonts);
|
||||
virtual ~CFontManagerBase();
|
||||
|
||||
|
||||
public:
|
||||
bool GenerateFontName(NSStringUtils::CStringUTF32& oText)
|
||||
{
|
||||
if (m_oFont.m_oFont.Path.empty() || oText.empty())
|
||||
{
|
||||
m_strCurrentPickFont = m_oFont.m_strFamilyName;
|
||||
m_lCurrentPictFontStyle = m_oFont.m_lStyle;
|
||||
return false;
|
||||
}
|
||||
void ClearPickUps();
|
||||
|
||||
BYTE lRangeNum = 0xFF;
|
||||
BYTE lRange = 0xFF;
|
||||
public:
|
||||
void SetDefaultFont(const std::wstring& strName);
|
||||
std::wstring GetDefaultFont();
|
||||
|
||||
m_oRanges.CheckRange(oText[0], lRange, lRangeNum);
|
||||
std::list<CFontPickUp>::iterator posStart, pos;
|
||||
posStart = pos = m_arListPicUps.begin();
|
||||
virtual void LoadFont(long lFaceIndex = 0, bool bIsNeedAddToMap = true);
|
||||
|
||||
while (m_arListPicUps.end() != pos)
|
||||
{
|
||||
std::list<CFontPickUp>::iterator posOld = pos;
|
||||
CFontPickUp& oPick = *(pos++);
|
||||
if ((oPick.m_oFont.m_oFont.IsEqual2(&m_oFont.m_oFont)) && (lRangeNum == oPick.m_lRangeNum) && (lRange == oPick.m_lRange))
|
||||
{
|
||||
// нашли! ничего подбирать не нужно
|
||||
// нужно просто выкинуть этот шрифт наверх
|
||||
m_arListPicUps.splice(m_arListPicUps.begin(), m_arListPicUps, posOld);
|
||||
m_strCurrentPickFont = oPick.m_strPickFont;
|
||||
m_lCurrentPictFontStyle = oPick.m_lPickStyle;
|
||||
return false;
|
||||
}
|
||||
}
|
||||
void LoadFontByName(const std::wstring& strName, const double& dSize, const LONG& lStyle, const double& dDpiX, const double& dDpiY);
|
||||
|
||||
// не нашли...
|
||||
CFontPickUp oPick;
|
||||
oPick.m_lRangeNum = lRangeNum;
|
||||
oPick.m_lRange = lRange;
|
||||
oPick.m_oFont = m_oFont;
|
||||
oPick.m_strPickFont = m_oFont.m_strFamilyName;
|
||||
oPick.m_lPickStyle = m_oFont.m_lStyle;
|
||||
void LoadFontByFile(const std::wstring& strPath, const double& dSize, const double& dDpiX, const double& dDpiY, const LONG& lFaceIndex);
|
||||
|
||||
UINT dwR1 = m_oFont.m_arSignature[0];
|
||||
UINT dwR2 = m_oFont.m_arSignature[1];
|
||||
UINT dwR3 = m_oFont.m_arSignature[2];
|
||||
UINT dwR4 = m_oFont.m_arSignature[3];
|
||||
UINT dwCodePage1 = 0;
|
||||
UINT dwCodePage2 = 0;
|
||||
public:
|
||||
virtual void MeasureString(const std::wstring& sText, double x, double y, double& dBoxX, double& dBoxY,
|
||||
double& dBoxWidth, double& dBoxHeight, MeasureType measureType);
|
||||
virtual void CalculateBaselineOffset();
|
||||
|
||||
if ((lRangeNum == 1) && (lRange == 28))
|
||||
{
|
||||
dwCodePage1 = 0x80000000;
|
||||
//strText = (WCHAR)(strText[0] - 0xF000);
|
||||
}
|
||||
else if (((lRangeNum == 2) && (lRange == 3)) || ((lRangeNum == 1) && (lRange == 31)) || ((lRangeNum == 0) && (lRange == 13)))
|
||||
{
|
||||
// арабский язык!!!
|
||||
dwR1 = 1 << 13;
|
||||
dwR2 = 1 << 31;
|
||||
dwR3 = 1 << 3;
|
||||
}
|
||||
else
|
||||
{
|
||||
CheckRanges(dwR1, dwR2, dwR3, dwR4, lRangeNum, lRange);
|
||||
}
|
||||
public:
|
||||
void LoadFontMetrics();
|
||||
|
||||
NSFonts::CFontSelectFormat oFormat;
|
||||
std::wstring ToHexString( BYTE uc );
|
||||
|
||||
std::wstring sFontNameSelect = L"";
|
||||
if (m_oFont.m_strFamilyName.empty() && !m_oFont.m_oFont.Path.empty())
|
||||
sFontNameSelect = m_strDefaultFont;
|
||||
else
|
||||
sFontNameSelect = m_oFont.m_strFamilyName;
|
||||
BYTE FromHexString( wchar_t c1, wchar_t c2 );
|
||||
|
||||
bool bSelectBold = false;
|
||||
bool bSelectItalic = false;
|
||||
CheckFontNamePDF(sFontNameSelect, bSelectBold, bSelectItalic);
|
||||
void LoadFontParams(bool bIsPath = true);
|
||||
|
||||
oFormat.wsName = new std::wstring(sFontNameSelect);
|
||||
private:
|
||||
void CheckRanges(UINT& lRange1, UINT& lRange2, UINT& lRange3, UINT& lRange4, BYTE& lRangeNum, BYTE& lRange);
|
||||
|
||||
if (!m_oFont.m_strPANOSE.empty())
|
||||
{
|
||||
oFormat.pPanose = new BYTE[10];
|
||||
public:
|
||||
bool GenerateFontName(NSStringUtils::CStringUTF32& oText);
|
||||
|
||||
const wchar_t* pPanoseStr = m_oFont.m_strPANOSE.c_str();
|
||||
for (int i = 0; i < 10; ++i)
|
||||
{
|
||||
oFormat.pPanose[i] = FromHexString(pPanoseStr[0], pPanoseStr[1]);
|
||||
pPanoseStr += 2;
|
||||
}
|
||||
}
|
||||
bool CheckFontNameStyle(std::wstring& sName, const std::wstring& sStyle);
|
||||
|
||||
oFormat.bBold = new INT(((m_oFont.m_lStyle & 0x01) == 0x01) ? 1 : 0);
|
||||
oFormat.bItalic = new INT(((m_oFont.m_lStyle & 0x02) == 0x02) ? 1 : 0);
|
||||
oFormat.bFixedWidth = new INT(m_oFont.m_bIsFixedWidth ? 1 : 0);
|
||||
if (-1 != m_oFont.m_lAvgWidth)
|
||||
oFormat.shAvgCharWidth = new SHORT((SHORT)m_oFont.m_lAvgWidth);
|
||||
oFormat.ulRange1 = new UINT(dwR1);
|
||||
oFormat.ulRange2 = new UINT(dwR2);
|
||||
oFormat.ulRange3 = new UINT(dwR3);
|
||||
oFormat.ulRange4 = new UINT(dwR4);
|
||||
oFormat.ulCodeRange1 = new UINT(dwCodePage1);
|
||||
oFormat.ulCodeRange2 = new UINT(dwCodePage2);
|
||||
|
||||
if (oFormat.bBold && *(oFormat.bBold) == 1 && oFormat.pPanose && oFormat.pPanose[2] < 7)
|
||||
oFormat.pPanose[2] = 7;
|
||||
|
||||
oFormat.wsDefaultName = new std::wstring(L"Arial");
|
||||
|
||||
NSFonts::CFontInfo* pInfo = m_pManager->GetFontInfoByParams(oFormat);
|
||||
|
||||
oPick.m_strPickFont = pInfo->m_wsFontName;
|
||||
oPick.m_lPickStyle = 0;
|
||||
if (pInfo->m_bBold)
|
||||
oPick.m_lPickStyle |= 0x01;
|
||||
if (pInfo->m_bItalic)
|
||||
oPick.m_lPickStyle |= 0x02;
|
||||
|
||||
m_strCurrentPickFont = oPick.m_strPickFont;
|
||||
m_lCurrentPictFontStyle = oPick.m_lPickStyle;
|
||||
|
||||
m_arListPicUps.push_front(oPick);
|
||||
return true;
|
||||
}
|
||||
|
||||
bool CheckFontNameStyle(std::wstring& sName, const std::wstring& sStyle)
|
||||
{
|
||||
size_t nPos = 0;
|
||||
size_t nLenReplace = sStyle.length();
|
||||
bool bRet = false;
|
||||
|
||||
std::wstring sName2 = sName;
|
||||
NSStringExt::ToLower(sName2);
|
||||
|
||||
while (std::wstring::npos != (nPos = sName2.find(sStyle, nPos)))
|
||||
{
|
||||
size_t nOffset = 0;
|
||||
if ((nPos > 0) && sName2.at(nPos - 1) == '-')
|
||||
{
|
||||
--nPos;
|
||||
++nOffset;
|
||||
}
|
||||
|
||||
bRet = true;
|
||||
sName.erase(nPos, nLenReplace + nOffset);
|
||||
sName2.erase(nPos, nLenReplace + nOffset);
|
||||
}
|
||||
return bRet;
|
||||
}
|
||||
|
||||
void CheckFontNamePDF(std::wstring& sName, bool& bBold, bool& bItalic)
|
||||
{
|
||||
if (sName.length() > 7 && sName.at(6) == '+')
|
||||
{
|
||||
bool bIsRemove = true;
|
||||
for (int nIndex = 0; nIndex < 6; nIndex++)
|
||||
{
|
||||
wchar_t nChar = sName.at(nIndex);
|
||||
if (nChar < 'A' || nChar > 'Z')
|
||||
{
|
||||
bIsRemove = false;
|
||||
break;
|
||||
}
|
||||
}
|
||||
if (bIsRemove)
|
||||
{
|
||||
sName.erase(0, 7);
|
||||
}
|
||||
}
|
||||
|
||||
CheckFontNameStyle(sName, L"regular");
|
||||
CheckFontNameStyle(sName, L"condensed");
|
||||
CheckFontNameStyle(sName, L"condensedlight");
|
||||
//CheckFontNameStyle(sName, L"light");
|
||||
|
||||
CheckFontNameStyle(sName, L"condensedbold");
|
||||
CheckFontNameStyle(sName, L"semibold");
|
||||
if (CheckFontNameStyle(sName, L"boldmt")) bBold = true;
|
||||
if (CheckFontNameStyle(sName, L"bold")) bBold = true;
|
||||
|
||||
if (CheckFontNameStyle(sName, L"italicmt")) bItalic = true;
|
||||
if (CheckFontNameStyle(sName, L"italic")) bItalic = true;
|
||||
if (CheckFontNameStyle(sName, L"oblique")) bItalic = true;
|
||||
|
||||
if (CheckFontNameStyle(sName, L"bolditalicmt")) { bBold = true; bItalic = true; }
|
||||
if (CheckFontNameStyle(sName, L"bolditalic")) { bBold = true; bItalic = true; }
|
||||
if (CheckFontNameStyle(sName, L"bold_italic")) { bBold = true; bItalic = true; }
|
||||
if (CheckFontNameStyle(sName, L"boldoblique")) { bBold = true; bItalic = true; }
|
||||
if (CheckFontNameStyle(sName, L"bold_oblique")) { bBold = true; bItalic = true; }
|
||||
}
|
||||
};
|
||||
void CheckFontNamePDF(std::wstring& sName, bool& bBold, bool& bItalic);
|
||||
};
|
||||
}
|
||||
|
||||
#endif // DOCX_RENDERER_FMB_H
|
||||
|
||||
207
DocxRenderer/src/logic/ImageManager.cpp
Normal file
207
DocxRenderer/src/logic/ImageManager.cpp
Normal file
@ -0,0 +1,207 @@
|
||||
#include "ImageManager.h"
|
||||
#include "../DesktopEditor/common/Directory.h"
|
||||
|
||||
namespace NSDocxRenderer
|
||||
{
|
||||
void CImageManager::NewDocument()
|
||||
{
|
||||
m_strDstMedia = L"";
|
||||
m_lMaxSizeImage = 1200;
|
||||
m_lNextIDImage = 0;
|
||||
|
||||
m_mapImageData.clear();
|
||||
m_mapImagesFile.clear();
|
||||
}
|
||||
|
||||
CImageInfo CImageManager::WriteImage(Aggplus::CImage* pImage, double& x, double& y, double& width, double& height)
|
||||
{
|
||||
if (height < 0)
|
||||
{
|
||||
FlipY(pImage);
|
||||
height = -height;
|
||||
y -= height;
|
||||
}
|
||||
|
||||
return GenerateImageID(pImage);
|
||||
}
|
||||
|
||||
CImageInfo CImageManager::WriteImage(const std::wstring& strFile, double& x, double& y, double& width, double& height)
|
||||
{
|
||||
return GenerateImageID(strFile);
|
||||
}
|
||||
|
||||
void CImageManager::CopyFile(std::wstring& strFileSrc, std::wstring& strFileDst)
|
||||
{
|
||||
NSFile::CFileBinary::Copy(strFileSrc, strFileDst);
|
||||
}
|
||||
|
||||
void CImageManager::SaveImage(const std::wstring& strFileSrc, CImageInfo& oInfo)
|
||||
{
|
||||
Aggplus::CImage oFrame(strFileSrc);
|
||||
if (nullptr != oFrame.GetData())
|
||||
return SaveImage(&oFrame, oInfo);
|
||||
}
|
||||
|
||||
void CImageManager::SaveImage(Aggplus::CImage* pImage, CImageInfo& oInfo)
|
||||
{
|
||||
if (nullptr == pImage)
|
||||
return;
|
||||
|
||||
int w = pImage->GetWidth();
|
||||
int h = pImage->GetHeight();
|
||||
|
||||
oInfo.m_eType = GetImageType(pImage);
|
||||
|
||||
int format = (oInfo.m_eType == CImageInfo::itJPG) ? 3 : 4;
|
||||
std::wstring sSavedFile = m_strDstMedia + L"/image" + std::to_wstring(oInfo.m_nId);
|
||||
sSavedFile += ((oInfo.m_eType == CImageInfo::itJPG) ? L".jpg" : L".png");
|
||||
|
||||
if (w <= m_lMaxSizeImage && h <= m_lMaxSizeImage)
|
||||
{
|
||||
pImage->SaveFile(sSavedFile, format);
|
||||
}
|
||||
else
|
||||
{
|
||||
int lW = 0;
|
||||
int lH = 0;
|
||||
double dAspect = (double)w / h;
|
||||
|
||||
if (w >= h)
|
||||
{
|
||||
lW = m_lMaxSizeImage;
|
||||
lH = (int)((double)lW / dAspect);
|
||||
}
|
||||
else
|
||||
{
|
||||
lH = m_lMaxSizeImage;
|
||||
lW = (LONG)(dAspect * lH);
|
||||
}
|
||||
|
||||
// TODO: resize
|
||||
pImage->SaveFile(sSavedFile, format);
|
||||
}
|
||||
}
|
||||
|
||||
CImageInfo CImageManager::GenerateImageID(Aggplus::CImage* pImage)
|
||||
{
|
||||
BYTE* pData = pImage->GetData();
|
||||
int nSize = pImage->GetStride() * pImage->GetHeight();
|
||||
if (nSize < 0)
|
||||
nSize = -nSize;
|
||||
|
||||
DWORD dwSum = m_oCRC.Calc(pData, nSize);
|
||||
|
||||
std::map<DWORD, CImageInfo>::iterator find = m_mapImageData.find(dwSum);
|
||||
if (find != m_mapImageData.end())
|
||||
return find->second;
|
||||
|
||||
++m_lNextIDImage;
|
||||
CImageInfo oInfo;
|
||||
oInfo.m_nId = m_lNextIDImage;
|
||||
SaveImage(pImage, oInfo);
|
||||
m_mapImageData.insert(std::pair<DWORD, CImageInfo>(dwSum, oInfo));
|
||||
|
||||
return oInfo;
|
||||
}
|
||||
|
||||
CImageInfo CImageManager::GenerateImageID(const std::wstring& strFileName)
|
||||
{
|
||||
std::map<std::wstring, CImageInfo>::iterator find = m_mapImagesFile.find(strFileName);
|
||||
if (find != m_mapImagesFile.end())
|
||||
return find->second;
|
||||
|
||||
++m_lNextIDImage;
|
||||
CImageInfo oInfo;
|
||||
oInfo.m_nId = m_lNextIDImage;
|
||||
SaveImage(strFileName, oInfo);
|
||||
m_mapImagesFile.insert(std::pair<std::wstring, CImageInfo>(strFileName, oInfo));
|
||||
|
||||
return oInfo;
|
||||
}
|
||||
|
||||
CImageInfo::ImageType CImageManager::GetImageType(Aggplus::CImage* pFrame)
|
||||
{
|
||||
int w = pFrame->GetWidth();
|
||||
int h = pFrame->GetHeight();
|
||||
BYTE* pBuffer = pFrame->GetData();
|
||||
|
||||
BYTE* pBufferMem = pBuffer + 3;
|
||||
LONG lCountPix = w * h;
|
||||
|
||||
for (LONG i = 0; i < lCountPix; ++i, pBufferMem += 4)
|
||||
{
|
||||
if (255 != *pBufferMem)
|
||||
return CImageInfo::itPNG;
|
||||
}
|
||||
return CImageInfo::itJPG;
|
||||
}
|
||||
|
||||
void CImageManager::FlipY(Aggplus::CImage* pImage)
|
||||
{
|
||||
if (nullptr == pImage)
|
||||
return;
|
||||
|
||||
int w = pImage->GetWidth();
|
||||
int h = pImage->GetHeight();
|
||||
BYTE* pBuffer = pImage->GetData();
|
||||
int stride = pImage->GetStride();
|
||||
|
||||
if (stride < 0)
|
||||
stride = -stride;
|
||||
|
||||
if ((w * 4) != stride)
|
||||
return;
|
||||
|
||||
BYTE* pBufferMem = new BYTE[stride];
|
||||
|
||||
BYTE* pBufferEnd = pBuffer + stride * (h - 1);
|
||||
|
||||
LONG lCountV = h / 2;
|
||||
|
||||
for (LONG lIndexV = 0; lIndexV < lCountV; ++lIndexV)
|
||||
{
|
||||
memcpy(pBufferMem, pBuffer, stride);
|
||||
memcpy(pBuffer, pBufferEnd, stride);
|
||||
memcpy(pBufferEnd, pBufferMem, stride);
|
||||
|
||||
pBuffer += stride;
|
||||
pBufferEnd -= stride;
|
||||
}
|
||||
|
||||
RELEASEARRAYOBJECTS(pBufferMem);
|
||||
}
|
||||
|
||||
void CImageManager::FlipX(CBgraFrame* pImage)
|
||||
{
|
||||
if (nullptr == pImage)
|
||||
return;
|
||||
|
||||
int w = pImage->get_Width();
|
||||
int h = pImage->get_Height();
|
||||
BYTE* pBuffer = pImage->get_Data();
|
||||
int stride = pImage->get_Stride();
|
||||
|
||||
if (stride < 0)
|
||||
stride = -stride;
|
||||
|
||||
if ((w * 4) != stride)
|
||||
return;
|
||||
|
||||
DWORD* pBufferDWORD = (DWORD*)pBuffer;
|
||||
|
||||
LONG lW2 = w / 2;
|
||||
for (LONG lIndexV = 0; lIndexV < h; ++lIndexV)
|
||||
{
|
||||
DWORD* pMem1 = pBufferDWORD;
|
||||
DWORD* pMem2 = pBufferDWORD + w - 1;
|
||||
|
||||
LONG lI = 0;
|
||||
while (lI < lW2)
|
||||
{
|
||||
DWORD dwMem = *pMem1;
|
||||
*pMem1++ = *pMem2;
|
||||
*pMem2-- = dwMem;
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
64
DocxRenderer/src/logic/ImageManager.h
Normal file
64
DocxRenderer/src/logic/ImageManager.h
Normal file
@ -0,0 +1,64 @@
|
||||
#pragma once
|
||||
#include "../DesktopEditor/common/StringBuilder.h"
|
||||
#include "../DesktopEditor/common/CalculatorCRC32.h"
|
||||
#include "../DesktopEditor/raster/BgraFrame.h"
|
||||
#include <map>
|
||||
|
||||
namespace NSDocxRenderer
|
||||
{
|
||||
class CImageInfo
|
||||
{
|
||||
public:
|
||||
enum ImageType
|
||||
{
|
||||
itPNG = 0,
|
||||
itJPG = 1
|
||||
};
|
||||
|
||||
public:
|
||||
ImageType m_eType {itPNG};
|
||||
int m_nId {0};
|
||||
};
|
||||
|
||||
class CImageManager
|
||||
{
|
||||
public:
|
||||
std::map<std::wstring, CImageInfo> m_mapImagesFile;
|
||||
std::map<DWORD, CImageInfo> m_mapImageData;
|
||||
|
||||
std::wstring m_strDstMedia {L""};
|
||||
|
||||
int m_lMaxSizeImage {1200};
|
||||
int m_lNextIDImage {0};
|
||||
|
||||
CCalculatorCRC32 m_oCRC;
|
||||
|
||||
public:
|
||||
|
||||
CImageManager(){};
|
||||
|
||||
void NewDocument();
|
||||
|
||||
public:
|
||||
CImageInfo WriteImage(Aggplus::CImage* pImage, double& x, double& y, double& width, double& height);
|
||||
|
||||
CImageInfo WriteImage(const std::wstring& strFile, double& x, double& y, double& width, double& height);
|
||||
|
||||
protected:
|
||||
void CopyFile(std::wstring& strFileSrc, std::wstring& strFileDst);
|
||||
|
||||
void SaveImage(const std::wstring& strFileSrc, CImageInfo& oInfo);
|
||||
|
||||
void SaveImage(Aggplus::CImage* pImage, CImageInfo& oInfo);
|
||||
|
||||
CImageInfo GenerateImageID(Aggplus::CImage* pImage);
|
||||
|
||||
CImageInfo GenerateImageID(const std::wstring& strFileName);
|
||||
|
||||
CImageInfo::ImageType GetImageType(Aggplus::CImage* pFrame);
|
||||
|
||||
void FlipY(Aggplus::CImage* pImage);
|
||||
|
||||
void FlipX(CBgraFrame* pImage);
|
||||
};
|
||||
}
|
||||
1414
DocxRenderer/src/logic/Page.cpp
Normal file
1414
DocxRenderer/src/logic/Page.cpp
Normal file
File diff suppressed because it is too large
Load Diff
@ -1,868 +1,123 @@
|
||||
#pragma once
|
||||
#include "ElementShape.h"
|
||||
#include "../DesktopEditor/graphics/pro/Graphics.h"
|
||||
#include "ElementOldShape.h"
|
||||
#include "ElementParagraph.h"
|
||||
#include "ElementImage.h"
|
||||
#include "ElementShape.h"
|
||||
|
||||
namespace NSDocxRenderer
|
||||
{
|
||||
const double STANDART_STRING_HEIGHT_MM = 4.2333333333333334;
|
||||
const double THE_SAME_STRING_Y_PRECISION_MM = 0.01;
|
||||
|
||||
inline bool IsSpaceUtf32(const uint32_t& c)
|
||||
class CPage
|
||||
{
|
||||
return (' ' == c) ? true : false;
|
||||
}
|
||||
inline bool IsSpaceUtf32(NSStringUtils::CStringUTF32& oText)
|
||||
{
|
||||
if (1 != oText.length())
|
||||
return false;
|
||||
return IsSpaceUtf32(oText[0]);
|
||||
}
|
||||
public:
|
||||
NSStructures::CFont* m_pFont {nullptr};
|
||||
NSStructures::CPen* m_pPen {nullptr};
|
||||
NSStructures::CBrush* m_pBrush {nullptr};
|
||||
NSStructures::CShadow* m_pShadow {nullptr};
|
||||
NSStructures::CEdgeText* m_pEdgeText {nullptr};
|
||||
|
||||
inline bool IsUnicodeSymbol( int symbol )
|
||||
{
|
||||
bool result = false;
|
||||
Aggplus::CMatrix* m_pTransform {nullptr};
|
||||
Aggplus::CGraphicsPathSimpleConverter* m_pSimpleGraphicsConverter {nullptr};
|
||||
|
||||
if ( ( 0x0009 == symbol ) || ( 0x000A == symbol ) || ( 0x000D == symbol ) ||
|
||||
( ( 0x0020 <= symbol ) && ( 0xD7FF >= symbol ) ) || ( ( 0xE000 <= symbol ) && ( symbol <= 0xFFFD ) ) ||
|
||||
( ( 0x10000 <= symbol ) && symbol ) )
|
||||
{
|
||||
result = true;
|
||||
}
|
||||
CVectorGraphics m_oVector;
|
||||
|
||||
return result;
|
||||
}
|
||||
double m_dWidth {0.0};
|
||||
double m_dHeight {0.0};
|
||||
|
||||
class CPage
|
||||
{
|
||||
public:
|
||||
NSStructures::CFont* m_pFont;
|
||||
NSStructures::CPen* m_pPen;
|
||||
NSStructures::CBrush* m_pBrush;
|
||||
NSStructures::CShadow* m_pShadow;
|
||||
NSStructures::CEdgeText* m_pEdgeText;
|
||||
LONG m_lCurrentCommand {0};
|
||||
|
||||
Aggplus::CMatrix* m_pTransform;
|
||||
Aggplus::CGraphicsPathSimpleConverter* m_pSimpleGraphicsConverter;
|
||||
|
||||
CVectorGraphics m_oVector;
|
||||
|
||||
double m_dWidth;
|
||||
double m_dHeight;
|
||||
|
||||
LONG m_lCurrentCommand;
|
||||
|
||||
std::vector<CBaseItem*> m_arGraphicItems;
|
||||
std::vector<CImage*> m_arImages;
|
||||
std::vector<CContText*> m_arTextData;
|
||||
std::vector<CTextLine*> m_arTextLine;
|
||||
std::vector<CShape*> m_arShapes;
|
||||
std::vector<CParagraph*> m_arParagraphs;
|
||||
|
||||
std::vector<CParagraph*> m_arParagraphsBlocks;
|
||||
CTextLine* m_pCurrentLine {nullptr};
|
||||
|
||||
std::vector<CTextLine*> m_arTextLine;
|
||||
CTextLine* m_pCurrentLine;
|
||||
CFontManager m_oManager;
|
||||
CFontManagerLight m_oManagerLight;
|
||||
|
||||
CFontManager m_oManager;
|
||||
CFontManagerLight m_oManagerLight;
|
||||
TextAssociationType m_eTextAssociationType {tatPlainLine};
|
||||
|
||||
TextAssociationType m_eTextAssociationType;
|
||||
bool m_bIsDeleteTextClipPage {true};
|
||||
|
||||
NSStringUtils::CStringBuilder m_oWriterVML;
|
||||
double m_dLastTextX {-1};
|
||||
double m_dLastTextY {-1};
|
||||
double m_dLastTextX_block {-1};
|
||||
|
||||
bool m_bIsDeleteTextClipPage;
|
||||
|
||||
double m_dLastTextX;
|
||||
double m_dLastTextY;
|
||||
double m_dLastTextX_block;
|
||||
|
||||
public:
|
||||
CPage(NSFonts::IApplicationFonts* pFonts) : m_oManager(pFonts), m_oManagerLight(pFonts)
|
||||
{
|
||||
m_pFont = NULL;
|
||||
m_pBrush = NULL;
|
||||
m_pPen = NULL;
|
||||
m_pShadow = NULL;
|
||||
m_pEdgeText = NULL;
|
||||
|
||||
m_pTransform = NULL;
|
||||
m_pSimpleGraphicsConverter = NULL;
|
||||
|
||||
m_dWidth = 0;
|
||||
m_dHeight = 0;
|
||||
|
||||
m_pCurrentLine = NULL;
|
||||
m_eTextAssociationType = TextAssociationTypePlainLine;
|
||||
|
||||
m_bIsDeleteTextClipPage = true;
|
||||
|
||||
m_dLastTextX = -1;
|
||||
m_dLastTextY = -1;
|
||||
m_dLastTextX_block = m_dLastTextX;
|
||||
}
|
||||
|
||||
public:
|
||||
public:
|
||||
CPage(NSFonts::IApplicationFonts* pFonts);
|
||||
~CPage();
|
||||
void Init(NSStructures::CFont* pFont, NSStructures::CPen* pPen, NSStructures::CBrush* pBrush,
|
||||
NSStructures::CShadow* pShadow, NSStructures::CEdgeText* pEdge, Aggplus::CMatrix* pMatrix, Aggplus::CGraphicsPathSimpleConverter* pSimple)
|
||||
{
|
||||
m_pFont = pFont;
|
||||
m_pPen = pPen;
|
||||
m_pBrush = pBrush;
|
||||
m_pShadow = pShadow;
|
||||
m_pEdgeText = pEdge;
|
||||
|
||||
m_pTransform = pMatrix;
|
||||
m_pSimpleGraphicsConverter = pSimple;
|
||||
|
||||
m_oManager.m_pFont = m_pFont;
|
||||
m_oManager.m_pTransform = m_pTransform;
|
||||
|
||||
m_pCurrentLine = NULL;
|
||||
|
||||
m_oWriterVML.AddSize(1000);
|
||||
|
||||
m_dLastTextX = -1;
|
||||
m_dLastTextY = -1;
|
||||
m_dLastTextX_block = m_dLastTextX;
|
||||
}
|
||||
|
||||
void Clear()
|
||||
{
|
||||
size_t nCount = 0;
|
||||
|
||||
nCount = m_arTextLine.size();
|
||||
for (size_t i = 0; i < nCount; ++i)
|
||||
{
|
||||
CTextLine* pTemp = m_arTextLine[i];
|
||||
RELEASEOBJECT(pTemp);
|
||||
}
|
||||
m_arTextLine.clear();
|
||||
|
||||
nCount = m_arGraphicItems.size();
|
||||
for (size_t i = 0; i < nCount; ++i)
|
||||
{
|
||||
CBaseItem* pTemp = m_arGraphicItems[i];
|
||||
RELEASEOBJECT(pTemp);
|
||||
}
|
||||
m_arGraphicItems.clear();
|
||||
|
||||
nCount = m_arParagraphs.size();
|
||||
for (size_t i = 0; i < nCount; ++i)
|
||||
{
|
||||
CParagraph* pTemp = m_arParagraphs[i];
|
||||
RELEASEOBJECT(pTemp);
|
||||
}
|
||||
m_arParagraphs.clear();
|
||||
|
||||
m_pCurrentLine = NULL;
|
||||
|
||||
m_oWriterVML.ClearNoAttack();
|
||||
|
||||
m_dLastTextX = -1;
|
||||
m_dLastTextY = -1;
|
||||
m_dLastTextX_block = m_dLastTextX;
|
||||
}
|
||||
|
||||
~CPage()
|
||||
{
|
||||
Clear();
|
||||
}
|
||||
|
||||
void SetCurrentLineByBaseline(const double& dBaseLinePos)
|
||||
{
|
||||
if ((NULL == m_pCurrentLine) || (TextAssociationTypeBlockChar == m_eTextAssociationType))
|
||||
{
|
||||
// пустая (в плане текста) страница
|
||||
m_pCurrentLine = new CTextLine();
|
||||
|
||||
m_pCurrentLine->m_dBaselinePos = dBaseLinePos;
|
||||
m_arTextLine.push_back(m_pCurrentLine);
|
||||
return;
|
||||
}
|
||||
if (fabs(m_pCurrentLine->m_dBaselinePos - dBaseLinePos) <= THE_SAME_STRING_Y_PRECISION_MM)
|
||||
{
|
||||
return;
|
||||
}
|
||||
size_t nCount = m_arTextLine.size();
|
||||
for (size_t i = 0; i < nCount; ++i)
|
||||
{
|
||||
if (fabs(m_arTextLine[i]->m_dBaselinePos - dBaseLinePos) <= THE_SAME_STRING_Y_PRECISION_MM)
|
||||
{
|
||||
m_pCurrentLine = m_arTextLine[i];
|
||||
return;
|
||||
}
|
||||
}
|
||||
|
||||
// линия не нашлась - не беда - создадим новую
|
||||
m_pCurrentLine = new CTextLine();
|
||||
m_pCurrentLine->m_dBaselinePos = dBaseLinePos;
|
||||
m_arTextLine.push_back(m_pCurrentLine);
|
||||
return;
|
||||
}
|
||||
|
||||
// image commands
|
||||
void WriteImage(CImageInfo& oInfo, double& fX, double& fY, double& fWidth, double& fHeight)
|
||||
{
|
||||
CImage* pImage = new CImage(oInfo, L"");
|
||||
|
||||
double dRotation = m_pTransform->z_Rotation();
|
||||
|
||||
if (fabs(dRotation) < 5.0)
|
||||
{
|
||||
double x1 = fX;
|
||||
double y1 = fY;
|
||||
double x2 = fX + fWidth;
|
||||
double y2 = fY + fHeight;
|
||||
|
||||
m_pTransform->TransformPoint(x1, y1);
|
||||
m_pTransform->TransformPoint(x2, y2);
|
||||
|
||||
if (x1 <= x2)
|
||||
{
|
||||
pImage->m_dLeft = x1;
|
||||
pImage->m_dWidth = x2 - x1;
|
||||
}
|
||||
else
|
||||
{
|
||||
pImage->m_dLeft = x2;
|
||||
pImage->m_dWidth = x1 - x2;
|
||||
}
|
||||
|
||||
if (y1 <= y2)
|
||||
{
|
||||
pImage->m_dTop = y1;
|
||||
pImage->m_dHeight = y2 - y1;
|
||||
}
|
||||
else
|
||||
{
|
||||
pImage->m_dTop = y2;
|
||||
pImage->m_dHeight = y1 - y2;
|
||||
}
|
||||
|
||||
pImage->m_dRotate = 0.0;
|
||||
}
|
||||
else
|
||||
{
|
||||
double x1 = fX;
|
||||
double y1 = fY;
|
||||
double x2 = fX + fWidth;
|
||||
double y2 = fY + fHeight;
|
||||
|
||||
Aggplus::CMatrix oTemp = *m_pTransform;
|
||||
|
||||
double dCx = (x1 + x2) / 2;
|
||||
double dCy = (y1 + y2) / 2;
|
||||
m_pTransform->TransformPoint(dCx, dCy);
|
||||
oTemp.RotateAt(-dRotation, dCx, dCy, Aggplus::MatrixOrderAppend);
|
||||
|
||||
oTemp.TransformPoint(x1, y1);
|
||||
oTemp.TransformPoint(x2, y2);
|
||||
|
||||
if (x1 <= x2)
|
||||
{
|
||||
pImage->m_dLeft = x1;
|
||||
pImage->m_dWidth = x2 - x1;
|
||||
}
|
||||
else
|
||||
{
|
||||
pImage->m_dLeft = x2;
|
||||
pImage->m_dWidth = x1 - x2;
|
||||
}
|
||||
|
||||
if (y1 <= y2)
|
||||
{
|
||||
pImage->m_dTop = y1;
|
||||
pImage->m_dHeight = y2 - y1;
|
||||
}
|
||||
else
|
||||
{
|
||||
pImage->m_dTop = y2;
|
||||
pImage->m_dHeight = y1 - y2;
|
||||
}
|
||||
|
||||
pImage->m_dRotate = dRotation;
|
||||
}
|
||||
|
||||
m_arGraphicItems.push_back(pImage);
|
||||
}
|
||||
|
||||
// path commands
|
||||
void MoveTo(double& dX, double& dY)
|
||||
{
|
||||
m_pTransform->TransformPoint(dX, dY);
|
||||
m_oVector.MoveTo(dX, dY);
|
||||
|
||||
}
|
||||
void LineTo(double& dX, double& dY)
|
||||
{
|
||||
m_pTransform->TransformPoint(dX, dY);
|
||||
m_oVector.LineTo(dX, dY);
|
||||
}
|
||||
void CurveTo(double& x1, double& y1, double& x2, double& y2, double& x3, double& y3)
|
||||
{
|
||||
m_pTransform->TransformPoint(x1, y1);
|
||||
m_pTransform->TransformPoint(x2, y2);
|
||||
m_pTransform->TransformPoint(x3, y3);
|
||||
|
||||
m_oVector.CurveTo(x1, y1, x2, y2, x3, y3);
|
||||
}
|
||||
void Start()
|
||||
{
|
||||
}
|
||||
void End()
|
||||
{
|
||||
m_oVector.End();
|
||||
m_oWriterVML.ClearNoAttack();
|
||||
}
|
||||
void Close()
|
||||
{
|
||||
m_oVector.Close();
|
||||
}
|
||||
void DrawPath(LONG lType, LONG lTxId)
|
||||
{
|
||||
if ((m_oVector.m_dLeft <= m_oVector.m_dRight) && (m_oVector.m_dTop <= m_oVector.m_dBottom))
|
||||
{
|
||||
CShape* pShape = new CShape();
|
||||
|
||||
pShape->m_lTxId = lTxId;
|
||||
|
||||
pShape->m_oPen = *m_pPen;
|
||||
pShape->m_oBrush = *m_pBrush;
|
||||
|
||||
// нормализуем толщину линии
|
||||
double dScaleTransform = (m_pTransform->sx() + m_pTransform->sy()) / 2.0;
|
||||
pShape->m_oPen.Size *= dScaleTransform;
|
||||
|
||||
if ((lType & 0x01) == 0x00)
|
||||
{
|
||||
if ((fabs(m_oVector.m_dLeft - m_oVector.m_dRight) < 0.3) || (fabs(m_oVector.m_dTop - m_oVector.m_dBottom) < 0.3))
|
||||
{
|
||||
lType = 0x01;
|
||||
pShape->m_oPen.Color = m_pBrush->Color1;
|
||||
pShape->m_oPen.Alpha = m_pBrush->Alpha1;
|
||||
//pShape->m_oPen.Size = max(pShape->m_oPen.Size, 1);
|
||||
}
|
||||
}
|
||||
|
||||
pShape->CreateFromVectorData(&m_oVector, m_oWriterVML, 100000, lType);
|
||||
m_arGraphicItems.push_back(pShape);
|
||||
}
|
||||
}
|
||||
|
||||
void WriteText(unsigned int* pUnicodes, unsigned int* pGids, unsigned int nCount, double fX, double fY, double fWidth, double fHeight, double fBaseLineOffset, bool bIsPDFAnalyzer)
|
||||
{
|
||||
double dTextX = fX;
|
||||
double dTextY = fY;
|
||||
double dTextR = fX + fWidth;
|
||||
double dTextB = fY + fHeight;
|
||||
|
||||
m_pTransform->TransformPoint(dTextX, dTextY);
|
||||
m_pTransform->TransformPoint(dTextR, dTextB);
|
||||
|
||||
double dTextW = dTextR - dTextX;
|
||||
double dTextH = dTextB - dTextY;
|
||||
|
||||
NSStringUtils::CStringUTF32 oText((uint32_t*)pUnicodes, nCount);
|
||||
|
||||
if ((pUnicodes != NULL) && (pGids != NULL))
|
||||
{
|
||||
for (unsigned int i = 0; i < nCount; ++i)
|
||||
{
|
||||
if ( !IsUnicodeSymbol( pUnicodes[i] ) )
|
||||
{
|
||||
oText[i] = ' ';
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
bool bIsPath = ((NULL == pGids) && !bIsPDFAnalyzer) ? false : true;
|
||||
|
||||
m_oManager.LoadFont(0, !bIsPath);
|
||||
|
||||
if (bIsPath)
|
||||
m_oManager.GenerateFontName2(oText);
|
||||
|
||||
if (fabs(dTextW) < 0.01 || (dTextW > 10))
|
||||
{
|
||||
double _x = 0;
|
||||
double _y = 0;
|
||||
double _w = 0;
|
||||
double _h = 0;
|
||||
|
||||
if (NULL != pGids)
|
||||
{
|
||||
m_oManager.SetStringGid(1);
|
||||
m_oManager.MeasureStringGids(pGids, nCount, dTextX, dTextY, _x, _y, _w, _h, CFontManager::MeasureTypePosition);
|
||||
}
|
||||
else
|
||||
{
|
||||
// такого быть не должно (только из xps)
|
||||
m_oManager.SetStringGid(0);
|
||||
m_oManager.MeasureStringGids(pUnicodes, nCount, dTextX, dTextY, _x, _y, _w, _h, CFontManager::MeasureTypePosition);
|
||||
}
|
||||
|
||||
dTextW = _w;
|
||||
//dTextW *= c_dPixToMM;
|
||||
}
|
||||
|
||||
double dBaseLinePos = dTextY + fBaseLineOffset;
|
||||
dTextH = m_oManager.GetFontHeight();
|
||||
|
||||
SetCurrentLineByBaseline(dBaseLinePos);
|
||||
|
||||
CContText* pLastCont = NULL;
|
||||
size_t nCountConts = m_pCurrentLine->m_arConts.size();
|
||||
if (nCountConts != 0)
|
||||
pLastCont = m_pCurrentLine->m_arConts[nCountConts - 1];
|
||||
|
||||
if (NULL == pLastCont)
|
||||
{
|
||||
// первое слово в линии
|
||||
CContText* pCont = new CContText();
|
||||
|
||||
pCont->m_dX = dTextX;
|
||||
pCont->m_dLastX = dTextX;
|
||||
pCont->m_dY = dBaseLinePos;
|
||||
|
||||
pCont->m_dWidth = dTextW;
|
||||
pCont->m_dHeight = dTextH;
|
||||
|
||||
if (IsSpaceUtf32(oText))
|
||||
{
|
||||
pCont->m_dWidthWithoutSpaces = 0;
|
||||
pCont->m_dLeftWithoutSpaces = dTextX + dTextW;
|
||||
}
|
||||
else
|
||||
{
|
||||
pCont->m_dWidthWithoutSpaces = dTextW;
|
||||
pCont->m_dLeftWithoutSpaces = dTextX;
|
||||
}
|
||||
|
||||
pCont->m_oText = oText;
|
||||
|
||||
pCont->m_oFont = m_oManager.m_oFont.m_oFont;
|
||||
pCont->m_oBrush = *m_pBrush;
|
||||
|
||||
if (bIsPath)
|
||||
{
|
||||
pCont->m_strPickFontName = m_oManager.m_strCurrentPickFont;
|
||||
pCont->m_lPickFontStyle = m_oManager.m_lCurrentPictFontStyle;
|
||||
}
|
||||
|
||||
pCont->m_dSpaceWidthMM = m_oManager.m_dSpaceWidthMM;
|
||||
|
||||
m_pCurrentLine->AddCont(pCont, m_oManager.m_oFont.m_dBaselineOffset);
|
||||
|
||||
m_dLastTextX = dTextX;
|
||||
m_dLastTextY = dBaseLinePos;
|
||||
m_dLastTextX_block = m_dLastTextX;
|
||||
return;
|
||||
}
|
||||
|
||||
// продолжение линии
|
||||
//if (m_lCurrentCommand == c_nTextType && pLastCont->m_oFont.IsEqual(&m_oManager.m_oFontOld) && pLastCont->m_oBrush.IsEqual(m_pBrush))
|
||||
//{
|
||||
// // быстрое отметание вс¤ких проверок
|
||||
// pLastCont->m_strText += strText;
|
||||
// pLastCont->m_dWidth = (dTextX + dTextW - pLastCont->m_dX);
|
||||
// return;
|
||||
//}
|
||||
|
||||
double dRight = pLastCont->m_dX + pLastCont->m_dWidth;
|
||||
|
||||
if (pLastCont->m_oFont.IsEqual(&m_oManager.m_oFont.m_oFont) && pLastCont->m_oBrush.IsEqual(m_pBrush))
|
||||
{
|
||||
// настройки одинаковые. теперь смотрим, на расположение
|
||||
if (fabs(dRight - dTextX) < 0.5)
|
||||
{
|
||||
// продолжаем слово
|
||||
pLastCont->m_oText += oText;
|
||||
pLastCont->m_dWidth = (dTextX + dTextW - pLastCont->m_dX);
|
||||
|
||||
if (!IsSpaceUtf32(oText))
|
||||
{
|
||||
if (0 == pLastCont->m_dWidthWithoutSpaces)
|
||||
pLastCont->m_dLeftWithoutSpaces = dTextX;
|
||||
|
||||
pLastCont->m_dWidthWithoutSpaces = dTextX + dTextW - pLastCont->m_dLeftWithoutSpaces;
|
||||
}
|
||||
else if (0 == pLastCont->m_dWidthWithoutSpaces)
|
||||
{
|
||||
pLastCont->m_dLeftWithoutSpaces = dTextX + dTextW;
|
||||
}
|
||||
|
||||
m_dLastTextX = dTextX;
|
||||
m_dLastTextY = dBaseLinePos;
|
||||
m_dLastTextX_block = m_dLastTextX;
|
||||
pLastCont->m_dLastX = dTextX;
|
||||
return;
|
||||
}
|
||||
else if ((dRight < dTextX) && ((dTextX - dRight) < m_oManager.m_dSpaceWidthMM))
|
||||
{
|
||||
// продолжаем слово с пробелом
|
||||
pLastCont->m_oText += uint32_t(' ');
|
||||
pLastCont->m_oText += oText;
|
||||
pLastCont->m_dWidth = (dTextX + dTextW - pLastCont->m_dX);
|
||||
|
||||
if (!IsSpaceUtf32(oText))
|
||||
{
|
||||
if (0 == pLastCont->m_dWidthWithoutSpaces)
|
||||
pLastCont->m_dLeftWithoutSpaces = dTextX;
|
||||
|
||||
pLastCont->m_dWidthWithoutSpaces = dTextX + dTextW - pLastCont->m_dLeftWithoutSpaces;
|
||||
}
|
||||
else if (0 == pLastCont->m_dWidthWithoutSpaces)
|
||||
{
|
||||
pLastCont->m_dLeftWithoutSpaces = dTextX + dTextW;
|
||||
}
|
||||
|
||||
m_dLastTextX = dTextX;
|
||||
m_dLastTextY = dBaseLinePos;
|
||||
m_dLastTextX_block = m_dLastTextX;
|
||||
pLastCont->m_dLastX = dTextX;
|
||||
return;
|
||||
}
|
||||
else if (fabs(dBaseLinePos - pLastCont->m_dY) < 0.01 &&
|
||||
fabs(m_dLastTextY - pLastCont->m_dY) < 0.01 &&
|
||||
fabs(m_dLastTextX - pLastCont->m_dLastX) < 0.01)
|
||||
{
|
||||
// идет текст подряд, но с расстояниями что-то не так. смотрим - если новый текст идет после предыдущего, но
|
||||
// просто левее чем предыдущий x + w - то считаем это нормальным. и дописываем слово. корректируя длину
|
||||
if (dTextX < dRight && dTextX > pLastCont->m_dLastX)
|
||||
{
|
||||
// продолжаем слово
|
||||
pLastCont->m_oText += oText;
|
||||
double dNewW = (dTextX + dTextW - pLastCont->m_dX);
|
||||
if (pLastCont->m_dWidth < dNewW)
|
||||
pLastCont->m_dWidth = dNewW;
|
||||
|
||||
if (!IsSpaceUtf32(oText))
|
||||
{
|
||||
if (0 == pLastCont->m_dWidthWithoutSpaces)
|
||||
pLastCont->m_dLeftWithoutSpaces = dTextX;
|
||||
|
||||
pLastCont->m_dWidthWithoutSpaces = dTextX + dTextW - pLastCont->m_dLeftWithoutSpaces;
|
||||
}
|
||||
else if (0 == pLastCont->m_dWidthWithoutSpaces)
|
||||
{
|
||||
pLastCont->m_dLeftWithoutSpaces = dTextX + dTextW;
|
||||
}
|
||||
|
||||
m_dLastTextX = dTextX;
|
||||
m_dLastTextY = dBaseLinePos;
|
||||
m_dLastTextX_block = m_dLastTextX;
|
||||
pLastCont->m_dLastX = dTextX;
|
||||
return;
|
||||
|
||||
}
|
||||
|
||||
// еще одна заглушка на большой пробел - добавляем пробел, потом в линии все разрулится через spacing
|
||||
if (dTextX > dRight && (dTextX - dRight) < 5 && fabs(m_dLastTextX_block - m_dLastTextX) < 0.01)
|
||||
{
|
||||
// продолжаем слово с пробелом
|
||||
pLastCont->m_oText += uint32_t(' ');
|
||||
pLastCont->m_oText += oText;
|
||||
pLastCont->m_dWidth = (dTextX + dTextW - pLastCont->m_dX);
|
||||
|
||||
if (!IsSpaceUtf32(oText))
|
||||
{
|
||||
if (0 == pLastCont->m_dWidthWithoutSpaces)
|
||||
pLastCont->m_dLeftWithoutSpaces = dTextX;
|
||||
|
||||
pLastCont->m_dWidthWithoutSpaces = dTextX + dTextW - pLastCont->m_dLeftWithoutSpaces;
|
||||
}
|
||||
else if (0 == pLastCont->m_dWidthWithoutSpaces)
|
||||
{
|
||||
pLastCont->m_dLeftWithoutSpaces = dTextX + dTextW;
|
||||
}
|
||||
|
||||
m_dLastTextX = dTextX;
|
||||
m_dLastTextY = dBaseLinePos;
|
||||
m_dLastTextX_block = m_dLastTextX;
|
||||
pLastCont->m_dLastX = dTextX;
|
||||
return;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
// либо пробел большой между словами, либо новый текст левее, либо настройки не те (шрифт, кисть)
|
||||
// либо все вместе... просто добавл¤ем новое слово
|
||||
CContText* pCont = new CContText();
|
||||
|
||||
pCont->m_dX = dTextX;
|
||||
pCont->m_dY = dBaseLinePos;
|
||||
pCont->m_dLastX = dTextX;
|
||||
|
||||
pCont->m_dWidth = dTextW;
|
||||
pCont->m_dHeight = dTextH;
|
||||
|
||||
if (IsSpaceUtf32(oText))
|
||||
{
|
||||
pCont->m_dWidthWithoutSpaces = 0;
|
||||
pCont->m_dLeftWithoutSpaces = dTextX + dTextW;
|
||||
}
|
||||
else
|
||||
{
|
||||
pCont->m_dWidthWithoutSpaces = dTextW;
|
||||
pCont->m_dLeftWithoutSpaces = dTextX;
|
||||
}
|
||||
|
||||
pCont->m_oText = oText;
|
||||
|
||||
pCont->m_oFont = m_oManager.m_oFont.m_oFont;
|
||||
pCont->m_oBrush = *m_pBrush;
|
||||
|
||||
if (bIsPath)
|
||||
{
|
||||
pCont->m_strPickFontName = m_oManager.m_strCurrentPickFont;
|
||||
pCont->m_lPickFontStyle = m_oManager.m_lCurrentPictFontStyle;
|
||||
}
|
||||
|
||||
pCont->m_dSpaceWidthMM = m_oManager.m_dSpaceWidthMM;
|
||||
|
||||
m_pCurrentLine->AddCont(pCont, m_oManager.m_oFont.m_dBaselineOffset);
|
||||
|
||||
m_dLastTextX = dTextX;
|
||||
m_dLastTextY = dBaseLinePos;
|
||||
m_dLastTextX_block = m_dLastTextX;
|
||||
}
|
||||
|
||||
void Build()
|
||||
{
|
||||
if (m_bIsDeleteTextClipPage)
|
||||
{
|
||||
// удалим все линии, которые выходят за границы страницы
|
||||
size_t nCount = m_arTextLine.size();
|
||||
for (size_t i = 0; i < nCount; ++i)
|
||||
{
|
||||
CTextLine* pTextLine = m_arTextLine[i];
|
||||
|
||||
double _top = pTextLine->m_dBaselinePos - pTextLine->m_dHeight;
|
||||
double _bottom = pTextLine->m_dBaselinePos;
|
||||
|
||||
if (_top >= m_dHeight || _bottom <= 0)
|
||||
{
|
||||
m_arTextLine.erase(m_arTextLine.begin() + i);
|
||||
--i;
|
||||
--nCount;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
switch (m_eTextAssociationType)
|
||||
{
|
||||
case TextAssociationTypeBlockChar:
|
||||
{
|
||||
size_t nCount = m_arTextLine.size();
|
||||
for (size_t i = 0; i < nCount; ++i)
|
||||
{
|
||||
CTextLine* pTextLine = m_arTextLine[i];
|
||||
|
||||
CParagraph* pParagraph = new CParagraph(m_eTextAssociationType);
|
||||
pParagraph->m_pManagerLight = &m_oManagerLight;
|
||||
pParagraph->m_bIsTextFrameProperties = true;
|
||||
|
||||
pParagraph->m_dLeft = pTextLine->m_dX;
|
||||
pParagraph->m_dTop = pTextLine->m_dBaselinePos - pTextLine->m_dHeight - pTextLine->m_dBaselineOffset;
|
||||
|
||||
pParagraph->m_arLines.push_back(pTextLine);
|
||||
|
||||
m_arParagraphs.push_back(pParagraph);
|
||||
}
|
||||
|
||||
// удалим все линии
|
||||
m_arTextLine.clear();
|
||||
break;
|
||||
}
|
||||
case TextAssociationTypeBlockLine:
|
||||
{
|
||||
size_t nCount = m_arTextLine.size();
|
||||
|
||||
if (0 == nCount)
|
||||
break;
|
||||
|
||||
CTextLine* pFirstLine = m_arTextLine[0];
|
||||
|
||||
CParagraph* pParagraph = new CParagraph(m_eTextAssociationType);
|
||||
pParagraph->m_pManagerLight = &m_oManagerLight;
|
||||
pParagraph->m_bIsTextFrameProperties = true;
|
||||
|
||||
pParagraph->m_dLeft = pFirstLine->m_dX;
|
||||
pParagraph->m_dTop = pFirstLine->m_dBaselinePos - pFirstLine->m_dHeight - pFirstLine->m_dBaselineOffset;
|
||||
double dCurrentTop = pParagraph->m_dTop;
|
||||
|
||||
pParagraph->m_arLines.push_back(pFirstLine);
|
||||
|
||||
m_arParagraphs.push_back(pParagraph);
|
||||
|
||||
for (size_t i = 1; i < nCount; ++i)
|
||||
{
|
||||
CTextLine* pTextLine = m_arTextLine[i];
|
||||
|
||||
CParagraph* pParagraph = new CParagraph(m_eTextAssociationType);
|
||||
pParagraph->m_pManagerLight = &m_oManagerLight;
|
||||
pParagraph->m_bIsTextFrameProperties = true;
|
||||
|
||||
if (((fabs(pTextLine->m_dBaselinePos - pTextLine->m_dHeight - pFirstLine->m_dBaselinePos) > STANDART_STRING_HEIGHT_MM) && (pTextLine->m_dX == pFirstLine->m_dX)) ||
|
||||
((pTextLine->m_dX != pFirstLine->m_dX) && (pTextLine->m_dBaselinePos != pFirstLine->m_dBaselinePos)))
|
||||
{
|
||||
pParagraph->m_dLeft = pTextLine->m_dX;
|
||||
pParagraph->m_dTop = pTextLine->m_dBaselinePos - pTextLine->m_dHeight - pTextLine->m_dBaselineOffset;
|
||||
dCurrentTop = pParagraph->m_dTop;
|
||||
}
|
||||
else
|
||||
{
|
||||
pParagraph->m_dLeft = pFirstLine->m_dX;
|
||||
pParagraph->m_dTop = dCurrentTop;
|
||||
}
|
||||
|
||||
pFirstLine = pTextLine;
|
||||
|
||||
pParagraph->m_arLines.push_back(pTextLine);
|
||||
m_arParagraphs.push_back(pParagraph);
|
||||
}
|
||||
|
||||
// удалим все линии
|
||||
m_arTextLine.clear();
|
||||
break;
|
||||
}
|
||||
case TextAssociationTypePlainLine:
|
||||
{
|
||||
SortElements(m_arTextLine);
|
||||
|
||||
if (true) // merge line
|
||||
{
|
||||
for (std::vector<CTextLine*>::iterator iter = m_arTextLine.begin(); iter != m_arTextLine.end(); ++iter)
|
||||
{
|
||||
(*iter)->Analyze();
|
||||
}
|
||||
}
|
||||
|
||||
Merge(STANDART_STRING_HEIGHT_MM / 3);
|
||||
|
||||
double previousStringOffset = 0;
|
||||
size_t nCount = m_arTextLine.size();
|
||||
for (size_t i = 0; i < nCount; ++i)
|
||||
{
|
||||
CTextLine* pTextLine = m_arTextLine[i];
|
||||
|
||||
CParagraph* pParagraph = new CParagraph(m_eTextAssociationType);
|
||||
pParagraph->m_pManagerLight = &m_oManagerLight;
|
||||
pParagraph->m_bIsTextFrameProperties = false;
|
||||
|
||||
#if 0
|
||||
// у рамок нельзя выключить обтекание. поэтому в этом случае нужно конверировать в шейп
|
||||
if (pTextLine->IsForceBlock())
|
||||
{
|
||||
pParagraph->m_bIsTextFrameProperties = true;
|
||||
pParagraph->m_dLeft = pTextLine->m_dX;
|
||||
pParagraph->m_dTop = pTextLine->m_dBaselinePos - pTextLine->m_dHeight - pTextLine->m_dBaselineOffset;
|
||||
|
||||
pParagraph->m_arLines.push_back(pTextLine);
|
||||
m_arParagraphs.push_back(pParagraph);
|
||||
continue;
|
||||
}
|
||||
#endif
|
||||
|
||||
pParagraph->m_dLeft = pTextLine->m_dX;
|
||||
|
||||
double dBeforeSpacing = (pTextLine->m_dBaselinePos - previousStringOffset - pTextLine->m_dHeight - pTextLine->m_dBaselineOffset);
|
||||
|
||||
pParagraph->m_dSpaceBefore = std::max(dBeforeSpacing, 0.0);
|
||||
|
||||
double dHeight = 1;
|
||||
if (pTextLine->m_dHeight != 0)
|
||||
{
|
||||
dHeight = pTextLine->m_dHeight;
|
||||
|
||||
if (dBeforeSpacing < 0)
|
||||
dHeight += dBeforeSpacing;
|
||||
}
|
||||
|
||||
pParagraph->m_dHeight = dHeight;
|
||||
|
||||
previousStringOffset = pTextLine->m_dBaselinePos - pTextLine->m_dBaselineOffset;
|
||||
|
||||
pParagraph->m_arLines.push_back(pTextLine);
|
||||
m_arParagraphs.push_back(pParagraph);
|
||||
}
|
||||
|
||||
m_arTextLine.clear();
|
||||
break;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
void Merge(double dAffinity)
|
||||
{
|
||||
size_t nCount = m_arTextLine.size();
|
||||
if (1 < nCount)
|
||||
{
|
||||
CTextLine* pPrev = m_arTextLine[0];
|
||||
for (size_t i = 1; i < nCount; ++i)
|
||||
{
|
||||
CTextLine* pNext = m_arTextLine[i];
|
||||
|
||||
if (fabs(pNext->m_dBaselinePos - pPrev->m_dBaselinePos) < dAffinity)
|
||||
{
|
||||
pPrev->Merge(pNext);
|
||||
|
||||
pNext->m_arConts.clear();
|
||||
RELEASEOBJECT(pNext);
|
||||
|
||||
m_arTextLine.erase(m_arTextLine.begin() + i);
|
||||
--i;
|
||||
--nCount;
|
||||
continue;
|
||||
}
|
||||
pPrev = pNext;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
void Write(NSStringUtils::CStringBuilder& oWriter)
|
||||
{
|
||||
// drawings
|
||||
size_t nCountDrawings = m_arGraphicItems.size();
|
||||
if (0 != nCountDrawings)
|
||||
{
|
||||
oWriter.WriteString(L"<w:p><w:pPr><w:spacing w:line=\"1\" w:lineRule=\"exact\"/></w:pPr>");
|
||||
|
||||
for (size_t i = 0; i < nCountDrawings; ++i)
|
||||
{
|
||||
m_arGraphicItems[i]->ToXml(oWriter);
|
||||
}
|
||||
|
||||
oWriter.WriteString(L"</w:p>");
|
||||
}
|
||||
|
||||
size_t nCountParagraphs = m_arParagraphs.size();
|
||||
for (size_t i = 0; i < nCountParagraphs; ++i)
|
||||
{
|
||||
m_arParagraphs[i]->ToXml(oWriter);
|
||||
}
|
||||
}
|
||||
|
||||
void WriteSectionToFile(bool bLastPage, NSStringUtils::CStringBuilder& oWriter)
|
||||
{
|
||||
// section
|
||||
int lWidthDx = (int)(m_dWidth * c_dMMToDx);
|
||||
int lHeightDx = (int)(m_dHeight * c_dMMToDx);
|
||||
|
||||
if (!bLastPage)
|
||||
oWriter.WriteString(L"<w:p><w:pPr><w:sectPr>");
|
||||
else
|
||||
oWriter.WriteString(L"<w:sectPr>");
|
||||
|
||||
oWriter.WriteString(L"<w:pgSz w:w=\"");
|
||||
oWriter.AddInt((int)(m_dWidth * c_dMMToDx));
|
||||
oWriter.WriteString(L"\" w:h=\"");
|
||||
oWriter.AddInt((int)(m_dHeight * c_dMMToDx));
|
||||
oWriter.WriteString(L"\" w:orient=\"");
|
||||
(lWidthDx >= lHeightDx) ? oWriter.WriteString(L"landscape") : oWriter.WriteString(L"portrait");
|
||||
oWriter.WriteString(L"\"/>");
|
||||
|
||||
if (!bLastPage)
|
||||
oWriter.WriteString(L"<w:pgMar w:top=\"0\" w:right=\"0\" w:bottom=\"0\" w:left=\"0\"/></w:sectPr><w:spacing w:line=\"1\" w:lineRule=\"exact\"/></w:pPr></w:p>");
|
||||
else
|
||||
oWriter.WriteString(L"<w:pgMar w:top=\"0\" w:right=\"0\" w:bottom=\"0\" w:left=\"0\" w:header=\"0\" w:footer=\"0\" w:gutter=\"0\"/></w:sectPr>");
|
||||
}
|
||||
};
|
||||
NSStructures::CShadow* pShadow, NSStructures::CEdgeText* pEdge, Aggplus::CMatrix* pMatrix, Aggplus::CGraphicsPathSimpleConverter* pSimple);
|
||||
|
||||
void Clear();
|
||||
void ClearImages();
|
||||
void ClearTextData();
|
||||
void ClearTextLines();
|
||||
void ClearShapes();
|
||||
void ClearParagraphs();
|
||||
|
||||
void SetCurrentLineByBaseline(const double& dBaseLinePos);
|
||||
//удаляем то, что выходит за границы страницы
|
||||
void DeleteTextClipPage();
|
||||
|
||||
// image commands
|
||||
//набивается содержимым вектор m_arImages
|
||||
void WriteImage(CImageInfo& oInfo, double& fX, double& fY, double& fWidth, double& fHeight);
|
||||
|
||||
// path commands
|
||||
void MoveTo(double& dX, double& dY);
|
||||
void LineTo(double& dX, double& dY);
|
||||
void CurveTo(double& x1, double& y1, double& x2, double& y2, double& x3, double& y3);
|
||||
void Start();
|
||||
void End();
|
||||
void Close();
|
||||
//набивается содержимым вектор m_arShapes
|
||||
void DrawPath(LONG lType, LONG lTxId);
|
||||
|
||||
//набивается содержимым вектор m_arTextData
|
||||
void CollectTextData(const PUINT pUnicodes, const PUINT pGids, const UINT& nCount,
|
||||
const double& fX, const double& fY, const double& fWidth, const double& fHeight,
|
||||
const double& fBaseLineOffset, const bool& bIsPDFAnalyzer);
|
||||
|
||||
void AnalyzeCollectedShapes();
|
||||
void DetermineContWithMaxSizeFont();
|
||||
void DetermineLinesType();
|
||||
|
||||
//Собранные для текущей страницы данные нужно проанализировать и сгруппировать, лишнее удалить
|
||||
void AnalyzeCollectedData();
|
||||
|
||||
//набивается содержимым вектор m_arTextLine
|
||||
void BuildLines();
|
||||
void BuildLines(const CContText* pContText);
|
||||
|
||||
void BuildByType();
|
||||
void BuildByTypeBlockChar();
|
||||
void BuildByTypeBlockLine();
|
||||
void BuildByTypePlainLine();
|
||||
void BuildByTypeShapeLine();
|
||||
void BuildByTypePlainParagraph();
|
||||
|
||||
//Объединяем строки, которые находятся на расстроянии не большем dAffinity
|
||||
void Merge(double dAffinity);
|
||||
|
||||
//конвертим m_arImages, m_arShapes, m_arParagraphs в xml-строку
|
||||
void ToXml(NSStringUtils::CStringBuilder& oWriter);
|
||||
|
||||
void WriteSectionToFile(bool bLastPage, NSStringUtils::CStringBuilder& oWriter);
|
||||
|
||||
double RightBorderCorrection(const CTextLine *pLine);
|
||||
|
||||
void CreateSingleLineParagraph(CTextLine *pLine, const double *pRight, const double *pBeforeSpacing);
|
||||
void CreateSingleLineOldShape(CTextLine *pLine);
|
||||
void CreateSingleLineShape(CTextLine *pLine);
|
||||
|
||||
bool IsLineCrossingText(const CShape* pGraphicItem, CContText* pContText);
|
||||
bool IsLineBelowText(const CShape* pGraphicItem, CContText* pContText);
|
||||
bool IsItHighlightingBackground(const CShape* pGraphicItem, CContText* pContText);
|
||||
|
||||
void DetermineDominantGraphics();
|
||||
bool IsShadingPresent(const CTextLine *pLine1, const CTextLine *pLine2);
|
||||
};
|
||||
}
|
||||
|
||||
65
DocxRenderer/src/resources/ColorTable.h
Normal file
65
DocxRenderer/src/resources/ColorTable.h
Normal file
@ -0,0 +1,65 @@
|
||||
#pragma once
|
||||
#include <string>
|
||||
#include <map>
|
||||
#include <algorithm>
|
||||
|
||||
class ColorTable
|
||||
{
|
||||
public:
|
||||
ColorTable ()
|
||||
{
|
||||
InitClrTable ();
|
||||
}
|
||||
|
||||
inline std::wstring ConverColorToString(const unsigned int& sKey)
|
||||
{
|
||||
auto iter = m_Table.find(sKey);
|
||||
if (iter == m_Table.end())
|
||||
{
|
||||
//note если не нашли стандартный цвет, отсылаем что есть
|
||||
return L"none";
|
||||
}
|
||||
else
|
||||
{
|
||||
return iter->second;
|
||||
}
|
||||
}
|
||||
|
||||
inline bool IsStandardColor(const unsigned int& sKey)
|
||||
{
|
||||
auto iter = m_Table.find(sKey);
|
||||
return iter == m_Table.end() ? false : true;
|
||||
}
|
||||
|
||||
private:
|
||||
std::map<unsigned int, std::wstring> m_Table;
|
||||
|
||||
private:
|
||||
void InitClrTable()
|
||||
{
|
||||
if (m_Table.size())
|
||||
return;
|
||||
|
||||
//ECMA-376-1:2016 17.18.40 ST_HighlightColor (Text Highlight Colors)
|
||||
m_Table.insert({0x000000, L"black" });
|
||||
m_Table.insert({0x0000FF, L"blue" });
|
||||
m_Table.insert({0x00FFFF, L"cyan" });
|
||||
m_Table.insert({0x00008B, L"darkBlue" });
|
||||
m_Table.insert({0x008B8B, L"darkCyan" });
|
||||
m_Table.insert({0xA9A9A9, L"darkGray" });
|
||||
m_Table.insert({0x006400, L"darkGreen" });
|
||||
m_Table.insert({0x800080, L"darkMagenta" });
|
||||
m_Table.insert({0x8B0000, L"darkRed" });
|
||||
m_Table.insert({0x808000, L"darkYellow" });
|
||||
m_Table.insert({0x00FF00, L"green" });
|
||||
m_Table.insert({0xD3D3D3, L"lightGray" });
|
||||
m_Table.insert({0xFF00FF, L"magenta" });
|
||||
m_Table.insert({0xFF0000, L"red" });
|
||||
m_Table.insert({0xFFFFFF, L"white" });
|
||||
m_Table.insert({0xFFFF00, L"yellow" });
|
||||
|
||||
//note Больше цветов здесь
|
||||
//core\Common\3dParty\html\css\src\ConstValues.h
|
||||
//core\DesktopEditor\agg-2.4\svg\agg_svg_color_parser.cpp
|
||||
}
|
||||
};
|
||||
58
DocxRenderer/src/resources/Constants.h
Normal file
58
DocxRenderer/src/resources/Constants.h
Normal file
@ -0,0 +1,58 @@
|
||||
#pragma once
|
||||
|
||||
#include "../DesktopEditor/common/Types.h"
|
||||
#include <map>
|
||||
|
||||
const double c_dDpiX = 72.0;
|
||||
const double c_dDpiY = 72.0;
|
||||
|
||||
const double c_dInchToMM = 25.4;
|
||||
constexpr double c_dPixToMM = 25.4 / 72.0;
|
||||
constexpr double c_dPtToMM = 25.4 / 72.0;
|
||||
constexpr double c_dMMToPt = 72.0 / 25.4;
|
||||
constexpr double c_dMMToDx = 72 * 20 / 25.4;
|
||||
const double c_dMMToEMU = 36000.0;
|
||||
const double c_dInchToEMU = 914400.0;
|
||||
const double c_dPtToEMU = 12700.0;
|
||||
|
||||
const double c_dSTANDART_STRING_HEIGHT_MM = 4.2333333333333334;
|
||||
const double c_dTHE_SAME_STRING_Y_PRECISION_MM = 0.01;
|
||||
const double c_dLINE_DISTANCE_ERROR_MM = 0.5;
|
||||
const double c_dERROR_OF_RIGHT_BORDERS_MM = 0.5;
|
||||
const double c_dCENTER_POSITION_ERROR_MM = 1.5;
|
||||
const double c_dTHE_STRING_X_PRECISION_MM = 0.5;
|
||||
const double c_dERROR_FOR_TEXT_WITH_GRAPHICS_MM = 0.1;
|
||||
const double c_dGRAPHICS_ERROR_MM = 0.5;
|
||||
const double c_GRAPHICS_ERROR_IN_LINES_MM = 0.3;
|
||||
|
||||
const UINT c_iWhiteColor = 0xFFFFFF;
|
||||
const UINT c_iBlackColor = 0x000000;
|
||||
|
||||
const double c_dSTANDART_LEFT_INDENT_MM = 30;
|
||||
const double c_dSTANDART_RIGHT_INDENT_MM = 15;
|
||||
const double c_dSTANDART_FIRSTLINE_INDENT_MM = 12.5;
|
||||
|
||||
const double c_dRightBorderCorrectionSize[][4] =
|
||||
{
|
||||
//TextFontStyles (N - None, B - Bold, I - Italic)
|
||||
// N B I BI
|
||||
{0.0, 0.0, 0.0, 0.0}, //6pt
|
||||
{0.1, 0.5, 0.0, 0.0}, //7pt
|
||||
{0.1, 0.0, 0.0, 0.0}, //8pt
|
||||
{0.6, 0.0, 0.0, 0.0}, //9pt
|
||||
{0.1, 0.0, 0.7, 0.0}, //10pt
|
||||
{0.5, 0.2, 0.0, 0.0}, //11pt
|
||||
{1.5, 0.1, 0.0, 0.1}, //12pt
|
||||
{1.1, 0.3, 0.0, 0.0}, //14pt
|
||||
{0.0, 0.1, 0.0, 0.0}, //16pt
|
||||
{2.3, 0.6, 0.0, 0.1}, //18pt
|
||||
{2.1, 0.0, 0.0, 0.0}, //20pt
|
||||
{1.4, 0.0, 0.0, 0.0}, //22pt
|
||||
{0.0, 0.4, 0.0, 0.0}, //24pt
|
||||
{0.0, 0.0, 0.0, 0.0}, //26pt
|
||||
{0.0, 1.2, 0.5, 0.0}, //28pt
|
||||
{4.7, 0.0, 0.0, 0.0}, //36pt
|
||||
{0.0, 0.0, 0.0, 0.0}, //48pt
|
||||
{4.1, 0.0, 0.0, 0.0}, //72pt
|
||||
{0.0, 0.0, 0.0, 0.0}, //>72pt
|
||||
};
|
||||
81
DocxRenderer/src/resources/LinesTable.h
Normal file
81
DocxRenderer/src/resources/LinesTable.h
Normal file
@ -0,0 +1,81 @@
|
||||
#pragma once
|
||||
#include <string>
|
||||
#include <map>
|
||||
#include <algorithm>
|
||||
|
||||
enum class eSimpleLineType
|
||||
{
|
||||
sltUnknown,
|
||||
sltDot,
|
||||
sltDash,
|
||||
sltWave
|
||||
};
|
||||
|
||||
enum class eLineType
|
||||
{
|
||||
ltUnknown,
|
||||
ltSingle,
|
||||
ltDouble,
|
||||
ltThick,
|
||||
ltDotted,
|
||||
ltDottedHeavy,
|
||||
ltDash,
|
||||
ltDashedHeavy,
|
||||
ltDashLong,
|
||||
ltDashLongHeavy,
|
||||
ltDotDash,
|
||||
ltDashDotHeavy,
|
||||
ltDotDotDash,
|
||||
ltDashDotDotHeavy,
|
||||
ltWave,
|
||||
ltWavyHeavy,
|
||||
ltWavyDouble,
|
||||
ltWords,
|
||||
ltNone
|
||||
};
|
||||
|
||||
class LinesTable
|
||||
{
|
||||
public:
|
||||
LinesTable ()
|
||||
{
|
||||
InitLinesTable ();
|
||||
}
|
||||
|
||||
inline std::wstring ConverLineToString(const eLineType& sKey)
|
||||
{
|
||||
auto iter = m_Table.find(sKey);
|
||||
return iter == m_Table.end() ? L"\"none\"" : iter->second;
|
||||
}
|
||||
|
||||
private:
|
||||
std::map<eLineType, std::wstring> m_Table;
|
||||
|
||||
private:
|
||||
void InitLinesTable()
|
||||
{
|
||||
if (m_Table.size())
|
||||
return;
|
||||
|
||||
//ECMA-376 Part 1 17.18.99 ST_Underline (Underline Patterns)
|
||||
m_Table.insert({eLineType::ltSingle, L"\"single\""});
|
||||
m_Table.insert({eLineType::ltDouble, L"\"double\"" });
|
||||
m_Table.insert({eLineType::ltThick, L"\"thick\"" });
|
||||
m_Table.insert({eLineType::ltDotted, L"\"dotted\"" });
|
||||
m_Table.insert({eLineType::ltDottedHeavy, L"\"dottedHeavy\"" });
|
||||
m_Table.insert({eLineType::ltDash, L"\"dash\"" });
|
||||
m_Table.insert({eLineType::ltDashedHeavy, L"\"dashedHeavy\"" });
|
||||
m_Table.insert({eLineType::ltDashLong, L"\"dashLong\"" });
|
||||
m_Table.insert({eLineType::ltDashLongHeavy, L"\"dashLongHeavy\"" });
|
||||
m_Table.insert({eLineType::ltDotDash, L"\"dotDash\"" });
|
||||
m_Table.insert({eLineType::ltDashDotHeavy, L"\"dashDotHeavy\"" });
|
||||
m_Table.insert({eLineType::ltDotDotDash, L"\"dotDotDash\"" });
|
||||
m_Table.insert({eLineType::ltDashDotDotHeavy, L"\"dashDotDotHeavy\"" });
|
||||
m_Table.insert({eLineType::ltWave, L"\"wave\"" });
|
||||
m_Table.insert({eLineType::ltWavyHeavy, L"\"wavyHeavy\"" });
|
||||
m_Table.insert({eLineType::ltWavyDouble, L"\"wavyDouble\"" });
|
||||
m_Table.insert({eLineType::ltWords, L"\"words\"" });
|
||||
m_Table.insert({eLineType::ltNone, L"\"none\"" });
|
||||
}
|
||||
};
|
||||
|
||||
22
DocxRenderer/src/resources/SingletonTemplate.h
Normal file
22
DocxRenderer/src/resources/SingletonTemplate.h
Normal file
@ -0,0 +1,22 @@
|
||||
#pragma once
|
||||
|
||||
template<class T>
|
||||
class SingletonTemplate{
|
||||
public:
|
||||
static T& GetInstance()
|
||||
{
|
||||
static T instance;
|
||||
return instance;
|
||||
}
|
||||
protected:
|
||||
SingletonTemplate(){}
|
||||
SingletonTemplate(const SingletonTemplate&) = delete;
|
||||
SingletonTemplate& operator=(const SingletonTemplate&) = delete;
|
||||
virtual ~SingletonTemplate() {}
|
||||
};
|
||||
|
||||
template<class T>
|
||||
inline T& SingletonInstance()
|
||||
{
|
||||
return SingletonTemplate<T>::GetInstance();
|
||||
}
|
||||
82
DocxRenderer/src/resources/SortElements.h
Normal file
82
DocxRenderer/src/resources/SortElements.h
Normal file
@ -0,0 +1,82 @@
|
||||
#pragma once
|
||||
|
||||
#include <vector>
|
||||
|
||||
// у класса T должен быть метод IsBigger, IsBiggerOrEqual
|
||||
template<typename T>
|
||||
void SortElements(std::vector<T*>& oArray)
|
||||
{
|
||||
int nSize = (int)oArray.size();
|
||||
|
||||
// handle 0, 1 and 2 elements
|
||||
if (nSize <= 1)
|
||||
return;
|
||||
if (nSize == 2)
|
||||
{
|
||||
if (oArray[0]->IsBigger(oArray[1]))
|
||||
{
|
||||
T* pTemp = oArray[0];
|
||||
oArray[0] = oArray[1];
|
||||
oArray[1] = pTemp;
|
||||
}
|
||||
return;
|
||||
}
|
||||
|
||||
T* tTemp;
|
||||
|
||||
// arrange elements as tree with greater elements appearing first
|
||||
int nIndex = (nSize >> 1) - 1, nCurr = 0, nNext = 0;
|
||||
int nLast = nSize - 1;
|
||||
int nHalf = nSize >> 1;
|
||||
do
|
||||
{
|
||||
// save element at start of chain
|
||||
tTemp = oArray[nIndex];
|
||||
|
||||
nCurr = nIndex;
|
||||
while (nCurr < nHalf)
|
||||
{
|
||||
nNext = (nCurr << 1) + 1;
|
||||
if (nNext < nLast && (oArray[nNext + 1]->IsBigger(oArray[nNext])))
|
||||
nNext++;
|
||||
if (tTemp->IsBiggerOrEqual(oArray[nNext]))
|
||||
break;
|
||||
|
||||
// promote element in chain
|
||||
oArray[nCurr] = oArray[nNext];
|
||||
nCurr = nNext;
|
||||
}
|
||||
|
||||
// restore element at end of chain
|
||||
oArray[nCurr] = tTemp;
|
||||
}
|
||||
while (nIndex--);
|
||||
|
||||
// sequentially reduce tree size by removing maximum element and rebalancing
|
||||
nIndex = nSize;
|
||||
while (--nIndex)
|
||||
{
|
||||
// save element at start of chain
|
||||
tTemp = oArray[nIndex];
|
||||
oArray[nIndex] = oArray[0];
|
||||
|
||||
nCurr = 0;
|
||||
nLast = nIndex - 1;
|
||||
nHalf = nIndex >> 1;
|
||||
while (nCurr < nHalf)
|
||||
{
|
||||
nNext = (nCurr << 1) + 1;
|
||||
if (nNext < nLast && (oArray[nNext + 1]->IsBigger(oArray[nNext])))
|
||||
nNext++;
|
||||
if (tTemp->IsBiggerOrEqual(oArray[nNext]))
|
||||
break;
|
||||
|
||||
// promote element in chain
|
||||
oArray[nCurr] = oArray[nNext];
|
||||
nCurr = nNext;
|
||||
}
|
||||
|
||||
// restore element at end of chain
|
||||
oArray[nCurr] = tTemp;
|
||||
}
|
||||
}
|
||||
175
DocxRenderer/src/resources/VectorGraphics.cpp
Normal file
175
DocxRenderer/src/resources/VectorGraphics.cpp
Normal file
@ -0,0 +1,175 @@
|
||||
#include "VectorGraphics.h"
|
||||
#include "../DesktopEditor/common/Types.h"
|
||||
#include "../DesktopEditor/graphics/structures.h"
|
||||
#include <algorithm>
|
||||
|
||||
namespace NSDocxRenderer
|
||||
{
|
||||
CVectorGraphics::CVectorGraphics()
|
||||
{
|
||||
m_pData = nullptr;
|
||||
m_lSize = 0;
|
||||
|
||||
m_pDataCur = m_pData;
|
||||
m_lSizeCur = m_lSize;
|
||||
|
||||
End();
|
||||
}
|
||||
|
||||
CVectorGraphics::~CVectorGraphics()
|
||||
{
|
||||
RELEASEMEM(m_pData);
|
||||
}
|
||||
|
||||
void CVectorGraphics::AddSize(size_t nSize)
|
||||
{
|
||||
if (nullptr == m_pData)
|
||||
{
|
||||
m_lSize = std::max(nSize, (size_t)500);
|
||||
m_pData = (double *)malloc(m_lSize * sizeof(double));
|
||||
|
||||
m_lSizeCur = 0;
|
||||
m_pDataCur = m_pData;
|
||||
return;
|
||||
}
|
||||
|
||||
if ((m_lSizeCur + nSize) > m_lSize)
|
||||
{
|
||||
while ((m_lSizeCur + nSize) > m_lSize)
|
||||
{
|
||||
m_lSize *= 2;
|
||||
}
|
||||
|
||||
double *pRealloc = (double *)realloc(m_pData, m_lSize * sizeof(double));
|
||||
if (nullptr != pRealloc)
|
||||
{
|
||||
// реаллок сработал
|
||||
m_pData = pRealloc;
|
||||
m_pDataCur = m_pData + m_lSizeCur;
|
||||
}
|
||||
else
|
||||
{
|
||||
double *pMalloc = (double *)malloc(m_lSize * sizeof(double));
|
||||
memcpy(pMalloc, m_pData, m_lSizeCur * sizeof(double));
|
||||
|
||||
free(m_pData);
|
||||
m_pData = pMalloc;
|
||||
m_pDataCur = m_pData + m_lSizeCur;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
void CVectorGraphics::MoveTo(const double &x1, const double &y1)
|
||||
{
|
||||
AddSize(3);
|
||||
*m_pDataCur = vgtMove;
|
||||
++m_pDataCur;
|
||||
|
||||
*m_pDataCur = x1;
|
||||
++m_pDataCur;
|
||||
*m_pDataCur = y1;
|
||||
++m_pDataCur;
|
||||
|
||||
m_lSizeCur += 3;
|
||||
|
||||
CheckPoint(x1, y1);
|
||||
}
|
||||
|
||||
void CVectorGraphics::LineTo(const double &x1, const double &y1)
|
||||
{
|
||||
AddSize(3);
|
||||
*m_pDataCur = vgtLine;
|
||||
++m_pDataCur;
|
||||
|
||||
*m_pDataCur = x1;
|
||||
++m_pDataCur;
|
||||
*m_pDataCur = y1;
|
||||
++m_pDataCur;
|
||||
|
||||
m_lSizeCur += 3;
|
||||
|
||||
CheckPoint(x1, y1);
|
||||
}
|
||||
|
||||
void CVectorGraphics::CurveTo(const double &x1, const double &y1,
|
||||
const double &x2, const double &y2,
|
||||
const double &x3, const double &y3)
|
||||
{
|
||||
AddSize(7);
|
||||
*m_pDataCur = vgtCurve;
|
||||
++m_pDataCur;
|
||||
|
||||
*m_pDataCur = x1;
|
||||
++m_pDataCur;
|
||||
*m_pDataCur = y1;
|
||||
++m_pDataCur;
|
||||
*m_pDataCur = x2;
|
||||
++m_pDataCur;
|
||||
*m_pDataCur = y2;
|
||||
++m_pDataCur;
|
||||
*m_pDataCur = x3;
|
||||
++m_pDataCur;
|
||||
*m_pDataCur = y3;
|
||||
++m_pDataCur;
|
||||
|
||||
m_lSizeCur += 7;
|
||||
|
||||
CheckPoint(x1, y1);
|
||||
CheckPoint(x2, y2);
|
||||
CheckPoint(x3, y3);
|
||||
}
|
||||
|
||||
void CVectorGraphics::Close()
|
||||
{
|
||||
AddSize(1);
|
||||
*m_pDataCur = vgtClose;
|
||||
++m_pDataCur;
|
||||
|
||||
m_lSizeCur += 1;
|
||||
}
|
||||
|
||||
size_t CVectorGraphics::GetCurSize() const
|
||||
{
|
||||
return m_lSizeCur;
|
||||
}
|
||||
|
||||
void CVectorGraphics::Clear()
|
||||
{
|
||||
RELEASEMEM(m_pData);
|
||||
|
||||
m_pData = nullptr;
|
||||
m_lSize = 0;
|
||||
|
||||
m_pDataCur = m_pData;
|
||||
m_lSizeCur = 0;
|
||||
}
|
||||
|
||||
void CVectorGraphics::ClearNoAttack()
|
||||
{
|
||||
m_pDataCur = m_pData;
|
||||
m_lSizeCur = 0;
|
||||
}
|
||||
|
||||
void CVectorGraphics::End()
|
||||
{
|
||||
ClearNoAttack();
|
||||
|
||||
//todo
|
||||
m_dLeft = 0xFFFFFF;
|
||||
m_dTop = 0xFFFFFF;
|
||||
m_dRight = -0xFFFFFF;
|
||||
m_dBottom = -0xFFFFFF;
|
||||
}
|
||||
|
||||
void CVectorGraphics::CheckPoint(const double &x, const double &y)
|
||||
{
|
||||
if (m_dLeft > x)
|
||||
m_dLeft = x;
|
||||
if (m_dRight < x)
|
||||
m_dRight = x;
|
||||
if (m_dTop > y)
|
||||
m_dTop = y;
|
||||
if (m_dBottom < y)
|
||||
m_dBottom = y;
|
||||
}
|
||||
}
|
||||
51
DocxRenderer/src/resources/VectorGraphics.h
Normal file
51
DocxRenderer/src/resources/VectorGraphics.h
Normal file
@ -0,0 +1,51 @@
|
||||
#pragma once
|
||||
#include <stddef.h>
|
||||
|
||||
namespace NSDocxRenderer
|
||||
{
|
||||
class CVectorGraphics
|
||||
{
|
||||
public:
|
||||
enum VectorGraphicsType
|
||||
{
|
||||
vgtMove = 0,
|
||||
vgtLine = 1,
|
||||
vgtCurve = 2,
|
||||
vgtClose = 3
|
||||
};
|
||||
|
||||
public:
|
||||
double* m_pData;
|
||||
size_t m_lSize;
|
||||
|
||||
double* m_pDataCur;
|
||||
size_t m_lSizeCur;
|
||||
|
||||
public:
|
||||
double m_dLeft;
|
||||
double m_dTop;
|
||||
double m_dRight;
|
||||
double m_dBottom;
|
||||
|
||||
public:
|
||||
CVectorGraphics();
|
||||
~CVectorGraphics();
|
||||
|
||||
inline void AddSize(size_t nSize);
|
||||
|
||||
public:
|
||||
void MoveTo(const double& x1, const double& y1);
|
||||
void LineTo(const double& x1, const double& y1);
|
||||
void CurveTo(const double& x1, const double& y1, const double& x2, const double& y2, const double& x3, const double& y3);
|
||||
void Close();
|
||||
|
||||
size_t GetCurSize() const;
|
||||
|
||||
void Clear();
|
||||
void ClearNoAttack();
|
||||
|
||||
void End();
|
||||
|
||||
void CheckPoint(const double& x, const double& y);
|
||||
};
|
||||
}
|
||||
File diff suppressed because one or more lines are too long
@ -1,10 +1,5 @@
|
||||
#pragma once
|
||||
|
||||
#ifndef DOCX_RENDERER_RESOURCES
|
||||
#define DOCX_RENDERER_RESOURCES
|
||||
|
||||
#include <string>
|
||||
|
||||
bool CreateTemplate(const std::wstring& strDirectory);
|
||||
|
||||
#endif
|
||||
|
||||
47
DocxRenderer/src/resources/utils.h
Normal file
47
DocxRenderer/src/resources/utils.h
Normal file
@ -0,0 +1,47 @@
|
||||
#pragma once
|
||||
#include "../DesktopEditor/common/Types.h"
|
||||
#include "../DesktopEditor/common/StringUTF32.h"
|
||||
|
||||
inline LONG ConvertColorBGRToRGB(LONG lBGR)
|
||||
{
|
||||
return (0x00FFFFFF & (((lBGR & 0xFF) << 16) | (lBGR & 0x0000FF00) | ((lBGR >> 16) & 0xFF)));
|
||||
}
|
||||
|
||||
inline bool IsSpaceUtf32(const uint32_t& c)
|
||||
{
|
||||
return (' ' == c) ? true : false;
|
||||
}
|
||||
inline bool IsSpaceUtf32(const NSStringUtils::CStringUTF32& oText)
|
||||
{
|
||||
if (1 != oText.length())
|
||||
return false;
|
||||
return IsSpaceUtf32(oText.ToStdWString()[0]);
|
||||
}
|
||||
|
||||
inline bool IsUnicodeSymbol( int symbol )
|
||||
{
|
||||
bool result = false;
|
||||
|
||||
if ( ( 0x0009 == symbol ) || ( 0x000A == symbol ) || ( 0x000D == symbol ) ||
|
||||
( ( 0x0020 <= symbol ) && ( 0xD7FF >= symbol ) ) || ( ( 0xE000 <= symbol ) && ( symbol <= 0xFFFD ) ) ||
|
||||
( ( 0x10000 <= symbol ) && symbol ) )
|
||||
{
|
||||
result = true;
|
||||
}
|
||||
|
||||
return result;
|
||||
}
|
||||
|
||||
// 2-byte number
|
||||
inline short little_endian_2_big_endian( short s )
|
||||
{
|
||||
return ( ( s >> 8) & 0xff ) + ( ( s << 8 ) & 0xff00 );
|
||||
}
|
||||
|
||||
/*========================================================================================================*/
|
||||
|
||||
// 4-byte number
|
||||
inline int little_endian_2_big_endian( int i )
|
||||
{
|
||||
return ( ( i & 0xff ) << 24 ) + ( ( i & 0xff00 ) << 8 ) + ( ( i & 0xff0000 ) >> 8 ) + ( ( i >> 24 ) & 0xff );
|
||||
}
|
||||
@ -87,40 +87,55 @@ int main(int argc, char *argv[])
|
||||
if (!NSDirectory::Exists(sTempDirOut))
|
||||
NSDirectory::CreateDirectory(sTempDirOut);
|
||||
|
||||
std::wstring sSourceFile = L"PATH_TO_TEST_FILE";
|
||||
std::wstring sDestFile = NSFile::GetProcessDirectory() + L"/output.docx";
|
||||
//Добавляем все файлы из определенного каталога
|
||||
//std::vector<std::wstring> sSourceFiles = NSDirectory::GetFiles(L"C:\\Folder");
|
||||
std::vector<std::wstring> sSourceFiles;
|
||||
//Или добавляем любой нужный файл
|
||||
//sSourceFiles.push_back(L"C:\\File.pdf");
|
||||
|
||||
std::wstring sTextDirOut = NSFile::GetProcessDirectory() + L"/text";
|
||||
if (!NSDirectory::Exists(sTextDirOut))
|
||||
NSDirectory::CreateDirectory(sTextDirOut);
|
||||
|
||||
IOfficeDrawingFile* pReader = NULL;
|
||||
|
||||
COfficeFileFormatChecker oChecker;
|
||||
if (oChecker.isOfficeFile(sSourceFile))
|
||||
int nFileType = 0;
|
||||
|
||||
CDocxRenderer oDocxRenderer(pFonts);
|
||||
oDocxRenderer.SetTempFolder(sTempDirOut);
|
||||
|
||||
for (size_t nIndex = 0; nIndex < sSourceFiles.size(); nIndex++)
|
||||
{
|
||||
switch (oChecker.nFileType)
|
||||
if (oChecker.isOfficeFile(sSourceFiles[nIndex]))
|
||||
{
|
||||
case AVS_OFFICESTUDIO_FILE_CROSSPLATFORM_PDF:
|
||||
pReader = new PdfReader::CPdfReader(pFonts);
|
||||
break;
|
||||
case AVS_OFFICESTUDIO_FILE_CROSSPLATFORM_XPS:
|
||||
pReader = new CXpsFile(pFonts);
|
||||
break;
|
||||
case AVS_OFFICESTUDIO_FILE_CROSSPLATFORM_DJVU:
|
||||
pReader = new CDjVuFile(pFonts);
|
||||
break;
|
||||
default:
|
||||
break;
|
||||
nFileType = oChecker.nFileType;
|
||||
switch (nFileType)
|
||||
{
|
||||
case AVS_OFFICESTUDIO_FILE_CROSSPLATFORM_PDF:
|
||||
pReader = new PdfReader::CPdfReader(pFonts);
|
||||
break;
|
||||
case AVS_OFFICESTUDIO_FILE_CROSSPLATFORM_XPS:
|
||||
pReader = new CXpsFile(pFonts);
|
||||
break;
|
||||
case AVS_OFFICESTUDIO_FILE_CROSSPLATFORM_DJVU:
|
||||
pReader = new CDjVuFile(pFonts);
|
||||
break;
|
||||
default:
|
||||
break;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
if (!pReader)
|
||||
{
|
||||
pFonts->Release();
|
||||
return 0;
|
||||
}
|
||||
if (!pReader)
|
||||
{
|
||||
pFonts->Release();
|
||||
return 0;
|
||||
}
|
||||
|
||||
pReader->SetTempDirectory(sTempDir);
|
||||
pReader->SetTempDirectory(sTempDir);
|
||||
|
||||
#ifndef LOAD_FILE_AS_BINARY
|
||||
pReader->LoadFromFile(sSourceFile);
|
||||
pReader->LoadFromFile(sSourceFiles[nIndex]);
|
||||
#else
|
||||
BYTE* pFileBinary = NULL;
|
||||
DWORD nFileBinaryLen = 0;
|
||||
@ -142,19 +157,27 @@ int main(int argc, char *argv[])
|
||||
}
|
||||
}
|
||||
#else
|
||||
CDocxRenderer oDocxRenderer(pFonts);
|
||||
|
||||
// проверить все режимы
|
||||
NSDocxRenderer::TextAssociationType taType;
|
||||
//taType = NSDocxRenderer::TextAssociationTypeBlockChar;
|
||||
//taType = NSDocxRenderer::TextAssociationTypeBlockLine;
|
||||
taType = NSDocxRenderer::TextAssociationTypePlainLine;
|
||||
//taType = NSDocxRenderer::TextAssociationTypePlainParagraph;
|
||||
oDocxRenderer.SetTextAssociationType(taType);
|
||||
std::wstring sExtention = NSFile::GetFileExtention(sSourceFiles[nIndex]);
|
||||
std::wstring sFileNameWithExtention = NSFile::GetFileName(sSourceFiles[nIndex]);
|
||||
std::wstring sFileName = sFileNameWithExtention.substr(0, sFileNameWithExtention.size() - 1 - sExtention.size());
|
||||
std::wstring sDocx = L"/" + sFileName + L".docx";
|
||||
std::wstring sZip = L"/" + sFileName + L".zip";
|
||||
|
||||
oDocxRenderer.SetTempFolder(sTempDirOut);
|
||||
oDocxRenderer.Convert(pReader, sDestFile);
|
||||
// проверить все режимы
|
||||
NSDocxRenderer::TextAssociationType taType;
|
||||
//taType = NSDocxRenderer::tatBlockChar;
|
||||
//taType = NSDocxRenderer::tatBlockLine;
|
||||
//taType = NSDocxRenderer::tatPlainLine;
|
||||
//taType = NSDocxRenderer::tatShapeLine;
|
||||
taType = NSDocxRenderer::tatPlainParagraph;
|
||||
|
||||
oDocxRenderer.SetTextAssociationType(taType);
|
||||
oDocxRenderer.Convert(pReader, sTextDirOut+sDocx);
|
||||
//Если сразу нужен zip-архив
|
||||
//oDocxRenderer.Convert(pReader, sPlainParagraphDirOut+sZip);
|
||||
#endif
|
||||
}
|
||||
|
||||
delete pReader;
|
||||
pFonts->Release();
|
||||
|
||||
@ -35,34 +35,35 @@ window.onload = function()
|
||||
|
||||
var reader = new FileReader();
|
||||
reader.onload = function(e) {
|
||||
if (!window.nativeZlibEngine.open(e.target.result)) return;
|
||||
var files = window.nativeZlibEngine.files;
|
||||
var jsZlib = new AscCommon.CZLibEngineJS();
|
||||
if (!jsZlib.open(e.target.result)) return;
|
||||
var files = jsZlib.files;
|
||||
var _files = {};
|
||||
for (var _path in files)
|
||||
{
|
||||
_files[_path] = window.nativeZlibEngine.getFile(_path);
|
||||
_files[_path] = jsZlib.getFile(_path);
|
||||
window.writeFile(_path, _files[_path]);
|
||||
}
|
||||
window.nativeZlibEngine.close();
|
||||
jsZlib.close();
|
||||
|
||||
if (!window.nativeZlibEngine.create()) return;
|
||||
if (!jsZlib.create()) return;
|
||||
for (var _path in files)
|
||||
{
|
||||
window.nativeZlibEngine.addFile(_path, _files[_path]);
|
||||
window.nativeZlibEngine.addFile(_path + "new", _files[_path]);
|
||||
window.nativeZlibEngine.removeFile(_path);
|
||||
jsZlib.addFile(_path, _files[_path]);
|
||||
jsZlib.addFile(_path + "new", _files[_path]);
|
||||
jsZlib.removeFile(_path);
|
||||
}
|
||||
var archive = window.nativeZlibEngine.save();
|
||||
window.nativeZlibEngine.close();
|
||||
var archive = jsZlib.save();
|
||||
jsZlib.close();
|
||||
|
||||
window.nativeZlibEngine.open(archive);
|
||||
var files2 = window.nativeZlibEngine.files;
|
||||
jsZlib.open(archive);
|
||||
var files2 = jsZlib.files;
|
||||
for (var _path in files2)
|
||||
{
|
||||
window.nativeZlibEngine.getFile(_path);
|
||||
jsZlib.getFile(_path);
|
||||
window.writeFile(_path, files2[_path]);
|
||||
}
|
||||
window.nativeZlibEngine.close();
|
||||
jsZlib.close();
|
||||
};
|
||||
reader.readAsArrayBuffer(file);
|
||||
|
||||
|
||||
@ -313,12 +313,13 @@
|
||||
this.engine = 0;
|
||||
};
|
||||
|
||||
window.nativeZlibEngine = new ZLib();
|
||||
window.onZlibEngineInit = function()
|
||||
{
|
||||
window.nativeZlibEngine.isModuleInit = true;
|
||||
window["ZLibModule_onLoad"] && window["ZLibModule_onLoad"]();
|
||||
};
|
||||
window.AscCommon = window.AscCommon || {};
|
||||
window.AscCommon.CZLibEngineJS = ZLib;
|
||||
window.onZlibEngineInit = function()
|
||||
{
|
||||
ZLib.prototype.isModuleInit = true;
|
||||
window["ZLibModule_onLoad"] && window["ZLibModule_onLoad"]();
|
||||
};
|
||||
|
||||
})(window, undefined);
|
||||
|
||||
|
||||
@ -67,8 +67,12 @@ android {
|
||||
}
|
||||
|
||||
compileOptions {
|
||||
sourceCompatibility(JavaVersion.VERSION_1_8)
|
||||
targetCompatibility(JavaVersion.VERSION_1_8)
|
||||
sourceCompatibility(JavaVersion.VERSION_11)
|
||||
targetCompatibility(JavaVersion.VERSION_11)
|
||||
}
|
||||
|
||||
kotlinOptions {
|
||||
jvmTarget = "11"
|
||||
}
|
||||
|
||||
packagingOptions {
|
||||
@ -87,7 +91,7 @@ android {
|
||||
|
||||
dependencies {
|
||||
implementation(fileTree(mapOf("dir" to "libs", "include" to listOf("*.jar"))))
|
||||
implementation("androidx.appcompat:appcompat:1.3.0")
|
||||
implementation("androidx.appcompat:appcompat:1.4.2")
|
||||
implementation("org.jetbrains.kotlin:kotlin-stdlib-jdk8:${rootProject.extra.get("kotlin_version")}")
|
||||
}
|
||||
|
||||
|
||||
@ -3053,6 +3053,22 @@ namespace NExtractTools
|
||||
}
|
||||
return AVS_FILEUTILS_ERROR_CONVERT;
|
||||
}
|
||||
// docxflat -> docx
|
||||
_UINT32 docxflat2docx(const std::wstring &sFrom, const std::wstring &sTo, const std::wstring &sTemp, InputParams& params)
|
||||
{
|
||||
std::wstring sTempUnpackedDOCX = sTemp + FILE_SEPARATOR_STR + L"docx_unpacked";
|
||||
NSDirectory::CreateDirectory(sTempUnpackedDOCX);
|
||||
|
||||
BinDocxRW::CDocxSerializer m_oCDocxSerializer;
|
||||
|
||||
if (m_oCDocxSerializer.convertFlat(sFrom, sTempUnpackedDOCX))
|
||||
{
|
||||
COfficeUtils oCOfficeUtils(NULL);
|
||||
return (S_OK == oCOfficeUtils.CompressFileOrDirectory(sTempUnpackedDOCX, sTo, false)) ? 0 : AVS_FILEUTILS_ERROR_CONVERT;
|
||||
|
||||
}
|
||||
return AVS_FILEUTILS_ERROR_CONVERT;
|
||||
}
|
||||
// docxflat -> odt
|
||||
_UINT32 docxflat2odt(const std::wstring &sFrom, const std::wstring &sTo, const std::wstring &sTemp, InputParams& params)
|
||||
{
|
||||
@ -3997,25 +4013,23 @@ namespace NExtractTools
|
||||
{
|
||||
if(AVS_OFFICESTUDIO_FILE_CANVAS_WORD == nFormatTo)
|
||||
{
|
||||
if(AVS_OFFICESTUDIO_FILE_DOCUMENT_DOCX_FLAT == nFormatFrom)
|
||||
nRes = docxflat2doct_bin(sFrom, sTo, sTemp, params);
|
||||
else
|
||||
nRes = AVS_FILEUTILS_ERROR_CONVERT_PARAMS;
|
||||
nRes = docxflat2doct_bin(sFrom, sTo, sTemp, params);
|
||||
}
|
||||
//else if (AVS_OFFICESTUDIO_FILE_DOCUMENT_ODT == nFormatTo)
|
||||
//{
|
||||
// if (AVS_OFFICESTUDIO_FILE_DOCUMENT_DOCX_FLAT == nFormatFrom)
|
||||
// nRes = docxflat2odt(sFrom, sTo, sTemp, params);
|
||||
// else
|
||||
// nRes = AVS_FILEUTILS_ERROR_CONVERT_PARAMS;
|
||||
//}
|
||||
else if (AVS_OFFICESTUDIO_FILE_DOCUMENT_ODT == nFormatTo)
|
||||
{
|
||||
nRes = docxflat2odt(sFrom, sTo, sTemp, params);
|
||||
}
|
||||
else if (AVS_OFFICESTUDIO_FILE_DOCUMENT_DOCX == nFormatTo)
|
||||
{
|
||||
nRes = docxflat2docx(sFrom, sTo, sTemp, params);
|
||||
}
|
||||
else
|
||||
{
|
||||
std::wstring sDoctDir = sTemp + FILE_SEPARATOR_STR + _T("doct_unpacked");
|
||||
NSDirectory::CreateDirectory(sDoctDir);
|
||||
std::wstring sTFile = sDoctDir + FILE_SEPARATOR_STR + _T("Editor.bin");
|
||||
|
||||
if(AVS_OFFICESTUDIO_FILE_DOCUMENT_DOCX_FLAT == nFormatFrom)
|
||||
if (AVS_OFFICESTUDIO_FILE_DOCUMENT_DOCX_FLAT == nFormatFrom)
|
||||
nRes = docxflat2doct_bin(sFrom, sTFile, sTemp, params);
|
||||
else
|
||||
nRes = AVS_FILEUTILS_ERROR_CONVERT_PARAMS;
|
||||
@ -4774,7 +4788,7 @@ namespace NExtractTools
|
||||
|
||||
CDocxRenderer oDocxRenderer(pApplicationFonts);
|
||||
|
||||
NSDocxRenderer::TextAssociationType taType = NSDocxRenderer::TextAssociationTypePlainLine;
|
||||
NSDocxRenderer::TextAssociationType taType = NSDocxRenderer::tatPlainLine;
|
||||
if (params.m_oTextParams)
|
||||
{
|
||||
InputParamsText* oTextParams = params.m_oTextParams;
|
||||
@ -4784,16 +4798,16 @@ namespace NExtractTools
|
||||
switch (*oTextParams->m_nTextAssociationType)
|
||||
{
|
||||
case 0:
|
||||
taType = NSDocxRenderer::TextAssociationTypeBlockChar;
|
||||
taType = NSDocxRenderer::tatBlockChar;
|
||||
break;
|
||||
case 1:
|
||||
taType = NSDocxRenderer::TextAssociationTypeBlockLine;
|
||||
taType = NSDocxRenderer::tatBlockLine;
|
||||
break;
|
||||
case 2:
|
||||
taType = NSDocxRenderer::TextAssociationTypePlainLine;
|
||||
taType = NSDocxRenderer::tatPlainLine;
|
||||
break;
|
||||
case 3:
|
||||
taType = NSDocxRenderer::TextAssociationTypePlainParagraph;
|
||||
taType = NSDocxRenderer::tatPlainParagraph;
|
||||
break;
|
||||
default:
|
||||
break;
|
||||
|
||||
@ -60,6 +60,7 @@ namespace NExtractTools
|
||||
_UINT32 docxflat2doct (const std::wstring &sFrom, const std::wstring &sTo, const std::wstring &sTemp, InputParams& params);
|
||||
_UINT32 docxflat2doct_bin (const std::wstring &sFrom, const std::wstring &sTo, const std::wstring &sTemp, InputParams& params);
|
||||
_UINT32 docxflat2odt (const std::wstring &sFrom, const std::wstring &sTo, const std::wstring &sTemp, InputParams& params);
|
||||
_UINT32 docxflat2docx (const std::wstring &sFrom, const std::wstring &sTo, const std::wstring &sTemp, InputParams& params);
|
||||
|
||||
_UINT32 package2ooxml (const std::wstring &sFrom, const std::wstring &sTo, const std::wstring &sTemp, InputParams& params);
|
||||
_UINT32 package2ooxml_dir (const std::wstring &sFrom, const std::wstring &sTo, const std::wstring &sTemp, InputParams& params);
|
||||
|
||||
Reference in New Issue
Block a user