Compare commits

..

43 Commits

Author SHA1 Message Date
51ca6f0ef2 fix docxrenderer enum set 2022-07-11 10:26:35 +03:00
5d97b35ba4 fix build 2022-07-11 10:00:51 +03:00
2bdc1e4a6d fix write application tag 2022-07-11 09:01:21 +03:00
787379808e Merge pull request #977 from ONLYOFFICE/feature/docx_renderer
Feature/docx renderer
2022-07-11 00:47:48 +05:00
9a658a2818 Fix compilation with old compilers 2022-07-10 22:41:47 +03:00
079d80adcb Refactoring 6. 2022-07-10 19:27:29 +03:00
8ec5685786 . 2022-07-10 09:40:44 +03:00
769ab7b238 Refactoring zlib export 2022-07-09 15:46:46 +03:00
2a28ba7060 . 2022-07-09 10:35:23 +03:00
eaabba0860 . 2022-07-09 10:33:48 +03:00
f892022232 . 2022-07-09 10:24:00 +03:00
dfa93c344c Create Pict.cpp 2022-07-08 17:14:16 +03:00
adfc2ef30d office 2003 xml -> docx (with fix errors format) 2022-07-08 17:13:29 +03:00
f8549eaa13 Refactoring 5. Aded support for different types of text underlines. 2022-07-08 16:31:30 +03:00
fc280b1cd6 [android] Update to kotlin 1.7 2022-07-08 10:48:21 +03:00
fc8784c540 Fix excel crash (preinit js context in thread) 2022-07-06 22:44:53 +03:00
17fe15948a [android] Update gradle plugin and jvmTarget 2022-07-06 16:19:14 +03:00
38f11a9f4a fix bug #57904 2022-07-05 14:24:58 +03:00
ea43991901 fix bug #57968 2022-07-05 14:24:12 +03:00
a469bad6e3 Possible fix for the right border problem. 2022-07-04 10:36:46 +03:00
393baf5265 Refactoring 4. 2022-06-30 21:31:51 +03:00
aa6dd092f7 Added shading support. 2022-06-30 21:18:50 +03:00
00e47257e1 Fixed an issue with calculating the right border of the line. Added a correction constant for each font. 2022-06-30 21:18:50 +03:00
01911afb0f Refactoring 3. 2022-06-30 21:18:50 +03:00
fe3e7357d5 Refactoring 2. Improved calculation of the right border of the text. 2022-06-30 21:18:50 +03:00
541c90eacf Refactoring. 2022-06-30 21:18:49 +03:00
4641c135e7 Added support for shape according to the new standard. Fixed problem with extra spaces. Code refactoring. 2022-06-30 21:18:49 +03:00
5c403b39eb Added graphics detection: underline, strikethrough, and text highlighting in color. 2022-06-30 21:18:49 +03:00
1ba6c9b73f minor changes 2022-06-30 21:18:49 +03:00
2ede1b0d65 Fixed problem with merging of mixed text. Improved vertical and horizontal text alignment. Some problems were identified (todo). The interaction between the shape and the paragraph has been worked out. 2022-06-30 21:18:49 +03:00
3e5c005714 Fixed an problem with measuring a line with a long space. 2022-06-30 21:18:49 +03:00
217c5157e1 Added BuildByTypeShapeLine() 2022-06-30 21:18:49 +03:00
6783e79c15 Attempted to rewrite BuildByTypePlainParagraph(). Conclusion - I should use shapes instead of frames. 2022-06-30 21:18:49 +03:00
7f3a658611 Fix problem with spaces. 2022-06-30 21:18:49 +03:00
25a10fb642 DocxRenderer: Added support for TextAssociationType PlainParagraph. 2022-06-30 21:18:49 +03:00
b59980bd62 Merge pull request #964 from ONLYOFFICE/release/v7.2.0
Release/v7.2.0
2022-06-22 21:51:13 +03:00
213b4ddf64 Merge pull request #958 from ONLYOFFICE/release/v7.2.0
Release/v7.2.0
2022-06-10 15:54:17 +03:00
fd08ef00c3 Merge pull request #956 from ONLYOFFICE/release/v7.2.0
Fix compilation
2022-06-10 08:36:04 +03:00
85d7b5063e Merge pull request #955 from ONLYOFFICE/release/v7.2.0
Release/v7.2.0
2022-06-10 08:27:41 +03:00
ce06cd0c4c Merge pull request #951 from ONLYOFFICE/release/v7.2.0
Refactoring ooxmlsignature library
2022-06-09 16:46:24 +03:00
e5e30596f0 Merge pull request #950 from ONLYOFFICE/release/v7.2.0
Release/v7.2.0
2022-06-08 17:24:32 +03:00
0af7c8b984 Merge pull request #946 from ONLYOFFICE/release/v7.2.0
Release/v7.2.0
2022-05-28 22:11:28 +03:00
e6c7efc0d5 Merge pull request #941 from ONLYOFFICE/release/v7.2.0
Release/v7.2.0
2022-05-26 18:18:33 +03:00
98 changed files with 8594 additions and 5578 deletions

View File

@ -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;

View File

@ -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

View File

@ -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
{

View File

@ -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);
}

View File

@ -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);

View File

@ -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"

View File

@ -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;

View File

@ -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()

View File

@ -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_

View File

@ -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_

View File

@ -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;
}
};

View File

@ -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;
}

View File

@ -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" );

View File

@ -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;

View File

@ -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)

View File

@ -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,

View File

@ -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 \

View File

@ -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"

View File

@ -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>

View File

@ -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>

View File

@ -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_

View File

@ -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_

View File

@ -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 );
}

View File

@ -110,11 +110,6 @@ namespace OOX
void FixAfterRead();
bool Write(const CPath& oFilePath)
{
// TO DO: Запись надо править. Она НЕ РАБОТАЕТ!!!! Проблемы в IFileContainer.
//return false;
// Создаем папку
NSDirectory::CreateDirectory(oFilePath.GetPath());

View File

@ -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;
}
}

View File

@ -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;
};

View File

@ -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

View File

@ -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",

View File

@ -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
{

View File

@ -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

View File

@ -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_

View File

@ -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">";

View File

@ -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;

View File

@ -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 );

View 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

View File

@ -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
{

View File

@ -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;
}

View File

@ -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;

View File

@ -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);
}
}
}

View File

@ -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 );

View File

@ -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<>
};

View File

@ -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);

View File

@ -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;
};
//--------------------------------------------------------------------------------

View File

@ -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_

View File

@ -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

View File

@ -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;

View File

@ -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)
{

View File

@ -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
{

View File

@ -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()

View File

@ -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
{

View File

@ -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();

View File

@ -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)

View File

@ -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);
}
}
}

View File

@ -350,7 +350,7 @@ namespace NSJSBase
return _value;
}
void CJSContext::MoveToThread()
void CJSContext::MoveToThread(ASC_THREAD_ID* id)
{
// none
}

View File

@ -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;

View File

@ -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);

View File

@ -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

View File

@ -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

View 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;
};
}

View File

@ -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

View 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

View 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;
}
}

View 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);
};
}

View 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>");
}
}

View File

@ -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

View 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

View 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;
};
}

View 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;
}
}
}
}
}
}

View File

@ -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();
};
}

View 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

View File

@ -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

View 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);
}
}

View 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);
};
}

View 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;
}
}

View File

@ -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);
};
}

View 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; }
}
}

View File

@ -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

View 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;
}
}
}
}

View 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);
};
}

File diff suppressed because it is too large Load Diff

View File

@ -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);
};
}

View 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
}
};

View 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
};

View 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\"" });
}
};

View 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();
}

View 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;
}
}

View 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;
}
}

View 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

View File

@ -1,10 +1,5 @@
#pragma once
#ifndef DOCX_RENDERER_RESOURCES
#define DOCX_RENDERER_RESOURCES
#include <string>
bool CreateTemplate(const std::wstring& strDirectory);
#endif

View 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 );
}

View File

@ -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();

View File

@ -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);

View 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);

View File

@ -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")}")
}

View File

@ -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;

View File

@ -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);