Compare commits

..

19 Commits

Author SHA1 Message Date
fcd7818675 Add test for heif 2025-08-04 12:51:33 +03:00
6d707ebae2 Fix decode 2025-07-28 13:28:20 +03:00
41dc23ce53 Add Release/Debug libs 2025-07-24 12:10:26 +03:00
a817cd54d5 Fix static build 2025-07-17 20:11:46 +03:00
f5ddf8c6ce Fix build 2025-07-10 18:27:15 +03:00
29355d337b Fix encode 2025-07-07 18:01:25 +03:00
8c6a26895b Add read from memory 2025-07-02 13:22:30 +03:00
0154543b01 Remove temp file 2025-06-30 16:25:28 +03:00
3e2dee5719 Fix heif encode 2025-06-30 16:13:03 +03:00
c25f8cc204 Fix heif image convert 2025-06-30 13:51:05 +03:00
d3aae6dfcb Add heif decode and encode 2025-06-29 10:08:51 +03:00
03463ee0e4 Merge remote-tracking branch 'origin/release/v9.0.0' into develop 2025-05-29 12:34:25 +03:00
c964ed7d58 Merge branch hotfix/v8.3.3 into develop 2025-04-21 09:03:54 +00:00
21028c2ca5 Merge pull request 'hotfix/v8.3.3' (#276) from hotfix/v8.3.3 into develop
Reviewed-on: https://git.onlyoffice.com/ONLYOFFICE/core/pulls/276
2025-04-07 11:58:23 +00:00
3c2fd33c7a Merge pull request 'FIx bug #73451' (#272) from fix/bug73451 into develop
Reviewed-on: https://git.onlyoffice.com/ONLYOFFICE/core/pulls/272
2025-04-04 10:44:44 +00:00
f9062d7d38 Merge pull request 'Fix bug #73585' (#271) from fix/bug73585 into develop
Reviewed-on: https://git.onlyoffice.com/ONLYOFFICE/core/pulls/271
2025-04-04 10:44:33 +00:00
cafdb1d2a5 Merge branch hotfix/v8.3.2 into develop 2025-04-01 08:34:19 +00:00
7857106d76 Fix bug #73585 2025-03-21 13:43:19 +05:00
64c74192c7 FIx bug #73451 2025-03-20 16:09:36 +05:00
298 changed files with 3665 additions and 15126 deletions

View File

@ -12,7 +12,7 @@
#include "StaticFunctions.h"
#include "ConstValues.h"
#define DEFAULT_FONT_SIZE 12
#define DEFAULT_FONT_SIZE 14
namespace NSCSS
{
@ -444,11 +444,6 @@ namespace NSCSS
m_oDisplay.SetVAlign(pPropertie.second, unLevel, bHardMode);
break;
}
CASE(L"white-space"):
{
m_oDisplay.SetWhiteSpace(pPropertie.second, unLevel, bHardMode);
break;
}
//TRANSFORM
CASE(L"transform"):
{

View File

@ -58,11 +58,6 @@ namespace NSCSS
return m_pInternal->GetDpi();
}
bool CCssCalculator::HaveStylesById(const std::wstring& wsId) const
{
return m_pInternal->HaveStylesById(wsId);
}
void CCssCalculator::ClearPageData()
{
m_pInternal->ClearPageData();

View File

@ -32,8 +32,6 @@ namespace NSCSS
std::wstring GetEncoding() const;
unsigned short int GetDpi() const;
bool HaveStylesById(const std::wstring& wsId) const;
void ClearPageData();
void ClearEmbeddedStyles();
void ClearAllowedStyleFiles();

View File

@ -184,7 +184,7 @@ namespace NSCSS
}
#endif
const CElement* CStyleStorage::FindElement(const std::wstring& wsSelector) const
const CElement* CStyleStorage::FindElement(const std::wstring& wsSelector)
{
if (wsSelector.empty())
return nullptr;
@ -470,7 +470,7 @@ namespace NSCSS
}
}
const CElement* CStyleStorage::FindSelectorFromStyleData(const std::wstring& wsSelector, const std::map<std::wstring, CElement*>& mStyleData) const
const CElement* CStyleStorage::FindSelectorFromStyleData(const std::wstring& wsSelector, const std::map<std::wstring, CElement*>& mStyleData)
{
std::map<std::wstring, CElement*>::const_iterator itFound = mStyleData.find(wsSelector);
@ -491,21 +491,6 @@ namespace NSCSS
if (arSelectors.empty())
return false;
if (L"#text" == arSelectors.back().m_wsName)
{
if (arSelectors.size() > 1 && arSelectors.back().m_pCompiledStyle->Empty())
*arSelectors.back().m_pCompiledStyle += *(arSelectors.end() - 2)->m_pCompiledStyle;
if(arSelectors.crend() != std::find_if(arSelectors.crbegin(), arSelectors.crend(),
[](const CNode& oNode){ return IsTableElement(oNode.m_wsName); }))
{
arSelectors.back().m_pCompiledStyle->m_oBackground.Clear();
arSelectors.back().m_pCompiledStyle->m_oBorder.Clear();
}
return true;
}
const std::map<std::vector<CNode>, CCompiledStyle>::iterator oItem = m_mUsedStyles.find(arSelectors);
if (oItem != m_mUsedStyles.end())
@ -707,16 +692,6 @@ namespace NSCSS
FindPrevAndKindElements(pFoundName, arNextNodes, arFindedElements, wsName, arClasses);
}
const CElement* pFoundAll = m_oStyleStorage.FindElement(L"*");
if (nullptr != pFoundAll)
{
if (!pFoundAll->Empty())
arFindedElements.push_back(pFoundAll);
FindPrevAndKindElements(pFoundAll, arNextNodes, arFindedElements, wsName, arClasses);
}
if (arFindedElements.size() > 1)
{
std::sort(arFindedElements.rbegin(), arFindedElements.rend(),
@ -790,11 +765,6 @@ namespace NSCSS
return m_nDpi;
}
bool CCssCalculator_Private::HaveStylesById(const std::wstring& wsId) const
{
return nullptr != m_oStyleStorage.FindElement(L'#' + wsId);
}
void CCssCalculator_Private::ClearEmbeddedStyles()
{
m_oStyleStorage.ClearEmbeddedStyles();

View File

@ -37,7 +37,7 @@ namespace NSCSS
void ClearPageData();
#endif
const CElement* FindElement(const std::wstring& wsSelector) const;
const CElement* FindElement(const std::wstring& wsSelector);
private:
typedef struct
{
@ -77,7 +77,7 @@ namespace NSCSS
void GetOutputData(KatanaOutput* oOutput, std::map<std::wstring, CElement*>& mStyleData);
const CElement* FindSelectorFromStyleData(const std::wstring& wsSelector, const std::map<std::wstring, CElement*>& mStyleData) const;
const CElement* FindSelectorFromStyleData(const std::wstring& wsSelector, const std::map<std::wstring, CElement*>& mStyleData);
};
class CCssCalculator_Private
@ -122,8 +122,6 @@ namespace NSCSS
std::wstring GetEncoding() const;
unsigned short int GetDpi() const;
bool HaveStylesById(const std::wstring& wsId) const;
void ClearEmbeddedStyles();
void ClearAllowedStyleFiles();
void ClearStylesFromFile(const std::wstring& wsFilePath);

View File

@ -1328,14 +1328,7 @@ namespace NSCSS
// DISPLAY
CDisplay::CDisplay()
{
m_eWhiteSpace.SetMapping({{L"normal", EWhiteSpace::Normal },
{L"nowrap", EWhiteSpace::Nowrap },
{L"pre", EWhiteSpace::Pre },
{L"pre-line", EWhiteSpace::Pre_Line},
{L"pre-wrap", EWhiteSpace::Pre_Wrap}},
EWhiteSpace::Normal);
}
{}
void CDisplay::Equation(CDisplay &oFirstDisplay, CDisplay &oSecondDisplay)
{
@ -1348,8 +1341,6 @@ namespace NSCSS
CString::Equation(oFirstDisplay.m_oHAlign, oSecondDisplay.m_oHAlign);
CString::Equation(oFirstDisplay.m_oDisplay, oSecondDisplay.m_oDisplay);
CEnum::Equation(oFirstDisplay.m_eWhiteSpace, oSecondDisplay.m_eWhiteSpace);
}
bool CDisplay::SetX(const std::wstring &wsValue, unsigned int unLevel, bool bHardMode)
@ -1413,11 +1404,6 @@ namespace NSCSS
return m_oDisplay.SetValue(wsValue, NSConstValues::DISPLAY_VALUES, unLevel, bHardMode);
}
bool CDisplay::SetWhiteSpace(const std::wstring& wsValue, unsigned int unLevel, bool bHardMode)
{
return m_eWhiteSpace.SetValue(wsValue, unLevel, bHardMode);
}
const CDigit& CDisplay::GetX() const
{
return m_oX;
@ -1453,42 +1439,34 @@ namespace NSCSS
return m_oDisplay;
}
const CEnum& CDisplay::GetWhiteSpace() const
{
return m_eWhiteSpace;
}
bool CDisplay::Empty() const
{
return m_oX.Empty() && m_oY.Empty() && m_oWidth.Empty() && m_oHeight.Empty() &&
m_oHeight.Empty() && m_oVAlign.Empty() && m_oDisplay.Empty() &&
(m_eWhiteSpace.Empty() || m_eWhiteSpace == EWhiteSpace::Normal);
m_oHeight.Empty() && m_oVAlign.Empty() && m_oDisplay.Empty();
}
CDisplay &CDisplay::operator+=(const CDisplay &oDisplay)
{
m_oX += oDisplay.m_oX;
m_oY += oDisplay.m_oY;
m_oWidth = oDisplay.m_oWidth;
m_oHeight = oDisplay.m_oHeight;
m_oHAlign += oDisplay.m_oHAlign;
m_oVAlign += oDisplay.m_oVAlign;
m_oDisplay += oDisplay.m_oDisplay;
m_eWhiteSpace += oDisplay.m_eWhiteSpace;
m_oX += oDisplay.m_oX;
m_oY += oDisplay.m_oY;
m_oWidth = oDisplay.m_oWidth;
m_oHeight = oDisplay.m_oHeight;
m_oHAlign += oDisplay.m_oHAlign;
m_oVAlign += oDisplay.m_oVAlign;
m_oDisplay += oDisplay.m_oDisplay;
return *this;
}
bool CDisplay::operator==(const CDisplay &oDisplay) const
{
return m_oX == oDisplay.m_oX &&
m_oY == oDisplay.m_oY &&
m_oWidth == oDisplay.m_oWidth &&
m_oHeight == oDisplay.m_oHeight &&
m_oHAlign == oDisplay.m_oHAlign &&
m_oVAlign == oDisplay.m_oVAlign &&
m_oDisplay == oDisplay.m_oDisplay &&
m_eWhiteSpace == oDisplay.m_eWhiteSpace.ToInt();
return m_oX == oDisplay.m_oX &&
m_oY == oDisplay.m_oY &&
m_oWidth == oDisplay.m_oWidth &&
m_oHeight == oDisplay.m_oHeight &&
m_oHAlign == oDisplay.m_oHAlign &&
m_oVAlign == oDisplay.m_oVAlign &&
m_oDisplay == oDisplay.m_oDisplay;
}
// STROKE

View File

@ -328,15 +328,6 @@ namespace NSCSS
};
// PROPERTIES
typedef enum
{
Normal,
Nowrap,
Pre,
Pre_Line,
Pre_Wrap
} EWhiteSpace;
class CDisplay
{
public:
@ -356,8 +347,6 @@ namespace NSCSS
bool SetDisplay(const std::wstring& wsValue, unsigned int unLevel, bool bHardMode = false);
bool SetWhiteSpace(const std::wstring& wsValue, unsigned int unLevel, bool bHardMode = false);
const CDigit& GetX() const;
const CDigit& GetY() const;
const CDigit& GetWidth() const;
@ -368,8 +357,6 @@ namespace NSCSS
const CString& GetDisplay() const;
const CEnum& GetWhiteSpace() const;
bool Empty() const;
CDisplay& operator+=(const CDisplay& oDisplay);
@ -384,8 +371,6 @@ namespace NSCSS
CString m_oVAlign;
CString m_oDisplay;
CEnum m_eWhiteSpace;
};
class CStroke

View File

@ -29,7 +29,7 @@ void WriteBaseHtmlStyles(NSFile::CFileBinary& oFile)
oFile.WriteStringUTF8(L"<style>");
// Main styles
oFile.WriteStringUTF8(L"* { font-family: Arial; color:black; white-space:pre; }");
oFile.WriteStringUTF8(L"* { font-family: Arial; }");
oFile.WriteStringUTF8(L"p { margin: 0 0 10px; display: block; }");
oFile.WriteStringUTF8(L"a { color: #0553c1; text-decoration: underline; } a:visited { color: #954f72; text-decoration: underline; }");
oFile.WriteStringUTF8(L"ul { margin-top: 0; margin-bottom: 10px; }");
@ -50,10 +50,11 @@ void WriteBaseHtmlStyles(NSFile::CFileBinary& oFile)
// Styles for code
oFile.WriteStringUTF8(L"code { padding: 2px 4px; font-size: 90%; color: #c7254e; background-color: #f9f2f4; border-radius: 4px; }");
oFile.WriteStringUTF8(L"pre code { padding: 0px; white-space: pre-wrap; border-radius: 0; background-color: #f5f5f5; color:black; }");
oFile.WriteStringUTF8(L"pre code { padding: 0px; white-space: pre-wrap; background-color: transparent; border-radius: 0; color: inherit; }");
oFile.WriteStringUTF8(L"pre { display: block; padding: 9.5px; margin: 0 0 10px; line-height: 1.4; word-break: break-all; word-wrap: break-word; background-color: #f5f5f5; border: 1px solid #ccc; border-radius: 4px; font-size: 1em; }");
oFile.WriteStringUTF8(L"code, pre { font-family: Menlo, Monaco, Consolas, \"Courier New\", monospace; }");
// Styles for headings
oFile.WriteStringUTF8(L"h1 { font-size: 20pt; color: #0f4761; margin-top: 18pt; margin-bottom: 4pt; }");
oFile.WriteStringUTF8(L"h2 { font-size: 16pt; color: #0f4761; margin-top: 8pt; margin-bottom: 4pt; }");
@ -80,16 +81,12 @@ bool ConvertMdFileToHtml(const std::wstring& wsPathToMdFile, const std::wstring&
oFile.WriteStringUTF8(L"<html><body>");
oFile.WriteStringUTF8(L"<head>");
//oFile.WriteStringUTF8(L"<meta charset=\"UTF-8\">");
oFile.WriteStringUTF8(L"<meta http-equiv=\"Content-Type\" content=\"text/html; charset=UTF-8\">");
WriteBaseHtmlStyles(oFile);
oFile.WriteStringUTF8(L"</head>");
bool bResult = true;
if (0 != md_html(sMdData.c_str(), sMdData.length(), ToHtmlFile, &oFile,
MD_DIALECT_GITHUB | MD_FLAG_NOINDENTEDCODEBLOCKS | MD_HTML_FLAG_SKIP_UTF8_BOM,
0))
if (0 != md_html(sMdData.c_str(), sMdData.length(), ToHtmlFile, &oFile, MD_DIALECT_GITHUB, 0))
bResult = false;
oFile.WriteStringUTF8(L"</body></html>");

View File

@ -240,7 +240,7 @@ bool COfficeFileFormatChecker::isPdfFormatFile(unsigned char *pBuffer, int dwByt
documentID.clear();
if (dwBytes < 5 || (pBuffer[0] == 'P' && pBuffer[1] == 'K'))
if (dwBytes < 1)
return false;
pBuffer[dwBytes - 1] = '\0';
@ -1601,15 +1601,12 @@ bool COfficeFileFormatChecker::isOOXFlatFormatFile(unsigned char *pBuffer, int d
const char *xlsxPackage = "progid=\"Excel.Sheet\"";
const char *pptxPackage = "progid=\"PowerPoint.Show\"";
const char *packageFormatLine = "xmlns:pkg=\"http://schemas.microsoft.com/office/2006/xmlPackage\"";
const char* workbookFormatLine = "<Workbook";
const char* htmlFormatLine = "<html";
if (std::string::npos != xml_string.find(docxFormatLine))
{
nFileType = AVS_OFFICESTUDIO_FILE_DOCUMENT_DOCX_FLAT;
}
else if (std::string::npos != xml_string.find(xlsxFormatLine) && ( std::string::npos != xml_string.find(workbookFormatLine) ||
std::string::npos == xml_string.find(htmlFormatLine)))
else if (std::string::npos != xml_string.find(xlsxFormatLine))
{
nFileType = AVS_OFFICESTUDIO_FILE_SPREADSHEET_XLSX_FLAT;
}

View File

@ -47,7 +47,7 @@ win32 {
DEFINES += COPYRIGHT_YEAR=$${CURRENT_YEAR}
QMAKE_TARGET_COMPANY = $$PUBLISHER_NAME
QMAKE_TARGET_COPYRIGHT = © $${PUBLISHER_NAME} $${CURRENT_YEAR}. All rights reserved.
QMAKE_TARGET_COPYRIGHT = Copyright (C) $${PUBLISHER_NAME} $${CURRENT_YEAR}. All rights reserved
# CONFIGURATION
CONFIG(debug, debug|release) {

View File

@ -46,7 +46,6 @@ namespace NSProcessEnv
static const char* gc_proxy = "proxy";
static const char* gc_proxyUser = "proxyUser";
static const char* gc_proxyHeader = "proxyHeader";
static const char* gc_oformAsPdf = "oformAsPdf";
}
// serialize

View File

@ -38,6 +38,7 @@
#define CXIMAGE_SUPPORT_PNM 1
#define CXIMAGE_SUPPORT_RAS 1
#define CXIMAGE_SUPPORT_PIC 1
#define CXIMAGE_SUPPORT_HEIF 1
#define CXIMAGE_SUPPORT_JBG 0 // GPL'd see ../jbig/copying.txt & ../jbig/patents.htm

View File

@ -133,13 +133,17 @@ CXIMAGE_FORMAT_PSD = 20,
#if CXIMAGE_SUPPORT_PIC
CXIMAGE_FORMAR_PIC = 25,
#endif
#if CXIMAGE_SUPPORT_HEIF
CXIMAGE_FORMAT_HEIF = 26,
#endif
CMAX_IMAGE_FORMATS = CXIMAGE_SUPPORT_BMP + CXIMAGE_SUPPORT_GIF + CXIMAGE_SUPPORT_JPG +
CXIMAGE_SUPPORT_PNG + CXIMAGE_SUPPORT_MNG + CXIMAGE_SUPPORT_ICO +
CXIMAGE_SUPPORT_TIF + CXIMAGE_SUPPORT_TGA + CXIMAGE_SUPPORT_PCX +
CXIMAGE_SUPPORT_WBMP+ CXIMAGE_SUPPORT_WMF + CXIMAGE_SUPPORT_PIC +
CXIMAGE_SUPPORT_JBG + CXIMAGE_SUPPORT_JP2 + CXIMAGE_SUPPORT_JPC +
CXIMAGE_SUPPORT_PGX + CXIMAGE_SUPPORT_PNM + CXIMAGE_SUPPORT_RAS +
CXIMAGE_SUPPORT_SKA + CXIMAGE_SUPPORT_RAW + CXIMAGE_SUPPORT_PSD + 1
CXIMAGE_SUPPORT_SKA + CXIMAGE_SUPPORT_RAW + CXIMAGE_SUPPORT_PSD +
CXIMAGE_SUPPORT_HEIF + 1
};
#if CXIMAGE_SUPPORT_EXIF

View File

@ -23,14 +23,14 @@
* LIABILITY, ARISING OUT OF OR IN CONNECTION WITH THE USE OR PERFORMANCE
* OF THIS SOFTWARE.
*/
#pragma warning (disable : 4550)
#pragma warning (disable : 4550)
/*
* TIFF Library
*
* Read and return a packed RGBA image.
*/
*/
#include "tiffiop.h"
#include <stdio.h>
@ -828,11 +828,12 @@ gtStripContig(TIFFRGBAImage* img, uint32* raster, uint32 w, uint32 h)
nrowsub = nrow;
if ((nrowsub%subsamplingver)!=0)
nrowsub+=subsamplingver-nrowsub%subsamplingver;
if (TIFFReadEncodedStrip(tif,
TIFFComputeStrip(tif,row+img->row_offset, 0),
buf,
((row + img->row_offset)%rowsperstrip + nrowsub) * scanline) < 0
&& img->stoponerr)
((row + img->row_offset)%rowsperstrip + nrowsub) * scanline) < 0
&& img->stoponerr)
{
ret = 0;
break;

View File

@ -74,7 +74,6 @@ CV8RealTimeWorker::CV8RealTimeWorker(NSDoctRenderer::CDocBuilder* pBuilder, cons
global->set("native", oNativeCtrl);
CBuilderEmbed* pBuilderJSNative = static_cast<CBuilderEmbed*>(oBuilderJS->getNative());
pBuilderJSNative->SetExternalize(true);
pBuilderJSNative->m_pBuilder = pBuilder;
}
CV8RealTimeWorker::~CV8RealTimeWorker()
@ -1242,13 +1241,13 @@ namespace NSDoctRenderer
while (true)
{
while (_currentPos < _commandsLen && !((_commandsPtr[_currentPos] == '\"' || _commandsPtr[_currentPos] == '\'') && _commandsPtr[_currentPos - 1] != '\\'))
while (_currentPos < _commandsLen && !(_commandsPtr[_currentPos] == '\"' && _commandsPtr[_currentPos - 1] != '\\'))
++_currentPos;
++_currentPos;
size_t _start = _currentPos;
while (_currentPos < _commandsLen && !((_commandsPtr[_currentPos] == '\"' || _commandsPtr[_currentPos] == '\'') && _commandsPtr[_currentPos - 1] != '\\'))
while (_currentPos < _commandsLen && !(_commandsPtr[_currentPos] == '\"' && _commandsPtr[_currentPos - 1] != '\\'))
++_currentPos;
if (_currentPos > _start)
@ -1273,7 +1272,7 @@ namespace NSDoctRenderer
if (m_pInternal->m_nFileType != -1 && m_pInternal->m_bIsOpenedFromSimpleJS)
{
m_pInternal->m_bIsOpenedFromSimpleJS = false;
return 0;
return true;
}
m_pInternal->m_nFileType = -1;
@ -1514,8 +1513,7 @@ namespace NSDoctRenderer
if (nCountParameters > 2)
sParams = _builder_params[2].c_str();
int nSaveError = this->SaveFile(nFormat, _builder_params[1].c_str(), sParams);
bIsNoError = (0 == nSaveError);
this->SaveFile(nFormat, _builder_params[1].c_str(), sParams);
}
else if ("WriteData" == sFuncNum)
{

View File

@ -927,7 +927,7 @@ namespace NSDoctRenderer
COfficeFileFormatChecker oChecker;
if (!oChecker.isOfficeFile(sFileCopy))
return 1;
return false;
if (oChecker.nFileType & AVS_OFFICESTUDIO_FILE_DOCUMENT)
m_nFileType = 0;

View File

@ -289,20 +289,10 @@ public:
return ((CPdfFile*)m_pFile)->SplitPages(arrPageIndex, nLength, data, size);
return NULL;
}
bool MergePages(BYTE* data, LONG size, int nMaxID, const std::string& sPrefixForm, bool bCopy = false)
bool MergePages(BYTE* data, LONG size, int nMaxID, const std::string& sPrefixForm)
{
if (m_nType == 0)
{
// Память из CDrawingFileEmbed освобождается сразу после вызова функции, поэтому копируем
if (bCopy)
{
BYTE* pCopy = (BYTE*)malloc(size);
memcpy(pCopy, data, size);
data = pCopy;
}
// Захватывает полученную память, будет освобождена либо в деструкторе MemStream, либо free в случае неудачи
return ((CPdfFile*)m_pFile)->MergePages(data, size, nMaxID, sPrefixForm);
}
return false;
}
bool UnmergePages()
@ -430,32 +420,22 @@ public:
oRenderer.SetExternalImageStorage(m_pImageStorage);
oRenderer.SetTextAssociationType(NSDocxRenderer::TextAssociationType::tatParagraphToShape);
std::vector<std::wstring> arShapes;
if (0 == mode)
arShapes = oRenderer.ScanPage(m_pFile, nPageIndex);
else
arShapes = oRenderer.ScanPagePptx(m_pFile, nPageIndex);
int nLen = (int)arShapes.size();
NSWasm::CData oRes;
switch (mode)
{
case 0:
case 1:
{
std::vector<std::wstring> arShapes = (0 == mode) ? oRenderer.ScanPage(m_pFile, nPageIndex) : oRenderer.ScanPagePptx(m_pFile, nPageIndex);
int nLen = (int)arShapes.size();
oRes.SkipLen();
oRes.AddInt(nLen);
oRes.SkipLen();
oRes.AddInt(nLen);
for (int i = 0; i < nLen; ++i)
oRes.WriteString(arShapes[i]);
for (int i = 0; i < nLen; ++i)
oRes.WriteString(arShapes[i]);
oRes.WriteLen();
break;
}
case 2:
{
oRes = oRenderer.ScanPageBin(m_pFile, nPageIndex);
break;
}
default:
return NULL;
}
oRes.WriteLen();
BYTE* res = oRes.GetBuffer();
oRes.ClearWithoutAttack();

View File

@ -195,7 +195,7 @@ JSSmart<CJSValue> CDrawingFileEmbed::MergePages(JSSmart<CJSValue> data, JSSmart<
int maxID = nMaxID->toInt32();
std::string prefix = sPrefixForm->toStringA();
CJSDataBuffer buffer = dataPtr->getData();
result = m_pFile->MergePages(buffer.Data, (LONG)buffer.Len, maxID, prefix, true);
result = m_pFile->MergePages(buffer.Data, (LONG)buffer.Len, maxID, prefix);
if (buffer.IsExternalize)
buffer.Free();
}

View File

@ -196,9 +196,7 @@ JSSmart<CJSValue> CGraphicsEmbed::create(JSSmart<CJSValue> Native, JSSmart<CJSVa
}
JSSmart<CJSValue> CGraphicsEmbed::Destroy()
{
// For save image bits, if needed.
m_pInternal->Destroy();
RELEASEOBJECT(m_pInternal);
return NULL;
}
JSSmart<CJSValue> CGraphicsEmbed::EndDraw()

View File

@ -45,7 +45,7 @@ public:
public:
CBuilderDocumentEmbed() : m_pBuilder(NULL), m_bIsValid(false) {}
~CBuilderDocumentEmbed() { if(m_pBuilder && !m_isExternalize) RELEASEOBJECT(m_pBuilder); }
~CBuilderDocumentEmbed() { if(m_pBuilder) RELEASEOBJECT(m_pBuilder); }
virtual void* getObject() { return (void*)m_pBuilder; }
NSDoctRenderer::CDocBuilder_Private* GetPrivate(NSDoctRenderer::CDocBuilder* pBuilder) { return pBuilder->GetPrivate(); }

View File

@ -88,7 +88,6 @@ JSSmart<CJSValue> CBuilderEmbed::OpenTmpFile(JSSmart<CJSValue> path, JSSmart<CJS
JSSmart<CJSObject> oBuilderTmpDoc = CJSContext::createEmbedObject("CBuilderDocumentEmbed");
CBuilderDocumentEmbed* pBuilderTmpDocNative = static_cast<CBuilderDocumentEmbed*>(oBuilderTmpDoc->getNative());
pBuilderTmpDocNative->m_pBuilder = m_pBuilder;
pBuilderTmpDocNative->SetExternalize(true);
pBuilderTmpDocNative->_OpenFile(sPath, sParams);
return oBuilderTmpDoc->toValue();
}

View File

@ -47,7 +47,7 @@ public:
NSDoctRenderer::CDocBuilder* m_pBuilder;
CBuilderEmbed() : m_pBuilder(NULL) {}
~CBuilderEmbed() { if(m_pBuilder && !m_isExternalize) RELEASEOBJECT(m_pBuilder); }
~CBuilderEmbed() { if(m_pBuilder) RELEASEOBJECT(m_pBuilder); }
virtual void* getObject() { return (void*)m_pBuilder; }
NSDoctRenderer::CDocBuilder_Private* GetPrivate() { return m_pBuilder->GetPrivate(); }

View File

@ -42,7 +42,6 @@ namespace NSGraphics
m_pRenderer = NSGraphics::Create();
m_pRenderer->SetFontManager(pManager);
RELEASEINTERFACE(pManager);
int nRasterW = (int)width_px;
int nRasterH = (int)height_px;

View File

@ -115,16 +115,17 @@ namespace NSGraphics
class CGraphics
{
public:
CGraphicsAppImage* m_pAppImage = nullptr;
CGraphicsAppImage* m_pAppImage;
CBgraFrame m_oFrame;
private:
NSGraphics::IGraphicsRenderer* m_pRenderer = nullptr;
NSGraphics::IGraphicsRenderer* m_pRenderer;
CGrState m_oGrState;
public:
CGraphics()
{
m_pAppImage = NULL;
}
~CGraphics()
{

View File

@ -31,7 +31,6 @@ namespace NSJSBase {
{
embed_native_internal = nullptr;
m_pAdapter = nullptr;
m_isExternalize = false;
}
CJSEmbedObject::~CJSEmbedObject()
@ -45,16 +44,6 @@ namespace NSJSBase {
return nullptr;
}
void CJSEmbedObject::SetExternalize(const bool& isExternalize)
{
m_isExternalize = isExternalize;
}
bool CJSEmbedObject::GetExternalize()
{
return m_isExternalize;
}
CJSEmbedObjectAdapterBase* CJSEmbedObject::getAdapter()
{
return nullptr;

View File

@ -194,18 +194,10 @@ namespace NSJSBase
*/
virtual CJSEmbedObjectAdapterBase* getAdapter();
/**
* Use the externalize flag if you are monitoring the object's destruction yourself.
*/
virtual void SetExternalize(const bool& isExternalize = true);
virtual bool GetExternalize();
protected:
CJSEmbedObjectPrivateBase* embed_native_internal;
CJSEmbedObjectAdapterBase* m_pAdapter;
bool m_isExternalize;
friend class CJSEmbedObjectPrivateBase;
friend class CJSEmbedObjectPrivate;
};

View File

@ -10,7 +10,6 @@
@protocol JSEmbedObjectProtocol
-(void*) getNative;
-(void) freeNative;
@end
#if __has_feature(objc_arc)
@ -42,10 +41,6 @@
-(void*) getNative \
{ \
return m_internal; \
} \
-(void) freeNative \
{ \
RELEASEOBJECT(m_internal); \
}
namespace NSJSBase

View File

@ -34,7 +34,6 @@ namespace NSJSBase
// embed
id CreateEmbedNativeObject(NSString* name);
void FreeNativeObject(id embedded_object);
}
namespace NSJSBase

View File

@ -232,14 +232,10 @@ namespace NSJSBase
{
[m_internal->context evaluateScript:@"function jsc_toBase64(r){for(var o=[\"A\",\"B\",\"C\",\"D\",\"E\",\"F\",\"G\",\"H\",\"I\",\"J\",\"K\",\"L\",\"M\",\"N\",\"O\",\"P\",\"Q\",\"R\",\"S\",\"T\",\"U\",\"V\",\"W\",\"X\",\"Y\",\"Z\",\"a\",\"b\",\"c\",\"d\",\"e\",\"f\",\"g\",\"h\",\"i\",\"j\",\"k\",\"l\",\"m\",\"n\",\"o\",\"p\",\"q\",\"r\",\"s\",\"t\",\"u\",\"v\",\"w\",\"x\",\"y\",\"z\",\"0\",\"1\",\"2\",\"3\",\"4\",\"5\",\"6\",\"7\",\"8\",\"9\",\"+\",\"/\"],a=r.length,f=4*(a/3>>0),n=f/76>>0,t=19,v=0,e=[],i=\"\",s=0;s<=n;s++){s==n&&(t=f%76/4>>0);for(var u=0;u<t;u++){for(var c=0,h=0;h<3;h++)c|=r[0+v++],c<<=8;i=\"\";for(var A=0;A<4;A++){i+=o[c>>>26&255],c<<=6,c&=4294967295}e.push(i)}}if(n=a%3!=0?a%3+1:0){for(c=0,h=0;h<3;h++)h<a%3&&(c|=r[0+v++]),c<<=8;i=\"\";for(A=0;A<n;A++){i+=o[c>>>26&255],c<<=6}t=0!=n?4-n:0;for(u=0;u<t;u++)i+=\"=\";e.push(i)}return e.join(\"\")}function jsc_fromBase64(r,o){for(var a,f=r.length,n=0,t=new Array(void 0===o?f:o),v=t,e=0,i=0;e<f;){for(var s=0,u=0,c=0;c<4&&!(f<=e);c++){var h=65<=(a=r.charCodeAt(e++))&&a<=90?a-65:97<=a&&a<=122?a-71:48<=a&&a<=57?a+4:43==a?62:47==a?63:-1;-1!=h?(s<<=6,s|=h,u+=6):c--}for(s<<=24-u,i=u>>>3,c=0;c<i;c++)v[n++]=(16711680&s)>>>16,s<<=8}return t}\n"];
}
// insert embed functions to global object of this context
// insert CreateEmbedObject() function to global object of this context
m_internal->context[@"CreateEmbedObject"] = ^(NSString* name) {
return CreateEmbedNativeObject(name);
};
m_internal->context[@"FreeEmbedObject"] = ^(id embedded_object) {
FreeNativeObject(embedded_object);
};
JSValue* global_js = [m_internal->context globalObject];
[global_js setValue:global_js forProperty:[[NSString alloc] initWithUTF8String:"window"]];
@ -250,8 +246,6 @@ namespace NSJSBase
{
CGlobalContext::GetInstance().UnregisterContextForId(*i);
}
// remove any exceptions pending to not prevent any JSValue deallocations
m_internal->context.exception = nil;
m_internal->context = nil;
}
@ -509,15 +503,6 @@ namespace NSJSBase
return pEmbedObj;
}
void FreeNativeObject(id embedded_object)
{
// check if the object was actually embedded and do nothing if it wasn't
if ([embedded_object conformsToProtocol:@protocol(JSEmbedObjectProtocol)])
{
[embedded_object freeNative];
}
}
JSSmart<CJSValue> CJSEmbedObjectAdapterJSC::Native2Value(JSValue* value)
{
return js_value(value);

View File

@ -214,41 +214,12 @@ namespace NSJSBase
m_internal->m_contextPersistent.Reset(isolate, v8::Context::New(isolate));
// create temporary local handle to context
m_internal->m_context = v8::Local<v8::Context>::New(isolate, m_internal->m_contextPersistent);
// insert embed functions to global object of this context
// insert CreateEmbedObject() function to global object of this context
m_internal->InsertToGlobal("CreateEmbedObject", CreateEmbedNativeObject);
m_internal->InsertToGlobal("FreeEmbedObject", FreeNativeObject);
// clear temporary local handle
m_internal->m_context.Clear();
}
}
class WeakHandleVisitor : public v8::PersistentHandleVisitor
{
private:
WeakHandleVisitor() = default;
public:
void VisitPersistentHandle(v8::Persistent<v8::Value>* value, uint16_t class_id) override
{
if (class_id == CJSEmbedObjectPrivate::kWeakHandleId)
{
v8::Isolate* isolate = v8::Isolate::GetCurrent();
v8::HandleScope scope(isolate);
v8::Local<v8::Object> handle = value->Get(isolate).As<v8::Object>();
v8::Local<v8::External> field = v8::Local<v8::External>::Cast(handle->GetInternalField(0));
CJSEmbedObject* native = static_cast<CJSEmbedObject*>(field->Value());
delete native;
}
}
public:
static WeakHandleVisitor* getInstance()
{
static WeakHandleVisitor visitor;
return &visitor;
}
};
void CJSContext::Dispose()
{
#ifdef V8_INSPECTOR
@ -257,13 +228,7 @@ namespace NSJSBase
#endif
m_internal->m_contextPersistent.Reset();
// destroy native object in the weak handles before isolate disposal
v8::Isolate* isolate = m_internal->m_isolate;
{
v8::Isolate::Scope scope(isolate);
isolate->VisitHandlesWithClassIds(WeakHandleVisitor::getInstance());
}
isolate->Dispose();
m_internal->m_isolate->Dispose();
m_internal->m_isolate = NULL;
}
@ -690,22 +655,4 @@ namespace NSJSBase
NSJSBase::CJSEmbedObjectPrivate::CreateWeaker(obj);
args.GetReturnValue().Set(obj);
}
void FreeNativeObject(const v8::FunctionCallbackInfo<v8::Value>& args)
{
v8::Isolate* isolate = args.GetIsolate();
v8::HandleScope scope(isolate);
if (args.Length() != 1)
{
args.GetReturnValue().Set(v8::Undefined(isolate));
return;
}
v8::Local<v8::Object> obj = args[0].As<v8::Object>();
v8::Local<v8::External> field = v8::Local<v8::External>::Cast(obj->GetInternalField(0));
CJSEmbedObject* native = static_cast<CJSEmbedObject*>(field->Value());
delete native;
// weak persistent handle will be cleared and removed in CJSEmbedObjectPrivate destructor
}
}

View File

@ -883,7 +883,6 @@ namespace NSJSBase
// embed
void CreateEmbedNativeObject(const v8::FunctionCallbackInfo<v8::Value>& args);
void FreeNativeObject(const v8::FunctionCallbackInfo<v8::Value>& args);
class CJSEmbedObjectAdapterV8Template : public CJSEmbedObjectAdapterBase
{
@ -901,8 +900,6 @@ namespace NSJSBase
{
public:
v8::Persistent<v8::Object> handle;
// contstant id for all weak native handles
static const uint16_t kWeakHandleId = 1;
CJSEmbedObjectPrivate(v8::Local<v8::Object> obj)
{
@ -921,8 +918,6 @@ namespace NSJSBase
handle.Reset(CV8Worker::GetCurrent(), obj);
handle.SetWeak(pEmbedObject, EmbedObjectWeakCallback, v8::WeakCallbackType::kParameter);
// set class_id for being able to iterate over all these handles to destroy them on isolate disposal
handle.SetWrapperClassId(kWeakHandleId);
pEmbedObject->embed_native_internal = this;
}
@ -936,6 +931,8 @@ namespace NSJSBase
static void EmbedObjectWeakCallback(const v8::WeakCallbackInfo<CJSEmbedObject>& data)
{
v8::Isolate* isolate = data.GetIsolate();
v8::HandleScope scope(isolate);
CJSEmbedObject* wrap = data.GetParameter();
((CJSEmbedObjectPrivate*)wrap->embed_native_internal)->handle.Reset();
delete wrap;

View File

@ -1,15 +1,4 @@
#include "Embed.h"
#include <iostream>
CTestEmbed::CTestEmbed()
{
std::cout << "debug: CTestEmbed constructed" << std::endl;
}
CTestEmbed::~CTestEmbed()
{
std::cout << "debug: CTestEmbed destroyed" << std::endl;
}
#ifdef ENABLE_SUM_DEL
JSSmart<CJSValue> CTestEmbed::FunctionSum(JSSmart<CJSValue> param1, JSSmart<CJSValue> param2)

View File

@ -1,5 +1,5 @@
#ifndef CTESTEMBED_H_
#define CTESTEMBED_H_
#ifndef _BUILD_NATIVE_HASH_EMBED_H_
#define _BUILD_NATIVE_HASH_EMBED_H_
#include "js_internal/js_base.h"
@ -10,8 +10,13 @@ using namespace NSJSBase;
class CTestEmbed : public CJSEmbedObject
{
public:
CTestEmbed();
~CTestEmbed();
CTestEmbed()
{
}
~CTestEmbed()
{
}
virtual void* getObject() override { return NULL; }
@ -28,4 +33,4 @@ public:
DECLARE_EMBED_METHODS
};
#endif // CTESTEMBED_H_
#endif // _BUILD_NATIVE_HASH_EMBED_H_

View File

@ -1,14 +1,278 @@
#include "test_functions.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
*
*/
int main()
#include <iostream>
#include "embed/Default.h"
#include "js_internal/js_base.h"
#include "Embed.h"
using namespace NSJSBase;
int main(int argc, char *argv[])
{
// TODO: test
#if 0
// Primitives example
// testMultipleContexts();
testEmbedExternal();
// testEmbedInternal();
// testHashEmbed();
// testEmbedMixed();
JSSmart<CJSContext> oContext1 = new CJSContext(false);
oContext1->Initialize();
JSSmart<CJSContext> oContext2 = new CJSContext;
// oContext2->Initialize();
// Work with first context
oContext1->Enter();
{
CJSContextScope scope(oContext1);
CJSLocalScope local_scope;
JSSmart<CJSValue> oResLocal = oContext1->runScript("function f() { return 'Local scope test'; }; f();");
std::cout << oResLocal->toStringA() << std::endl;
}
JSSmart<CJSObject> oGlobal1 = oContext1->GetGlobal();
JSSmart<CJSValue> oVar2 = oContext1->createString("Hel");
oGlobal1->set("v1", oVar2.GetPointer());
oContext1->runScript("var res = v1 + 'lo'");
oContext1->Exit();
// Work with second context with CJSContextScope usage
{
CJSContextScope scope(oContext2);
JSSmart<CJSObject> oGlobal2 = oContext2->GetGlobal();
JSSmart<CJSValue> oVar4 = oContext2->createString("Wor");
oGlobal2->set("v1", oVar4.GetPointer());
oContext2->runScript("var res = v1 + 'ld!'");
}
// Print result from first context
oContext1->Enter();
JSSmart<CJSValue> oRes1 = oContext1->runScript("function f() { return res; }; f();");
std::string strRes1 = oRes1->toStringA();
std::cout << strRes1 << std::endl;
// Print second variable
oContext2->Enter();
JSSmart<CJSValue> oRes2 = oContext1->runScript("function f() { return res; }; f();");
std::string strRes2 = oRes2->toStringA();
std::cout << strRes2 << std::endl;
oContext2->Exit();
oContext1->Exit();
// oContext1->Dispose();
oContext2->Dispose();
#endif
#if 0
// External embed example
JSSmart<CJSContext> oContext1 = new CJSContext();
// Embedding
CJSContextScope scope(oContext1);
CJSContext::Embed<CTestEmbed>();
JSSmart<CJSValue> oResTestEmbed1 = oContext1->runScript("(function() { var value = CreateEmbedObject('CTestEmbed'); return value.FunctionSum(10, 5); })();");
std::cout << "FunctionSum(10, 5) = " << oResTestEmbed1->toInt32() << std::endl;
JSSmart<CJSValue> oResTestEmbed2 = oContext1->runScript("(function() { var value = CreateEmbedObject('CTestEmbed'); return value.FunctionSquare(4); })();");
std::cout << "FunctionSquare(4) = " << oResTestEmbed2->toInt32() << std::endl;
JSSmart<CJSValue> oResTestEmbed3 = oContext1->runScript("(function() { var value = CreateEmbedObject('CTestEmbed'); return value.FunctionDel(30, 3); })();");
std::cout << "FunctionDel(30, 3) = " << oResTestEmbed3->toInt32() << std::endl;
JSSmart<CJSValue> oResTestEmbed4 = oContext1->runScript("(function() { var value = CreateEmbedObject('CTestEmbed'); return value.FunctionGet(); })();");
std::cout << "FunctionGet() = " << oResTestEmbed4->toInt32() << std::endl;
#endif
#if 0
// CZipEmbed example
JSSmart<CJSContext> oContext1 = new CJSContext();
JSSmart<CJSContext> oContext2 = new CJSContext();
// Work with first context
oContext1->Enter();
CreateDefaults();
JSSmart<CJSValue> oRes1 = oContext1->runScript(
"var oZip = CreateEmbedObject('CZipEmbed');\n"
"var files = oZip.open('" CURR_DIR "');\n"
"oZip.close();");
oContext1->Exit();
// Work with second context
{
CJSContextScope scope(oContext2);
// CreateDefaults();
JSSmart<CJSValue> oRes2 = oContext2->runScript(
"var oZip = CreateEmbedObject('CZipEmbed');\n"
"var files = oZip.open('" CURR_DIR "/../embed');\n"
"oZip.close();");
}
// Print first result
oContext1->Enter();
JSSmart<CJSObject> oGlobal1 = oContext1->GetGlobal();
JSSmart<CJSArray> oFiles1 = oGlobal1->get("files")->toArray();
std::cout << "\nRESULT FROM CONTEXT 1:\n";
for (int i = 0; i < oFiles1->getCount(); i++)
{
std::cout << oFiles1->get(i)->toStringA() << std::endl;
}
// Print second result
oContext2->Enter();
JSSmart<CJSObject> oGlobal2 = oContext2->GetGlobal();
JSSmart<CJSArray> oFiles2 = oGlobal2->get("files")->toArray();
std::cout << "\nRESULT FROM CONTEXT 2:\n";
for (int i = 0; i < oFiles2->getCount(); i++)
{
std::cout << oFiles2->get(i)->toStringA() << std::endl;
}
oContext2->Exit();
oContext1->Exit();
#endif
#if 0
// CHashEmbed example
JSSmart<CJSContext> oContext1 = new CJSContext();
// Call hash() on first context
CJSContextScope scope(oContext1);
CreateDefaults();
JSSmart<CJSValue> oRes1 = oContext1->runScript(
"var oHash = CreateEmbedObject('CHashEmbed');\n"
"var str = 'test';\n"
"var hash = oHash.hash(str, str.length, 0);");
// Print first result
JSSmart<CJSObject> oGlobal1 = oContext1->GetGlobal();
JSSmart<CJSTypedArray> oHash = oGlobal1->get("hash")->toTypedArray();
std::cout << "\nRESULTED HASH:\n";
for (int i = 0; i < oHash->getCount(); i++)
{
std::cout << std::hex << static_cast<unsigned>(oHash->getData().Data[i]);
}
std::cout << std::endl;
// Call hash2() on first context
JSSmart<CJSValue> oRes2 = oContext1->runScript(
"var str2 = 'test';\n"
"var hash2 = oHash.hash2(str2, 'yrGivlyCImiWnryRee1OJw==', 100000, 7);");
// Print first result
JSSmart<CJSTypedArray> oHash2 = oGlobal1->get("hash2")->toTypedArray();
std::cout << "\nRESULTED HASH2:\n";
for (int i = 0; i < oHash2->getCount(); i++)
{
std::cout << std::hex << static_cast<unsigned>(oHash2->getData().Data[i]);
}
std::cout << std::endl;
#endif
#if 1
// Mixed embed example
JSSmart<CJSContext> oContext1 = new CJSContext();
// External CTestEmbed
CJSContextScope scope(oContext1);
CJSContext::Embed<CTestEmbed>(false);
JSSmart<CJSValue> oResTestEmbed1 = oContext1->runScript("(function() { var value = CreateEmbedObject('CTestEmbed'); return value.FunctionSum(10, 5); })();");
if (oResTestEmbed1->isNumber())
std::cout << "FunctionSum(10, 5) = " << oResTestEmbed1->toInt32() << std::endl;
JSSmart<CJSObject> oTestEmbed = CJSContext::createEmbedObject("CTestEmbed");
// JSSmart<CJSValue> oResTestEmbed2 = oContext1->runScript("(function() { var value = CreateEmbedObject('CTestEmbed'); return value.FunctionSquare(4); })();");
JSSmart<CJSValue> args2[1];
args2[0] = CJSContext::createInt(4);
JSSmart<CJSValue> oResTestEmbed2 = oTestEmbed->call_func("FunctionSquare", 1, args2);
if (oResTestEmbed2->isNumber())
std::cout << "FunctionSquare(4) = " << oResTestEmbed2->toInt32() << std::endl;
// JSSmart<CJSValue> oResTestEmbed3 = oContext1->runScript("(function() { var value = CreateEmbedObject('CTestEmbed'); return value.FunctionDel(30, 3); })();");
JSSmart<CJSValue> args3[2];
args3[0] = CJSContext::createInt(30);
args3[1] = CJSContext::createInt(3);
JSSmart<CJSValue> oResTestEmbed3 = oTestEmbed->call_func("FunctionDel", 2, args3);
if (oResTestEmbed3->isNumber())
std::cout << "FunctionDel(30, 3) = " << oResTestEmbed3->toInt32() << std::endl;
JSSmart<CJSValue> oResTestEmbed4 = oContext1->runScript("(function() { var value = CreateEmbedObject('CTestEmbed'); return value.FunctionGet(); })();");
if (oResTestEmbed4->isNumber())
std::cout << "FunctionGet() = " << oResTestEmbed4->toInt32() << std::endl;
// Internal CHashEmbed
CreateDefaults();
oContext1->runScript(
"var oHash = CreateEmbedObject('CHashEmbed');\n"
"var str = 'test';\n"
"var hash = oHash.hash(str, str.length, 0);");
// Print hash
JSSmart<CJSObject> oGlobal = oContext1->GetGlobal();
JSSmart<CJSTypedArray> oHash = oGlobal->get("hash")->toTypedArray();
std::cout << "\nRESULTED HASH:\n";
for (int i = 0; i < oHash->getCount(); i++)
{
std::cout << std::hex << static_cast<unsigned>(oHash->getData().Data[i]);
}
std::cout << std::endl;
// Internal CZipEmbed
oContext1->runScript(
"var oZip = CreateEmbedObject('CZipEmbed');\n"
"var files = oZip.open('" CURR_DIR "');\n"
"oZip.close();");
// Print files
JSSmart<CJSArray> oFiles1 = oGlobal->get("files")->toArray();
std::cout << "\nFILES IN CURRENT DIRECTORY:\n";
for (int i = 0; i < oFiles1->getCount(); i++)
{
std::cout << oFiles1->get(i)->toStringA() << std::endl;
}
#endif
return 0;
}

View File

@ -1,14 +0,0 @@
#include "test_functions.h"
int main()
{
// all test functions should be called inside the `@autoreleasepool` block!
@autoreleasepool
{
testEmbedExternal();
// testHashEmbed();
// testEmbedMixed();
}
return 0;
}

View File

@ -29,18 +29,10 @@ core_linux {
LIBS += -ldl
}
SOURCES += main.cpp \
Embed.cpp
HEADERS += \
Embed.h \
test_functions.h
SOURCES += \
Embed.cpp \
test_functions.cpp
use_javascript_core {
OBJECTIVE_SOURCES += main.mm
} else {
SOURCES += main.cpp
}
Embed.h
ADD_FILES_FOR_EMBEDDED_CLASS_HEADER(Embed.h)

View File

@ -1,286 +0,0 @@
#include "test_functions.h"
#include <iostream>
#include "embed/Default.h"
#include "js_internal/js_base.h"
#include "Embed.h"
using namespace NSJSBase;
void testMultipleContexts()
{
// passing `false` when creating CJSContext means that we need to initialize it manually
JSSmart<CJSContext> context1 = new CJSContext(false);
context1->Initialize();
// while creating CJSContext without any arguments will create initialized CJSContext
JSSmart<CJSContext> context2 = new CJSContext;
// we don't need it:
// oContext2->Initialize();
// entering the first context
context1->Enter();
{
// entering the first context the second time in scope creation - it's allowed and the scopes stack correctly
CJSContextScope scope(context1);
// allocate new local variables inside a custom local scope instead of
// the one that is provided by CJSContextScope by default
CJSLocalScope local_scope;
JSSmart<CJSValue> res_local = context1->runScript("(function() { return 'Local scope test'; })();");
std::cout << res_local->toStringA() << std::endl;
// the first context is going to be exited at the end of the scope
}
// at this moment we are still inside the first context, since we have entered it twices
JSSmart<CJSObject> global1 = context1->GetGlobal();
JSSmart<CJSValue> var = context1->createString("Hel");
global1->set("v1", var);
// here `res` is set to be "Hello"
context1->runScript("var res = v1 + 'lo'");
// exit from the first context
context1->Exit();
// now we are going to work with the second context
{
// enter the second context via context scope
CJSContextScope scope(context2);
JSSmart<CJSObject> global2 = context2->GetGlobal();
JSSmart<CJSValue> var = context2->createString("Wor");
global2->set("v1", var);
// `res` is "World!"
context2->runScript("var res = v1 + 'ld!'");
// the second context is going to be exited at the end of the scope
}
// enter the first context
context1->Enter();
// print `res` variable from the first context
JSSmart<CJSValue> res1 = context1->runScript("(function() { return res; })();");
std::string str_res1 = res1->toStringA();
std::cout << str_res1 << ", ";
// make new variable `v2` in first context
// important to note, that accessing previous `global1` object is undefined behaviour and can lead to crashes!
// that is because when we exited from the first context, every local handle inside CJSValue and CJSObject was invalidated
global1 = context1->GetGlobal();
global1->set("v2", CJSContext::createInt(42));
// enter from the second context (notice, we haven't exited the first context before)
context2->Enter();
// print `res` variable from the second context
JSSmart<CJSValue> res2 = context1->runScript("(function() { return res; })();");
std::string str_res2 = res2->toStringA();
std::cout << str_res2 << std::endl;
// exit from the second context
context2->Exit();
// at this moment we are still in the first context
// we can validate that accessing `v2` variable, which exists only in the first context
global1 = context1->GetGlobal();
std::cout << global1->get("v2")->toInt32() << std::endl;
// exit from the first context
context1->Exit();
// manual disposing is not necessary, since it's going to be called in CJSContext's destructor anyway
// so we don't need to explicitly write:
// oContext1->Dispose();
// but still nothing wrong will happen if we do:
context2->Dispose();
}
void testEmbedExternal()
{
JSSmart<CJSContext> context = new CJSContext();
// Embedding
CJSContextScope scope(context);
CJSContext::Embed<CTestEmbed>();
JSSmart<CJSValue> res1 = context->runScript("(function() { let value = CreateEmbedObject('CTestEmbed'); let ret = value.FunctionSum(10, 5); FreeEmbedObject(value); return ret; })();");
std::cout << "FunctionSum(10, 5) = " << res1->toInt32() << std::endl;
JSSmart<CJSValue> res2 = context->runScript("(function() { let value = CreateEmbedObject('CTestEmbed'); let ret = value.FunctionSquare(4); FreeEmbedObject(value); return ret; })();");
std::cout << "FunctionSquare(4) = " << res2->toInt32() << std::endl;
JSSmart<CJSValue> res3 = context->runScript("(function() { let value = CreateEmbedObject('CTestEmbed'); let ret = value.FunctionDel(30, 3); FreeEmbedObject(value); return ret; })();");
std::cout << "FunctionDel(30, 3) = " << res3->toInt32() << std::endl;
JSSmart<CJSValue> res4 = context->runScript("(function() { let value = CreateEmbedObject('CTestEmbed'); let ret = value.FunctionGet(); FreeEmbedObject(value); return ret; })();");
std::cout << "FunctionGet() = " << res4->toInt32() << std::endl;
}
void testEmbedInternal()
{
// create both contexts
JSSmart<CJSContext> context1 = new CJSContext();
JSSmart<CJSContext> context2 = new CJSContext();
// work with the first context
context1->Enter();
// create embedding info for internally embedded objects (CZipEmbed is the one of them)
CreateDefaults();
context1->runScript(
"var oZip = CreateEmbedObject('CZipEmbed');\n"
"var files = oZip.open('" CURR_DIR "');\n"
"oZip.close();"
);
context1->Exit();
// work with the second context via context scope
{
CJSContextScope scope(context2);
// function CJSContext::Embed() is context-independent, so we don't actually need to call it in another context
// CreateDefaults();
context2->runScript(
"var oZip = CreateEmbedObject('CZipEmbed');\n"
"var files = oZip.open('" CURR_DIR "/../../../embed');\n"
"oZip.close();"
);
}
// print the files from the first context
context1->Enter();
JSSmart<CJSObject> global1 = context1->GetGlobal();
JSSmart<CJSArray> file_list1 = global1->get("files")->toArray();
std::cout << "\nRESULT FROM CONTEXT 1:\n";
for (int i = 0; i < file_list1->getCount(); i++)
{
std::cout << file_list1->get(i)->toStringA() << std::endl;
}
// print the files from the second result (note, we haven't exited the first context before)
context2->Enter();
JSSmart<CJSObject> global2 = context2->GetGlobal();
JSSmart<CJSArray> file_list2 = global2->get("files")->toArray();
std::cout << "\nRESULT FROM CONTEXT 2:\n";
for (int i = 0; i < file_list2->getCount(); i++)
{
std::cout << file_list2->get(i)->toStringA() << std::endl;
}
// exit the contexts in reverse order
context2->Exit();
context1->Exit();
}
void testHashEmbed()
{
JSSmart<CJSContext> context = new CJSContext();
// test hash()
CJSContextScope scope(context);
CreateDefaults();
context->runScript(
"var oHash = CreateEmbedObject('CHashEmbed');\n"
"var str = 'test';\n"
"var hash = oHash.hash(str, str.length, 0);"
);
JSSmart<CJSObject> global = context->GetGlobal();
JSSmart<CJSTypedArray> res_hash = global->get("hash")->toTypedArray();
std::cout << "\nRESULTED HASH:\n";
for (int i = 0; i < res_hash->getCount(); i++)
{
std::cout << std::hex << static_cast<unsigned>(res_hash->getData().Data[i]);
}
std::cout << std::endl;
// test hash2()
context->runScript(
"var str2 = 'test';\n"
"var hash2 = oHash.hash2(str2, 'yrGivlyCImiWnryRee1OJw==', 100000, 7);"
);
JSSmart<CJSTypedArray> res_hash2 = global->get("hash2")->toTypedArray();
std::cout << "\nRESULTED HASH2:\n";
for (int i = 0; i < res_hash2->getCount(); i++)
{
std::cout << std::hex << static_cast<unsigned>(res_hash2->getData().Data[i]);
}
std::cout << std::endl;
}
void testEmbedMixed()
{
JSSmart<CJSContext> context = new CJSContext();
CJSContextScope scope(context);
// --- test external embedding with CTestEmbed ---
// embed with `false` - means we are not able to create the object directly from JavaScript.
CJSContext::Embed<CTestEmbed>(false);
// example of incorrect usage:
JSSmart<CJSValue> res1 = context->runScript("(function() { var value = CreateEmbedObject('CTestEmbed'); return value.FunctionSum(10, 5); })();");
if (res1->isNumber())
{
// this wouldn't print anything, since `res1` not a number - embedded object was not created in JS and exception was thrown.
std::cout << "FunctionSum(10, 5) = " << res1->toInt32() << std::endl;
}
// example of correct usage:
JSSmart<CJSObject> embedded_object = CJSContext::createEmbedObject("CTestEmbed");
JSSmart<CJSValue> args2[1];
args2[0] = CJSContext::createInt(4);
JSSmart<CJSValue> res2 = embedded_object->call_func("FunctionSquare", 1, args2);
if (res2->isNumber())
{
// should print: "FunctionSquare(4) = 16"
std::cout << "FunctionSquare(4) = " << res2->toInt32() << std::endl;
}
// another example of correct usage:
JSSmart<CJSValue> args3[2];
args3[0] = CJSContext::createInt(30);
args3[1] = CJSContext::createInt(3);
JSSmart<CJSValue> oResTestEmbed3 = embedded_object->call_func("FunctionDel", 2, args3);
if (oResTestEmbed3->isNumber())
{
// should print: "FunctionDel(30, 3) = 10"
std::cout << "FunctionDel(30, 3) = " << oResTestEmbed3->toInt32() << std::endl;
}
// another example of incorrect usage:
JSSmart<CJSValue> oResTestEmbed4 = context->runScript("(function() { var value = CreateEmbedObject('CTestEmbed'); return value.FunctionGet(); })();");
if (oResTestEmbed4->isNumber())
{
// again, this won't be executed and nothing will be printed
std::cout << "FunctionGet() = " << oResTestEmbed4->toInt32() << std::endl;
}
// --- test internal embedding with CHashEmbed ---
CreateDefaults();
context->runScript(
"var oHash = CreateEmbedObject('CHashEmbed');\n"
"var str = 'test';\n"
"var hash = oHash.hash(str, str.length, 0);"
);
// print hash
JSSmart<CJSObject> global = context->GetGlobal();
JSSmart<CJSTypedArray> hash = global->get("hash")->toTypedArray();
std::cout << "\nRESULTED HASH:\n";
for (int i = 0; i < hash->getCount(); i++)
{
std::cout << std::hex << static_cast<unsigned>(hash->getData().Data[i]);
}
std::cout << std::endl;
// --- test internal embedding with CZipEmbed ---
context->runScript(
"var oZip = CreateEmbedObject('CZipEmbed');\n"
"var files = oZip.open('" CURR_DIR "');\n"
"oZip.close();"
);
// print files
JSSmart<CJSArray> file_list = global->get("files")->toArray();
std::cout << "\nFILES IN CURRENT DIRECTORY:\n";
for (int i = 0; i < file_list->getCount(); i++)
{
std::cout << file_list->get(i)->toStringA() << std::endl;
}
}

View File

@ -1,34 +0,0 @@
#ifndef TEST_FUNCTIONS_H_
#define TEST_FUNCTIONS_H_
/**
* NOTE: V8 ONLY!
* The function tests the work of two CJSContexts in one thread.
* Current working context is managed with Enter() and Exit() functions, or with CJSContextScope.
*/
void testMultipleContexts();
/**
* The function tests external embedding functionality by embedding CTestEmbed class.
*/
void testEmbedExternal();
/**
* NOTE: V8 ONLY!
* The function tests internal embedding functionality by using CZipEmbed class.
* It also shows how embedding works for two CJSContext in the same thread (similar to testMultipleContexts()).
*/
void testEmbedInternal();
/**
* The function tests CHashEmbed class that is embedded internally.
*/
void testHashEmbed();
/**
* The function tests both internal and external embedding in a more complicated way.
*/
void testEmbedMixed();
#endif // TEST_FUNCTIONS_H_

View File

@ -1958,10 +1958,6 @@ namespace NSFonts
if (FT_Open_Face(m_internal->m_library, &oOpenArgs, nFaceIndex, &pFace))
return;
bool bIsASC = false;
if (pFace->family_name && (0 == strcmp(pFace->family_name, "ASCW3")))
bIsASC = true;
for (int nCharMap = 0; nCharMap < pFace->num_charmaps; nCharMap++)
{
FT_Set_Charmap(pFace, pFace->charmaps[nCharMap]);
@ -1971,8 +1967,7 @@ namespace NSFonts
while (indexG)
{
if (!bIsASC || (character < 35 || character > 255))
pChecker->Check((int)character, indexG);
pChecker->Check((int)character, indexG);
character = FT_Get_Next_Char(pFace, character, &indexG);
}
}

View File

@ -36,7 +36,7 @@
#include <vector>
#include "../graphics/pro/Fonts.h"
#define ONLYOFFICE_FONTS_VERSION 13
#define ONLYOFFICE_FONTS_VERSION 12
#define ONLYOFFICE_ALL_FONTS_VERSION 2
class CApplicationFontsWorkerBreaker

View File

@ -917,15 +917,15 @@ function onLoadFontsModule(window, undefined)
this._mapToNames = AscCommon.spellcheckGetLanguages();
let _langKey = "" + lang;
let _langObj = this._mapToNames[_langKey];
if (!_langObj || !_langObj["hyphen"] || !_langObj["name"])
let _langName = this._mapToNames[_langKey];
if (_langName === undefined)
{
this._dictionaries[_langKey] = false;
callback();
return;
}
this._loadDictionaryAttemt(_langKey, _langObj["name"], callback);
this._loadDictionaryAttemt(_langKey, _langName, callback);
};
this._loadDictionaryAttemt = function(langKey, langName, callback, currentAttempt)

View File

@ -195,7 +195,7 @@
},
{
"folder": "../../../../PdfFile/SrcWriter/",
"files": ["AcroForm.cpp", "Annotation.cpp", "Catalog.cpp", "Destination.cpp", "Document.cpp", "Encrypt.cpp", "EncryptDictionary.cpp", "Field.cpp", "Font.cpp", "Font14.cpp", "FontCidTT.cpp", "FontOTWriter.cpp", "FontTT.cpp", "FontTTWriter.cpp", "GState.cpp", "Image.cpp", "Info.cpp", "Metadata.cpp", "Objects.cpp", "Outline.cpp", "Pages.cpp", "Pattern.cpp", "ResourcesDictionary.cpp", "Shading.cpp", "States.cpp", "Streams.cpp", "Utils.cpp"]
"files": ["AcroForm.cpp", "Annotation.cpp", "Catalog.cpp", "Destination.cpp", "Document.cpp", "Encrypt.cpp", "EncryptDictionary.cpp", "Field.cpp", "Font.cpp", "Font14.cpp", "FontCidTT.cpp", "FontTT.cpp", "FontTTWriter.cpp", "GState.cpp", "Image.cpp", "Info.cpp", "Metadata.cpp", "Objects.cpp", "Outline.cpp", "Pages.cpp", "Pattern.cpp", "ResourcesDictionary.cpp", "Shading.cpp", "States.cpp", "Streams.cpp", "Utils.cpp"]
},
{
"folder": "../../../../PdfFile/Resources/",

View File

@ -717,7 +717,6 @@ SOURCES += \
$$PDF_ROOT_DIR/SrcWriter/FontCidTT.cpp \
$$PDF_ROOT_DIR/SrcWriter/FontTT.cpp \
$$PDF_ROOT_DIR/SrcWriter/FontTTWriter.cpp \
$$PDF_ROOT_DIR/SrcWriter/FontOTWriter.cpp \
$$PDF_ROOT_DIR/SrcWriter/GState.cpp \
$$PDF_ROOT_DIR/SrcWriter/Image.cpp \
$$PDF_ROOT_DIR/SrcWriter/Info.cpp \

View File

@ -40,7 +40,7 @@ var UpdateFontsSource = {
function CFile()
{
this.nativeFile = 0;
this.stream = -1;
this.stream = [];
this.stream_size = 0;
this.type = -1;
this.pages = [];
@ -128,17 +128,17 @@ CFile.prototype["close"] = function()
this.pages = [];
this.info = null;
this.StartID = null;
if (this.stream > 0)
this._free(this.stream);
this.stream = -1;
for (let i = 0; i < this.stream.length; i++)
this._free(this.stream[i]);
this.stream = [];
self.drawingFile = null;
};
CFile.prototype["getFileBinary"] = function()
{
if (0 >= this.stream)
if (this.stream.length == 0)
return "";
return new Uint8Array(Module["HEAP8"].buffer, this.stream, this.stream_size);
return new Uint8Array(Module["HEAP8"].buffer, this.stream[0], this.stream_size);
};
CFile.prototype["isNeedPassword"] = function()
@ -1566,13 +1566,8 @@ CFile.prototype["readAnnotationsInfoFromBinary"] = function(AnnotInfo)
CFile.prototype["scanPage"] = function(page, mode)
{
let ptr = this._scanPage(page, mode);
if (mode == 2) {
data = ptr.getMemory(true);
ptr.free();
return data;
}
let reader = ptr.getReader();
if (!reader) return [];
let shapesCount = reader.readInt();

View File

@ -101,8 +101,9 @@ CFile.prototype._openFile = function(buffer, password)
{
let data = new Uint8Array(buffer);
this.stream_size = data.length;
this.stream = Module["_malloc"](this.stream_size);
Module["HEAP8"].set(data, this.stream);
let stream = Module["_malloc"](this.stream_size);
Module["HEAP8"].set(data, stream);
this.stream.push(stream);
}
let passwordPtr = 0;
@ -113,7 +114,7 @@ CFile.prototype._openFile = function(buffer, password)
Module["HEAP8"].set(passwordBuf, passwordPtr);
}
this.nativeFile = Module["_Open"](this.stream, this.stream_size, passwordPtr);
this.nativeFile = Module["_Open"](this.stream[0], this.stream_size, passwordPtr);
if (passwordPtr)
Module["_free"](passwordPtr);
@ -127,7 +128,7 @@ CFile.prototype._closeFile = function()
CFile.prototype._getType = function()
{
return Module["_GetType"](this.nativeFile);
return Module["_GetType"](this.stream[0], this.stream_size);
};
CFile.prototype._getError = function()
@ -179,7 +180,10 @@ CFile.prototype._MergePages = function(buffer, maxID, prefixForm)
}
let bRes = Module["_MergePages"](this.nativeFile, stream2, data.length, maxID, prefixPtr);
stream2 = 0; // Success or not, stream2 is either taken or freed
if (bRes == 1)
this.stream.push(stream2);
else
Module["_free"](stream2);
if (prefixPtr)
Module["_free"](prefixPtr);
@ -189,7 +193,13 @@ CFile.prototype._MergePages = function(buffer, maxID, prefixForm)
CFile.prototype._UndoMergePages = function()
{
return Module["_UnmergePages"](this.nativeFile) == 1;
let bRes = Module["_UnmergePages"](this.nativeFile);
if (bRes == 1)
{
let str = this.stream.pop();
Module["_free"](str);
}
return bRes == 1;
};
// FONTS

View File

@ -68,6 +68,25 @@ WASM_EXPORT int IsFontBinaryExist(char* path)
return 0;
}
WASM_EXPORT int GetType(BYTE* data, LONG size)
{
// 0 - PDF
// 1 - DJVU
// 2 - XPS
LONG nHeaderSearchSize = 1024;
LONG nSize = size < nHeaderSearchSize ? size : nHeaderSearchSize;
char* pData = (char*)data;
for (int i = 0; i < nSize - 5; ++i)
{
int nPDF = strncmp(&pData[i], "%PDF-", 5);
if (!nPDF)
return 0;
}
if ( (8 <= size) && (0x41 == data[0] && 0x54 == data[1] && 0x26 == data[2] && 0x54 == data[3] &&
0x46 == data[4] && 0x4f == data[5] && 0x52 == data[6] && 0x4d == data[7]))
return 1;
return 2;
}
WASM_EXPORT CDrawingFile* Open(BYTE* data, LONG size, const char* password)
{
if (!g_applicationFonts)
@ -83,13 +102,6 @@ WASM_EXPORT CDrawingFile* Open(BYTE* data, LONG size, const char* password)
pFile->OpenFile(data, size, sPassword);
return pFile;
}
WASM_EXPORT int GetType(CDrawingFile* pFile)
{
// 0 - PDF
// 1 - DJVU
// 2 - XPS
return pFile->GetType();
}
WASM_EXPORT int GetErrorCode(CDrawingFile* pFile)
{
if (!pFile)
@ -99,7 +111,6 @@ WASM_EXPORT int GetErrorCode(CDrawingFile* pFile)
WASM_EXPORT void Close(CDrawingFile* pFile)
{
delete pFile;
g_applicationFonts->GetStreams()->Clear();
NSFonts::NSApplicationFontStream::SetGlobalMemoryStorage(NULL);
}
WASM_EXPORT BYTE* GetInfo(CDrawingFile* pFile)

View File

@ -1022,9 +1022,9 @@ int main(int argc, char* argv[])
}
}
RELEASEARRAYOBJECTS(pFileData);
// SPLIT & MERGE
BYTE* pSplitPages = NULL;
BYTE* pFileMerge = NULL;
if (false)
{
int nBufferLen = NULL;
@ -1036,19 +1036,12 @@ int main(int argc, char* argv[])
BYTE* pSplitPages = SplitPages(pGrFile, arrPages.data(), arrPages.size(), pBuffer, nBufferLen);
int nLength = READ_INT(pSplitPages);
if (nLength > 4)
{
NSFile::CFileBinary oFile;
if (oFile.CreateFileW(NSFile::GetProcessDirectory() + L"/split1.pdf"))
oFile.WriteFile(pSplitPages + 4, nLength - 4);
oFile.CloseFile();
NSFile::CFileBinary oFile;
if (oFile.CreateFileW(NSFile::GetProcessDirectory() + L"/split1.pdf"))
oFile.WriteFile(pSplitPages + 4, nLength - 4);
oFile.CloseFile();
BYTE* pMallocData = (BYTE*)malloc(nLength - 4);
memcpy(pMallocData, pSplitPages + 4, nLength - 4);
MergePages(pGrFile, pMallocData, nLength - 4, 0, "merge1");
}
RELEASEARRAYOBJECTS(pSplitPages);
MergePages(pGrFile, pSplitPages + 4, nLength - 4, 0, "merge1");
}
RELEASEARRAYOBJECTS(pBuffer);
@ -1058,19 +1051,12 @@ int main(int argc, char* argv[])
BYTE* pSplitPages = SplitPages(pGrFile, arrPages.data(), arrPages.size(), pBuffer, nBufferLen);
int nLength = READ_INT(pSplitPages);
if (nLength > 4)
{
NSFile::CFileBinary oFile;
if (oFile.CreateFileW(NSFile::GetProcessDirectory() + L"/split2.pdf"))
oFile.WriteFile(pSplitPages + 4, nLength - 4);
oFile.CloseFile();
NSFile::CFileBinary oFile;
if (oFile.CreateFileW(NSFile::GetProcessDirectory() + L"/split2.pdf"))
oFile.WriteFile(pSplitPages + 4, nLength - 4);
oFile.CloseFile();
BYTE* pMallocData = (BYTE*)malloc(nLength - 4);
memcpy(pMallocData, pSplitPages + 4, nLength - 4);
MergePages(pGrFile, pMallocData, nLength - 4, 0, "merge2");
}
RELEASEARRAYOBJECTS(pSplitPages);
MergePages(pGrFile, pSplitPages + 4, nLength - 4, 0, "merge2");
}
RELEASEARRAYOBJECTS(pBuffer);
}
@ -2067,6 +2053,10 @@ int main(int argc, char* argv[])
}
Close(pGrFile);
RELEASEARRAYOBJECTS(pFileData);
RELEASEARRAYOBJECTS(pSplitPages);
RELEASEARRAYOBJECTS(pFileMerge);
RELEASEARRAYOBJECTS(pCMapData);
return 0;
}

View File

@ -2,11 +2,8 @@
#define _WASM_SERIALIZE_H
#include <vector>
#include <stack>
#include "../../../../../common/File.h"
#define CLEAR_STACK(stack) while (!(stack).empty()) (stack).pop()
namespace NSWasm
{
class CData
@ -18,8 +15,6 @@ namespace NSWasm
BYTE* m_pDataCur;
size_t m_lSizeCur;
std::stack<size_t> m_lStack;
public:
CData()
{
@ -29,70 +24,10 @@ namespace NSWasm
m_pDataCur = m_pData;
m_lSizeCur = m_lSize;
}
CData(const CData& other)
{
m_lSize = other.m_lSize;
m_lSizeCur = other.m_lSizeCur;
m_pData = (BYTE*)malloc(m_lSize * sizeof(BYTE));
memcpy(m_pData, other.m_pData, other.m_lSizeCur * sizeof(BYTE));
m_pDataCur = m_pData + m_lSizeCur;
m_lStack = other.m_lStack;
}
CData(CData&& other)
{
m_lSize = other.m_lSize;
m_lSizeCur = other.m_lSizeCur;
m_pData = other.m_pData;
m_pDataCur = other.m_pDataCur;
m_lStack = std::move(other.m_lStack);
other.ClearWithoutAttack();
}
virtual ~CData()
{
Clear();
}
CData& operator= (const CData& other)
{
if (this == &other)
return *this;
Clear();
m_lSize = other.m_lSize;
m_lSizeCur = other.m_lSizeCur;
m_pData = (BYTE*)malloc(m_lSize * sizeof(BYTE));
memcpy(m_pData, other.m_pData, other.m_lSizeCur * sizeof(BYTE));
m_pDataCur = m_pData + m_lSizeCur;
m_lStack = other.m_lStack;
return *this;
}
CData& operator= (CData&& other)
{
if (this == &other)
return *this;
Clear();
m_lSize = other.m_lSize;
m_lSizeCur = other.m_lSizeCur;
m_pData = other.m_pData;
m_pDataCur = other.m_pDataCur;
other.ClearWithoutAttack();
m_lStack = std::move(other.m_lStack);
return *this;
}
inline void AddSize(size_t nSize)
{
@ -133,20 +68,6 @@ namespace NSWasm
}
public:
void StartRecord(BYTE type)
{
AddSize(5); // sizeof (BYTE + unsigned int)
WriteBYTE(type);
AddInt(0);
m_lStack.push(m_lSizeCur);
}
void EndRecord()
{
size_t start = m_lStack.top();
unsigned int len = m_lSizeCur - start;
memcpy(m_pData + start - 4, &len, sizeof(unsigned int));
m_lStack.pop();
}
void AddInt(unsigned int value)
{
AddSize(4);
@ -154,13 +75,6 @@ namespace NSWasm
m_pDataCur += 4;
m_lSizeCur += 4;
}
void AddSInt(int value)
{
AddSize(4);
memcpy(m_pDataCur, &value, sizeof(int));
m_pDataCur += 4;
m_lSizeCur += 4;
}
void AddInt(unsigned int value, size_t pos)
{
if (pos < m_lSizeCur)
@ -179,10 +93,6 @@ namespace NSWasm
m_pDataCur += sizeof(BYTE);
m_lSizeCur += sizeof(BYTE);
}
void WriteBool(bool value)
{
WriteBYTE(value ? 1 : 0);
}
void WriteDouble(double value)
{
int nV = value * 10000;
@ -241,37 +151,6 @@ namespace NSWasm
WriteString(pDataUtf8, (unsigned int)lDataUtf8);
RELEASEARRAYOBJECTS(pDataUtf8);
}
void WriteStringUtf16(const std::wstring& sStr, const bool& isBytes = false)
{
unsigned int size = static_cast<unsigned int>(sStr.length());
int len = 0;
size_t posLen = m_lSizeCur;
// len reserve
AddInt(0);
if (sizeof(wchar_t) == 4)
{
AddSize(4 * size + 2/*'\0'*/);
NSFile::CUtf8Converter::GetUtf16StringFromUnicode_4bytes(sStr.c_str(), (LONG)size, m_pDataCur, len, false);
}
else
{
size_t bufferLen = 2 * size;
AddSize(bufferLen);
len = (int)(bufferLen);
memcpy(m_pDataCur, sStr.c_str(), bufferLen);
}
m_pDataCur += static_cast<unsigned int>(len);
m_lSizeCur += static_cast<unsigned int>(len);
if (!isBytes)
len /= 2;
AddInt((unsigned int)len, posLen);
}
void Write(BYTE* value, unsigned int len)
{
if (!value || len == 0)
@ -286,13 +165,6 @@ namespace NSWasm
return m_pData;
}
BYTE* MoveBuffer()
{
BYTE* pData = m_pData;
ClearWithoutAttack();
return pData;
}
void Clear()
{
if (m_pData)
@ -303,8 +175,6 @@ namespace NSWasm
m_pDataCur = m_pData;
m_lSizeCur = 0;
CLEAR_STACK(m_lStack);
}
void ClearWithoutAttack()
{
@ -313,15 +183,11 @@ namespace NSWasm
m_pDataCur = m_pData;
m_lSizeCur = 0;
CLEAR_STACK(m_lStack);
}
void ClearNoAttack()
{
m_pDataCur = m_pData;
m_lSizeCur = 0;
CLEAR_STACK(m_lStack);
}
unsigned int GetSize()
{

View File

@ -1,4 +1,6 @@
LIB_GRAPHICS_PRI_PATH=$$PWD/../..
LIB_3DPARTY_PRI_PATH=$$LIB_GRAPHICS_PRI_PATH/../Common/3dParty/heif/lib/Debug
!core_debug:LIB_3DPARTY_PRI_PATH=$$LIB_GRAPHICS_PRI_PATH/../Common/3dParty/heif/lib/Release
DEFINES -= UNICODE
DEFINES -= _UNICODE
@ -12,15 +14,24 @@ DEFINES += \
MNG_SUPPORT_WRITE \
MNG_ACCESS_CHUNKS \
MNG_STORE_CHUNKS\
MNG_ERROR_TELLTALE
MNG_ERROR_TELLTALE\
LIBHEIF_STATIC_BUILD
core_linux {
DEFINES += HAVE_UNISTD_H HAVE_FCNTL_H
QMAKE_CXXFLAGS += -Wno-narrowing
LIBS += -L$$LIB_3DPARTY_PRI_PATH \
-lheif \
-lde265 \
-lx265
}
core_linux_clang {
QMAKE_CFLAGS += -Wno-incompatible-function-pointer-types
QMAKE_CFLAGS += -Wno-incompatible-function-pointer-types
LIBS += -L$$LIB_3DPARTY_PRI_PATH \
-lheif \
-lde265 \
-lx265
}
core_mac {
@ -30,6 +41,10 @@ core_mac {
core_windows {
DEFINES += JAS_WIN_MSVC_BUILD NOMINMAX
LIBS += -lUser32
LIBS += -L$$LIB_3DPARTY_PRI_PATH \
-lheif \
-llibde265 \
-lx265-static
}
core_android {
@ -39,7 +54,8 @@ core_android {
INCLUDEPATH += \
$$LIB_GRAPHICS_PRI_PATH/cximage/jasper/include \
$$LIB_GRAPHICS_PRI_PATH/cximage/jpeg \
$$LIB_GRAPHICS_PRI_PATH/cximage/png
$$LIB_GRAPHICS_PRI_PATH/cximage/png \
$$LIB_GRAPHICS_PRI_PATH/../Common/3dParty/heif/libheif/libheif/api \
HEADERS += \
$$PWD/../../graphics/Image.h \
@ -285,6 +301,9 @@ SOURCES += \
$$LIB_GRAPHICS_PRI_PATH/raster/PICT/PICFile.cpp \
$$LIB_GRAPHICS_PRI_PATH/raster/PICT/pic.cpp
SOURCES += \
$$LIB_GRAPHICS_PRI_PATH/raster/heif/heif.cpp
SOURCES += \
$$LIB_GRAPHICS_PRI_PATH/cximage/jasper/base/jas_cm.c \
$$LIB_GRAPHICS_PRI_PATH/cximage/jasper/base/jas_debug.c \

View File

@ -0,0 +1,9 @@
#include "../../pro/Graphics.h"
int main(int argc, char *argv[])
{
Aggplus::CImage img(L"C:\\Users\\KProkhorov\\Work\\core\\DesktopEditor\\graphics\\tests\\testHeic\\image1.heic");
img.SaveFile(L"C:\\Users\\KProkhorov\\Work\\core\\DesktopEditor\\graphics\\tests\\testHeic\\image1.bmp", 1);
return 0;
}

View File

@ -0,0 +1,23 @@
QT -= core
QT -= gui
TARGET = test
CONFIG += console
TEMPLATE = app
CORE_ROOT_DIR = $$PWD/../../../..
PWD_ROOT_DIR = $$PWD
include($$CORE_ROOT_DIR/Common/base.pri)
include($$CORE_ROOT_DIR/Common/3dParty/icu/icu.pri)
ADD_DEPENDENCY(kernel, graphics, UnicodeConverter)
GRAPHICS_AGG_PATH = $$PWD/../../../agg-2.4
INCLUDEPATH += \
$$GRAPHICS_AGG_PATH/include
SOURCES += main.cpp
DESTDIR = $$PWD_ROOT_DIR/build/$$CORE_BUILDS_PLATFORM_PREFIX/$$CORE_BUILDS_CONFIGURATION_PREFIX

View File

@ -44,6 +44,10 @@
#include "PICT/PICFile.h"
#endif
#if CXIMAGE_SUPPORT_HEIF
#include "heif/heif.h"
#endif
#include <cmath>
#define BGRA_FRAME_CXIMAGE_MAX_MEMORY 67108864 // 256Mb (*4 channel)
@ -444,11 +448,18 @@ bool CBgraFrame::OpenFile(const std::wstring& strFileName, unsigned int nFileTyp
#endif
#if CXIMAGE_SUPPORT_PIC
if (CXIMAGE_FORMAR_PIC == m_nFileType)
{
PICT::CPictFile PIC;
return PIC.Open(this, strFileName, !m_bIsRGBA);
}
if (CXIMAGE_FORMAR_PIC == m_nFileType)
{
PICT::CPictFile PIC;
return PIC.Open(this, strFileName, !m_bIsRGBA);
}
#endif
#if CXIMAGE_SUPPORT_HEIF
if (CXIMAGE_FORMAT_HEIF == m_nFileType)
{
return NSHeif::CHeifFile::Open(this, strFileName);
}
#endif
NSFile::CFileBinary oFile;
@ -534,6 +545,13 @@ bool CBgraFrame::Decode(BYTE* pBuffer, int nSize, unsigned int nFileType)
}
#endif
#if CXIMAGE_SUPPORT_HEIF
if (CXIMAGE_FORMAT_HEIF == m_nFileType)
{
return NSHeif::CHeifFile::Open(this, pBuffer, nSize);
}
#endif
CxImage img;
if (!img.Decode(pBuffer, nSize, m_nFileType))
@ -562,28 +580,32 @@ bool CBgraFrame::SaveFile(const std::wstring& strFileName, unsigned int nFileTyp
return res;
}
else
#endif
#if CXIMAGE_SUPPORT_HEIF
if (CXIMAGE_FORMAT_HEIF == nFileType)
{
NSFile::CFileBinary oFile;
if (!oFile.CreateFileW(strFileName))
return false;
CxImage img;
if (!img.CreateFromArray(m_pData, m_lWidth, m_lHeight, lBitsPerPixel * 8, lStride, (m_lStride >= 0) ? true : false, !m_bIsRGBA))
return false;
if (m_pPalette)
{
img.SetPalette((RGBQUAD*)m_pPalette, m_lPaletteColors);
}
if (!img.Encode(oFile.GetFileNative(), nFileType))
return false;
oFile.CloseFile();
return NSHeif::CHeifFile::Save(m_pData, m_lWidth, m_lHeight, m_lStride, strFileName);
}
#endif
NSFile::CFileBinary oFile;
if (!oFile.CreateFileW(strFileName))
return false;
CxImage img;
if (!img.CreateFromArray(m_pData, m_lWidth, m_lHeight, lBitsPerPixel * 8, lStride, (m_lStride >= 0) ? true : false, !m_bIsRGBA))
return false;
if (m_pPalette)
{
img.SetPalette((RGBQUAD*)m_pPalette, m_lPaletteColors);
}
if (!img.Encode(oFile.GetFileNative(), nFileType))
return false;
oFile.CloseFile();
return true;
}
bool CBgraFrame::Encode(BYTE*& pBuffer, int& nSize, unsigned int nFileType)

View File

@ -32,6 +32,7 @@
#include "ImageFileFormatChecker.h"
#include "../common/File.h"
#include "../cximage/CxImage/ximacfg.h"
#include "heif/heif.h"
#ifndef IMAGE_CHECKER_DISABLE_XML
#include "../xml/include/xmlutils.h"
@ -432,6 +433,11 @@ bool CImageFileFormatChecker::isPicFile(BYTE *pBuffer, DWORD dwBytes)
return false;
}
bool CImageFileFormatChecker::isHeifFile(BYTE* pBuffer, DWORD dwBytes)
{
return NSHeif::CHeifFile::isHeif(pBuffer, dwBytes);
}
//////////////////////////////////////////////////////////////////////////////////////////////////////////////////
bool CImageFileFormatChecker::isImageFile(const std::wstring& fileName)
{
@ -554,6 +560,10 @@ bool CImageFileFormatChecker::isImageFile(const std::wstring& fileName)
{
eFileType = _CXIMAGE_FORMAT_PIC;
}
else if (isHeifFile(fileName))
{
eFileType = _CXIMAGE_FORMAT_HEIF;
}
///////////////////////////////////////////////////////////////////////
delete [] buffer;
@ -669,6 +679,10 @@ bool CImageFileFormatChecker::isImageFile(BYTE* buffer, DWORD sizeRead)
{
eFileType = _CXIMAGE_FORMAT_PIC;
}
if (isHeifFile(buffer, sizeRead))
{
eFileType = _CXIMAGE_FORMAT_HEIF;
}
///////////////////////////////////////////////////////////////////////
if (eFileType) return true;
return false;
@ -786,6 +800,10 @@ bool CImageFileFormatChecker::isSvgFile(const std::wstring& fileName)
return bFind;
#endif
}
bool CImageFileFormatChecker::isHeifFile(const std::wstring& fileName)
{
return NSHeif::CHeifFile::isHeif(fileName);
}
std::wstring CImageFileFormatChecker::DetectFormatByData(BYTE *Data, int DataSize)
{

View File

@ -63,6 +63,7 @@ enum __ENUM_CXIMAGE_FORMATS
_CXIMAGE_FORMAT_SVM = 23,
_CXIMAGE_FORMAT_SVG = 24,
_CXIMAGE_FORMAT_PIC = 25,
_CXIMAGE_FORMAT_HEIF = 26,
};
class GRAPHICS_DECL CImageFileFormatChecker
@ -82,6 +83,7 @@ public:
bool isRawFile(const std::wstring& fileName);
bool isSvgFile(const std::wstring& fileName);
bool isHeifFile(const std::wstring& fileName);
bool isImageFile(BYTE* pBuffer,DWORD dwBytes);
bool isBmpFile(BYTE* pBuffer,DWORD dwBytes);
@ -111,6 +113,7 @@ public:
bool isSvgFile(BYTE* pBuffer,DWORD dwBytes);
bool isRawFile(BYTE* pBuffer,DWORD dwBytes);
bool isPicFile(BYTE* pBuffer,DWORD dwBytes);
bool isHeifFile(BYTE* pBuffer, DWORD dwBytes);
std::wstring DetectFormatByData(BYTE *Data, int DataSize);

View File

@ -0,0 +1,152 @@
#include "heif.h"
#include "../../common/File.h"
#include <functional>
#define CONCAT_IMPL(x, y) x##y
#define CONCAT(x, y) CONCAT_IMPL(x, y)
#define defer(code) Defer CONCAT(_defer_, __COUNTER__)([&](){code;})
class Defer {
std::function<void()> func;
public:
explicit Defer(std::function<void()> func) : func(func) {}
~Defer() { func(); }
};
namespace NSHeif {
bool CHeifFile::isHeif(const std::wstring& fileName)
{
heif_context* ctx = heif_context_alloc();
defer(heif_context_free(ctx););
return !IsError(heif_context_read_from_file(ctx, m_oConverter.fromUnicode(fileName, "UTF-8").c_str(), nullptr));
}
bool CHeifFile::isHeif(BYTE* buffer, DWORD size)
{
heif_context* ctx = heif_context_alloc();
defer(heif_context_free(ctx););
return !IsError(heif_context_read_from_memory_without_copy(ctx, buffer, size, nullptr));
}
bool CHeifFile::Open(CBgraFrame *frame, const std::wstring& fileName)
{
heif_context* ctx = heif_context_alloc();
defer(heif_context_free(ctx););
if (IsError(heif_context_read_from_file(ctx, m_oConverter.fromUnicode(fileName, "UTF-8").c_str(), nullptr)))
return false;
return Decode(ctx, frame);
}
bool CHeifFile::Open(CBgraFrame *frame, BYTE* buffer, DWORD size)
{
heif_context* ctx = heif_context_alloc();
defer(heif_context_free(ctx););
if (IsError(heif_context_read_from_memory_without_copy(ctx, buffer, size, nullptr)))
return false;
return Decode(ctx, frame);
}
bool CHeifFile::Save(const BYTE* source, int width, int height, int sourceStride, const std::wstring& dstPath)
{
if (!source)
return false;
heif_image* img;
defer(heif_image_release(img););
if (IsError(heif_image_create(width, height, heif_colorspace_RGB, heif_chroma_interleaved_RGB, &img)))
return false;
if (IsError(heif_image_add_plane(img, heif_channel_interleaved, width, height, 24)))
return false;
int stride;
BYTE* data = heif_image_get_plane(img, heif_channel_interleaved, &stride);
if (!data || stride == 0)
return false;
for (size_t i = 0; i < height; ++i)
{
const BYTE* row = source + (height - i - 1) * (sourceStride < 0 ? -sourceStride : sourceStride);
for (size_t j = 0; j < width; ++j)
{
data[(i * width + j) * 3 + 0] = row[(width - j - 1) * 4 + 2];
data[(i * width + j) * 3 + 1] = row[(width - j - 1) * 4 + 1];
data[(i * width + j) * 3 + 2] = row[(width - j - 1) * 4 + 0];
}
}
heif_context* ctx = heif_context_alloc();
defer(heif_context_free(ctx););
heif_encoder* encoder;
defer(heif_encoder_release(encoder););
if (IsError(heif_context_get_encoder_for_format(ctx, heif_compression_HEVC, &encoder)))
return false;
if (IsError(heif_context_encode_image(ctx, img, encoder, nullptr, nullptr)))
return false;
if (IsError(heif_context_write_to_file(ctx, m_oConverter.fromUnicode(dstPath, "UTF-8").c_str())))
return false;
return true;
}
inline bool CHeifFile::IsError(heif_error err)
{
return err.code != heif_error_Ok;
}
inline bool CHeifFile::Decode(heif_context* ctx, CBgraFrame* frame)
{
heif_image_handle* handle;
defer(heif_image_handle_release(handle););
if (IsError(heif_context_get_primary_image_handle(ctx, &handle)))
return false;
heif_image* img;
defer(heif_image_release(img););
if (IsError(heif_decode_image(handle, &img, heif_colorspace_RGB, heif_chroma_444, nullptr)))
return false;
int width = heif_image_get_primary_width(img);
int height = heif_image_get_primary_height(img);
int stride_R, stride_G, stride_B;
const BYTE* source_R = heif_image_get_plane_readonly(img, heif_channel_R, &stride_R);
const BYTE* source_G = heif_image_get_plane_readonly(img, heif_channel_G, &stride_G);
const BYTE* source_B = heif_image_get_plane_readonly(img, heif_channel_B, &stride_B);
if (stride_R == 0 || !source_R)
return false;
BYTE* data = new BYTE[4 * width * height];
frame->put_Width(width);
frame->put_Height(height);
frame->put_Stride(4 * width);
frame->put_Data(data);
for (size_t i = 0; i < height; ++i)
{
const BYTE* row_R = source_R + i * stride_R;
const BYTE* row_G = source_G + i * stride_G;
const BYTE* row_B = source_B + i * stride_B;
for (size_t j = 0; j < width; ++j)
{
data[(i * width + j) * 4 + 0] = row_B[j];
data[(i * width + j) * 4 + 1] = row_G[j];
data[(i * width + j) * 4 + 2] = row_R[j];
data[(i * width + j) * 4 + 3] = 255;
}
}
return true;
}
}

View File

@ -0,0 +1,22 @@
#include "../BgraFrame.h"
#include "../../Common/3dParty/heif/libheif/libheif/api/libheif/heif.h"
#include "../../UnicodeConverter/UnicodeConverter.h"
namespace NSHeif {
class GRAPHICS_DECL CHeifFile {
private:
CHeifFile() = delete;
public:
static bool isHeif(const std::wstring& fileName);
static bool isHeif(BYTE* buffer, DWORD size);
static bool Open(CBgraFrame* frame, const std::wstring& fileName);
static bool Open(CBgraFrame* frame, BYTE* buffer, DWORD size);
static bool Save(const BYTE* source, int width, int height, int sourceStride, const std::wstring& dstPath);
private:
static inline bool IsError(heif_error err);
static inline bool Decode(heif_context* ctx, CBgraFrame* frame);
static inline NSUnicodeConverter::CUnicodeConverter m_oConverter{};
};
}

View File

@ -37,19 +37,12 @@
#include "../DesktopEditor/graphics/commands/DocInfo.h"
#include <algorithm>
enum class ShapeSerializeType
{
sstBinary,
sstXml
};
class CDocxRenderer_Private
{
public:
NSDocxRenderer::CDocument m_oDocument;
std::wstring m_sTempDirectory;
bool m_bIsSupportShapeCommands = false;
ShapeSerializeType m_eShapeSerializeType = ShapeSerializeType::sstBinary;
public:
CDocxRenderer_Private(NSFonts::IApplicationFonts* pFonts, IRenderer* pRenderer) : m_oDocument(pRenderer, pFonts)
@ -146,28 +139,12 @@ std::vector<std::wstring> CDocxRenderer::ScanPagePptx(IOfficeDrawingFile* pFile,
m_pInternal->m_oDocument.m_oCurrentPage.m_bWriteStyleRaw = true;
m_pInternal->m_bIsSupportShapeCommands = true;
m_pInternal->m_eShapeSerializeType = ShapeSerializeType::sstXml;
DrawPage(pFile, nPage);
m_pInternal->m_eShapeSerializeType = ShapeSerializeType::sstBinary;
auto xml_shapes = m_pInternal->m_oDocument.m_oCurrentPage.GetXmlShapesPptx();
m_pInternal->m_oDocument.Clear();
return xml_shapes;
}
NSWasm::CData CDocxRenderer::ScanPageBin(IOfficeDrawingFile* pFile, size_t nPage)
{
m_pInternal->m_oDocument.Clear();
m_pInternal->m_oDocument.Init(false);
m_pInternal->m_oDocument.m_oCurrentPage.m_bUseDefaultFont = true;
m_pInternal->m_oDocument.m_oCurrentPage.m_bWriteStyleRaw = true;
m_pInternal->m_bIsSupportShapeCommands = true;
DrawPage(pFile, nPage);
auto bin_shapes = m_pInternal->m_oDocument.m_oCurrentPage.GetShapesBin();
m_pInternal->m_oDocument.Clear();
return bin_shapes;
}
void CDocxRenderer::SetExternalImageStorage(NSDocxRenderer::IImageStorage* pStorage)
{
@ -217,7 +194,6 @@ HRESULT CDocxRenderer::IsSupportAdvancedCommand(const IAdvancedCommand::Advanced
return S_FALSE;
}
HRESULT CDocxRenderer::AdvancedCommand(IAdvancedCommand* command)
{
if (NULL == command)
@ -229,69 +205,14 @@ HRESULT CDocxRenderer::AdvancedCommand(IAdvancedCommand* command)
{
CShapeStart* pShape = (CShapeStart*)command;
std::string& sUtf8Shape = pShape->GetShapeXML();
UINT nImageId = 0xFFFFFFFF;
Aggplus::CImage* pImage = pShape->GetShapeImage();
if (pImage)
{
std::shared_ptr<NSDocxRenderer::CImageInfo> pInfo = m_pInternal->m_oDocument.m_oImageManager.GenerateImageID(pImage);
nImageId = pInfo->m_nId;
}
if (sUtf8Shape.empty())
return S_FALSE;
if ('<' == sUtf8Shape.at(0))
{
if (m_pInternal->m_eShapeSerializeType == ShapeSerializeType::sstBinary)
return S_FALSE;
if (0xFFFFFFFF != nImageId)
{
std::string sNewId = "r:embed=\"rId" + std::to_string(nImageId + c_iStartingIdForImages) + "\"";
NSStringUtils::string_replaceA(sUtf8Shape, "r:embed=\"\"", sNewId);
}
m_pInternal->m_oDocument.m_oCurrentPage.AddCompleteXml(UTF8_TO_U(sUtf8Shape));
}
else
{
if (m_pInternal->m_eShapeSerializeType == ShapeSerializeType::sstXml)
return S_FALSE;
if (0xFFFFFFFF != nImageId)
{
std::wstring rId_new = L"rId" + std::to_wstring(nImageId + c_iStartingIdForImages);
NSWasm::CData rId_record;
rId_record.StartRecord(100);
rId_record.WriteStringUtf16(rId_new);
rId_record.EndRecord();
int buff_len = NSBase64::Base64DecodeGetRequiredLength(sUtf8Shape.size());
BYTE* buff = new BYTE[buff_len + rId_record.GetSize()];
if (NSBase64::Base64Decode(sUtf8Shape.c_str(), (int)sUtf8Shape.size(), buff, &buff_len))
{
memcpy(buff + buff_len, rId_record.GetBuffer(), rId_record.GetSize());
unsigned int curr_len = 0;
memcpy(&curr_len, buff + 1, sizeof(unsigned int)); // first byte is "type" byte
curr_len += rId_record.GetSize();
memcpy(buff + 1, &curr_len, sizeof(unsigned int));
}
int buff_len_new = buff_len + rId_record.GetSize();
int size_base64 = NSBase64::Base64EncodeGetRequiredLength(buff_len_new);
char* data_base64 = new char[size_base64];
NSBase64::Base64Encode(buff, buff_len_new, (BYTE*)data_base64, &size_base64, NSBase64::B64_BASE64_FLAG_NOCRLF);
sUtf8Shape = std::string(data_base64, size_base64);
delete[] buff;
delete[] data_base64;
}
m_pInternal->m_oDocument.m_oCurrentPage.AddCompleteBinBase64(sUtf8Shape);
std::string sNewId = "r:embed=\"rId" + std::to_string(pInfo->m_nId + c_iStartingIdForImages) + "\"";
NSStringUtils::string_replaceA(sUtf8Shape, "r:embed=\"\"", sNewId);
}
m_pInternal->m_oDocument.m_oCurrentPage.AddCompleteXml(UTF8_TO_U(sUtf8Shape));
return S_OK;
}
case IAdvancedCommand::AdvancedCommandType::ShapeEnd:

View File

@ -45,7 +45,6 @@
#include "convert_params.h"
#include "src/logic/managers/ExternalImageStorage.h"
#include "../DesktopEditor/graphics/pro/js/wasm/src/serialize.h"
class CDocxRenderer_Private;
class DOCXRENDERER_DECL_EXPORT CDocxRenderer : public IRenderer
@ -179,7 +178,6 @@ public:
int Convert(IOfficeDrawingFile* pFile, const std::wstring& sDstFile, bool bIsOutCompress = true);
std::vector<std::wstring> ScanPage(IOfficeDrawingFile* pFile, size_t nPage);
std::vector<std::wstring> ScanPagePptx(IOfficeDrawingFile* pFile, size_t nPage);
NSWasm::CData ScanPageBin(IOfficeDrawingFile* pFile, size_t nPage);
void SetExternalImageStorage(NSDocxRenderer::IImageStorage* pStorage);
private:

View File

@ -12,10 +12,10 @@
namespace NSDocxRenderer
{
CDocument::CDocument(IRenderer* pRenderer, NSFonts::IApplicationFonts* pFonts) :
m_pAppFonts(pFonts),
m_oFontManager(pFonts),
m_oFontSelector(pFonts),
m_oCurrentPage(pFonts, {&m_oImageManager, &m_oFontStyleManager, &m_oParagraphStyleManager, &m_oFontManager, &m_oFontSelector})
m_pAppFonts(pFonts),
m_oFontManager(pFonts),
m_oFontSelector(pFonts),
m_oCurrentPage(pFonts, {&m_oImageManager, &m_oFontStyleManager, &m_oParagraphStyleManager, &m_oFontManager, &m_oFontSelector})
{
m_oSimpleGraphicsConverter.SetRenderer(pRenderer);
}
@ -492,8 +492,8 @@ namespace NSDocxRenderer
//-------- Функции для вывода текста --------------------------------------------------------
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)
const double& dX, const double& dY, const double& dW,
const double& dH, const double& dBaseLineOffset)
{
double dAngleMatrix = m_oCurrentPage.m_oTransform.z_Rotation();
if (fabs(dAngleMatrix) > 1 || m_oCurrentPage.m_oTransform.sx() < 0 || m_oCurrentPage.m_oTransform.sy() < 0)
@ -830,44 +830,44 @@ namespace NSDocxRenderer
oDocumentStream.CreateFileW(m_strTempDirectory + L"/word/document.xml");
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>");
<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>");
for (size_t i = 0; i < m_mapXmlString.size(); ++i)
for (size_t i = 0; i < m_mapXmlString.size(); ++i)
{
oDocumentStream.WriteStringUTF8(m_mapXmlString[i]->GetData());
}
@ -883,12 +883,12 @@ namespace NSDocxRenderer
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\"/>");
<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 (const auto& pImage : m_oImageManager.m_mapImageData)
{
@ -912,17 +912,17 @@ namespace NSDocxRenderer
NSStringUtils::CStringBuilder oWriter;
// сохраним fontTable
oWriter.WriteString(L"<?xml version=\"1.0\" encoding=\"UTF-8\" standalone=\"yes\"?>\
<w:fonts xmlns:mc=\"http://schemas.openxmlformats.org/markup-compatibility/2006\" \
xmlns:r=\"http://schemas.openxmlformats.org/officeDocument/2006/relationships\" \
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\" \
mc:Ignorable=\"w14 w15 w16se w16cid w16 w16cex w16sdtdh\">");
<w:fonts xmlns:mc=\"http://schemas.openxmlformats.org/markup-compatibility/2006\" \
xmlns:r=\"http://schemas.openxmlformats.org/officeDocument/2006/relationships\" \
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\" \
mc:Ignorable=\"w14 w15 w16se w16cid w16 w16cex w16sdtdh\">");
const auto& cache = m_oFontSelector.GetCache();
std::list<CFontSelector::CFontSelectInfo> font_table;
@ -994,17 +994,17 @@ namespace NSDocxRenderer
// сохраним styles
oWriter.WriteString(L"<?xml version=\"1.0\" encoding=\"UTF-8\" standalone=\"yes\"?>\
<w:styles xmlns:mc=\"http://schemas.openxmlformats.org/markup-compatibility/2006\" \
xmlns:r=\"http://schemas.openxmlformats.org/officeDocument/2006/relationships\" \
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\" \
mc:Ignorable=\"w14 w15 w16se w16cid w16 w16cex w16sdtdh\">");
<w:styles xmlns:mc=\"http://schemas.openxmlformats.org/markup-compatibility/2006\" \
xmlns:r=\"http://schemas.openxmlformats.org/officeDocument/2006/relationships\" \
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\" \
mc:Ignorable=\"w14 w15 w16se w16cid w16 w16cex w16sdtdh\">");
oWriter.WriteString(L"<w:docDefaults>");
oWriter.WriteString(L"<w:rPrDefault><w:rPr>");

File diff suppressed because it is too large Load Diff

View File

@ -68,65 +68,50 @@ namespace NSDocxRenderer
void DrawPath(LONG lType, const std::shared_ptr<CImageInfo> pInfo);
void AddText(
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 PUINT pUnicodes,
const PUINT pGids,
const UINT& nCount,
const double& fX,
const double& fY,
const double& fWidth,
const double& fHeight,
const double& fBaseLineOffset);
void Analyze();
void Record(NSStringUtils::CStringBuilder& oWriter, bool bIsLastPage);
std::vector<std::wstring> GetXmlShapes();
std::vector<std::wstring> GetXmlShapesPptx();
NSWasm::CData GetShapesBin();
void AddCompleteXml(const std::wstring& oXml);
void AddCompleteBinBase64(const std::string& oBase64);
void AddCompleteXml(const std::wstring oXml);
private:
using shape_ptr_t = std::shared_ptr<CShape>;
using cont_ptr_t = std::shared_ptr<CContText>;
using text_line_ptr_t = std::shared_ptr<CTextLine>;
using base_item_ptr_t = std::shared_ptr<CBaseItem>;
using ooxml_item_ptr_t = std::shared_ptr<IOoxmlItem>;
using line_ptr_t = std::shared_ptr<CTextLine>;
using item_ptr_t = std::shared_ptr<CBaseItem>;
using paragraph_ptr_t = std::shared_ptr<CParagraph>;
using table_ptr_t = std::shared_ptr<CTable>;
using graphical_cell_ptr_t = std::shared_ptr<CGraphicalCell>;
using text_cell_ptr_t = std::shared_ptr<CTextCell>;
using cell_ptr_t = std::shared_ptr<CTable::CCell>;
using text_line_group_ptr_t = std::shared_ptr<CBaseItemGroup<CTextLine>>;
using text_cell_group_ptr_t = std::shared_ptr<CBaseItemGroup<CTextCell>>;
using cell_group_ptr_t = std::shared_ptr<CBaseItemGroup<CTable::CCell>>;
// returns std::vector of conts with diac. symbols and remove it from m_arConts
std::vector<cont_ptr_t> MoveDiacriticalSymbols();
// returns std::vector of text lines builded from m_arConts
std::vector<text_line_ptr_t> BuildTextLines(const std::vector<cont_ptr_t>& arConts);
// build text line groups
std::vector<text_line_group_ptr_t> BuildTextLineGroups();
std::vector<line_ptr_t> BuildTextLines();
// returns std::vector of paragraphs builded from m_arTextLines
std::vector<paragraph_ptr_t> BuildParagraphs(const std::vector<text_line_group_ptr_t>& arTextLineGroups);
// return groups of text cells
std::vector<text_cell_group_ptr_t> BuildTextCellGroups(const std::vector<text_line_group_ptr_t>& arTextLineGroups);
std::vector<paragraph_ptr_t> BuildParagraphs();
// returns std::vector of tables builded from shapes and paragraphes
std::vector<table_ptr_t> BuildTables(const std::vector<text_line_group_ptr_t>& arTextLineGroups);
std::vector<table_ptr_t> BuildTables();
// return std::vector of graphical cells (from shapes)
std::vector<graphical_cell_ptr_t> BuildGraphicalCells();
// returns std::vector of cells for tables
std::vector<CTable::cell_ptr_t> BuildCells();
// returns std::vector of rows for tables
std::vector<CTable::row_ptr_t> BuildRows(std::vector<CTable::cell_ptr_t>& arCells);
// returns std::vector of base items builded from m_arParagraphs
std::vector<ooxml_item_ptr_t> BuildOutputObjects();
std::vector<item_ptr_t> BuildOutputObjects();
// analyze shapes (set lines type)
void AnalyzeShapes();
@ -147,7 +132,7 @@ namespace NSDocxRenderer
void AnalyzeEffects();
// adds diacritical symbols in conts
void AddDiacriticalSymbols(const std::vector<cont_ptr_t>& arDiac);
void AddDiacriticalSymbols();
// super-sub scripts line merge
void MergeTextLinesByVatType();
@ -182,24 +167,27 @@ namespace NSDocxRenderer
// for drawingml is no tag behind-doc - so we need to reorder shapes
void ReorderShapesForPptx();
// get lines by groups by X
std::vector<std::vector<line_ptr_t>> GetLinesByGroups();
bool IsLineCrossingText(shape_ptr_t pShape, cont_ptr_t pCont) const noexcept;
bool IsLineBelowText(shape_ptr_t pShape, cont_ptr_t pCont) const noexcept;
bool IsHighlight(shape_ptr_t pShape, cont_ptr_t pCont) const noexcept;
bool IsOutline(shape_ptr_t pShape, cont_ptr_t pCont) const noexcept;
bool IsVerticalLineBetween(base_item_ptr_t pFirst, base_item_ptr_t pSecond) const noexcept;
bool IsHorizontalLineBetween(base_item_ptr_t pFirst, base_item_ptr_t pSecond) const noexcept;
bool IsVerticalLineBetween(item_ptr_t pFirst, item_ptr_t pSecond) const noexcept;
bool IsHorizontalLineBetween(item_ptr_t pFirst, item_ptr_t pSecond) const noexcept;
bool IsVerticalLineBetween(text_line_ptr_t pFirst, text_line_ptr_t pSecond) const noexcept;
bool IsHorizontalLineBetween(text_line_ptr_t pFirst, text_line_ptr_t pSecond) const noexcept;
bool IsVerticalLineBetween(line_ptr_t pFirst, line_ptr_t pSecond) const noexcept;
bool IsHorizontalLineBetween(line_ptr_t pFirst, line_ptr_t pSecond) const noexcept;
bool IsVerticalLineTrough(base_item_ptr_t pFirst) const noexcept;
bool IsHorizontalLineTrough(base_item_ptr_t pFirst) const noexcept;
bool IsVerticalLineTrough(item_ptr_t pFirst) const noexcept;
bool IsHorizontalLineTrough(item_ptr_t pFirst) const noexcept;
void ToXml(NSStringUtils::CStringBuilder& oWriter) const noexcept;
void WriteSectionToFile(bool bLastPage, NSStringUtils::CStringBuilder& oWriter) const noexcept;
static shape_ptr_t CreateSingleLineShape(text_line_ptr_t& pLine);
static shape_ptr_t CreateSingleLineShape(line_ptr_t& pLine);
static shape_ptr_t CreateSingleParagraphShape(paragraph_ptr_t& pParagraph);
void DrawImage(shape_ptr_t pShape, std::shared_ptr<CImageInfo> oImg, CVectorGraphics& imageVector);
@ -216,14 +204,15 @@ namespace NSDocxRenderer
CContTextBuilder m_oContBuilder;
CHorVerLinesCollector m_oHorVerLinesCollector;
std::vector<shape_ptr_t> m_arShapes;
std::vector<text_line_ptr_t> m_arTextLines;
std::vector<paragraph_ptr_t> m_arParagraphs;
std::vector<table_ptr_t> m_arTables;
std::vector<ooxml_item_ptr_t> m_arOutputObjects;
std::vector<cont_ptr_t> m_arConts;
std::vector<line_ptr_t> m_arTextLines;
std::vector<cont_ptr_t> m_arDiacriticalSymbols;
std::vector<shape_ptr_t> m_arShapes;
std::vector<paragraph_ptr_t> m_arParagraphs;
std::vector<table_ptr_t> m_arTables;
std::vector<item_ptr_t> m_arOutputObjects;
std::vector<std::wstring> m_arCompleteObjectsXml;
std::vector<std::string> m_arCompleteObjectsBinBase64;
// save the luminosity shapes for later filling
std::vector<shape_ptr_t> m_arLuminosityShapes;

View File

@ -6,102 +6,76 @@
namespace NSDocxRenderer
{
CBaseItem::CBaseItem()
CBaseItem& CBaseItem::operator=(const CBaseItem& oSrc)
{
}
CBaseItem::CBaseItem(const CBaseItem& other) :
m_dTop(other.m_dTop),
m_dBot(other.m_dBot),
m_dLeft(other.m_dLeft),
m_dRight(other.m_dRight),
m_dHeight(other.m_dHeight),
m_dWidth(other.m_dWidth)
{
}
CBaseItem::CBaseItem(CBaseItem&& other) :
m_dTop(other.m_dTop),
m_dBot(other.m_dBot),
m_dLeft(other.m_dLeft),
m_dRight(other.m_dRight),
m_dHeight(other.m_dHeight),
m_dWidth(other.m_dWidth)
{
}
CBaseItem::~CBaseItem()
{
}
CBaseItem& CBaseItem::operator=(const CBaseItem& other)
{
if (this == &other)
if (this == &oSrc)
return *this;
m_dTop = other.m_dTop;
m_dBot = other.m_dBot;
m_dLeft = other.m_dLeft;
m_dRight = other.m_dRight;
m_dHeight = other.m_dHeight;
m_dWidth = other.m_dWidth;
m_dLeft = oSrc.m_dLeft;
m_dTop = oSrc.m_dTop;
m_dWidth = oSrc.m_dWidth;
m_dHeight = oSrc.m_dHeight;
m_dBaselinePos = oSrc.m_dBaselinePos;
m_dRight = oSrc.m_dRight;
return *this;
}
CBaseItem& CBaseItem::operator=(CBaseItem&& other)
bool CBaseItem::operator==(const CBaseItem& oSrc)
{
if (this == &other)
return *this;
if (this == &oSrc)
return true;
m_dTop = other.m_dTop;
m_dBot = other.m_dBot;
m_dLeft = other.m_dLeft;
m_dRight = other.m_dRight;
m_dHeight = other.m_dHeight;
m_dWidth = other.m_dWidth;
return *this;
return m_dLeft == oSrc.m_dLeft &&
m_dTop == oSrc.m_dTop &&
m_dWidth == oSrc.m_dWidth &&
m_dHeight == oSrc.m_dHeight &&
m_dBaselinePos == oSrc.m_dBaselinePos &&
m_dRight == oSrc.m_dRight;
}
eVerticalCrossingType CBaseItem::GetVerticalCrossingType(const CBaseItem* pBaseItem) const
eVerticalCrossingType CBaseItem::GetVerticalCrossingType(const CBaseItem* oSrc) const
{
if (m_dTop > pBaseItem->m_dTop && m_dBot < pBaseItem->m_dBot)
if (m_dTop > oSrc->m_dTop && m_dBaselinePos < oSrc->m_dBaselinePos)
{
return eVerticalCrossingType::vctCurrentInsideNext;
}
else if (m_dTop < pBaseItem->m_dTop && m_dBot > pBaseItem->m_dBot)
else if (m_dTop < oSrc->m_dTop && m_dBaselinePos > oSrc->m_dBaselinePos)
{
return eVerticalCrossingType::vctCurrentOutsideNext;
}
else if (m_dTop < pBaseItem->m_dTop && m_dBot < pBaseItem->m_dBot &&
(m_dBot >= pBaseItem->m_dTop || fabs(m_dBot - pBaseItem->m_dTop) < c_dTHE_SAME_STRING_Y_PRECISION_MM))
else if (m_dTop < oSrc->m_dTop && m_dBaselinePos < oSrc->m_dBaselinePos &&
(m_dBaselinePos >= oSrc->m_dTop || fabs(m_dBaselinePos - oSrc->m_dTop) < c_dTHE_SAME_STRING_Y_PRECISION_MM))
{
return eVerticalCrossingType::vctCurrentAboveNext;
}
else if (m_dTop > pBaseItem->m_dTop && m_dBot > pBaseItem->m_dBot &&
(m_dTop <= pBaseItem->m_dBot || fabs(m_dTop - pBaseItem->m_dBot) < c_dTHE_SAME_STRING_Y_PRECISION_MM))
else if (m_dTop > oSrc->m_dTop && m_dBaselinePos > oSrc->m_dBaselinePos &&
(m_dTop <= oSrc->m_dBaselinePos || fabs(m_dTop - oSrc->m_dBaselinePos) < c_dTHE_SAME_STRING_Y_PRECISION_MM))
{
return eVerticalCrossingType::vctCurrentBelowNext;
}
else if (m_dTop == pBaseItem->m_dTop && m_dBot == pBaseItem->m_dBot &&
m_dLeft == pBaseItem->m_dLeft && m_dRight == pBaseItem->m_dRight)
else if (m_dTop == oSrc->m_dTop && m_dBaselinePos == oSrc->m_dBaselinePos &&
m_dLeft == oSrc->m_dLeft && m_dRight == oSrc->m_dRight)
{
return eVerticalCrossingType::vctDublicate;
}
else if (fabs(m_dTop - pBaseItem->m_dTop) < c_dTHE_SAME_STRING_Y_PRECISION_MM &&
fabs(m_dBot - pBaseItem->m_dBot) < c_dTHE_SAME_STRING_Y_PRECISION_MM)
else if (fabs(m_dTop - oSrc->m_dTop) < c_dTHE_SAME_STRING_Y_PRECISION_MM &&
fabs(m_dBaselinePos - oSrc->m_dBaselinePos) < c_dTHE_SAME_STRING_Y_PRECISION_MM)
{
return eVerticalCrossingType::vctTopAndBottomBordersMatch;
}
else if (fabs(m_dTop - pBaseItem->m_dTop) < c_dTHE_SAME_STRING_Y_PRECISION_MM)
else if (fabs(m_dTop - oSrc->m_dTop) < c_dTHE_SAME_STRING_Y_PRECISION_MM)
{
return eVerticalCrossingType::vctTopBorderMatch;
}
else if (fabs(m_dBot - pBaseItem->m_dBot) < c_dTHE_SAME_STRING_Y_PRECISION_MM)
else if (fabs(m_dBaselinePos - oSrc->m_dBaselinePos) < c_dTHE_SAME_STRING_Y_PRECISION_MM)
{
return eVerticalCrossingType::vctBottomBorderMatch;
}
else if (m_dBot < pBaseItem->m_dTop)
else if (m_dBaselinePos < oSrc->m_dTop)
{
return eVerticalCrossingType::vctNoCrossingCurrentAboveNext;
}
else if (m_dTop > pBaseItem->m_dBot)
else if (m_dTop > oSrc->m_dBaselinePos)
{
return eVerticalCrossingType::vctNoCrossingCurrentBelowNext;
}
@ -110,49 +84,49 @@ namespace NSDocxRenderer
return eVerticalCrossingType::vctUnknown;
}
}
eHorizontalCrossingType CBaseItem::GetHorizontalCrossingType(const CBaseItem* pBaseItem) const
eHorizontalCrossingType CBaseItem::GetHorizontalCrossingType(const CBaseItem* oSrc) const
{
if (m_dLeft > pBaseItem->m_dLeft && m_dRight < pBaseItem->m_dRight)
if (m_dLeft > oSrc->m_dLeft && m_dRight < oSrc->m_dRight)
{
return eHorizontalCrossingType::hctCurrentInsideNext;
}
else if (m_dLeft < pBaseItem->m_dLeft && m_dRight > pBaseItem->m_dRight)
else if (m_dLeft < oSrc->m_dLeft && m_dRight > oSrc->m_dRight)
{
return eHorizontalCrossingType::hctCurrentOutsideNext;
}
else if (fabs(m_dLeft - pBaseItem->m_dLeft) < c_dTHE_SAME_STRING_X_PRECISION_MM &&
fabs(m_dRight - pBaseItem->m_dRight) < c_dTHE_SAME_STRING_X_PRECISION_MM)
{
return eHorizontalCrossingType::hctLeftAndRightBordersMatch;
}
else if (m_dLeft < pBaseItem->m_dLeft && m_dRight < pBaseItem->m_dRight &&
(m_dRight >= pBaseItem->m_dLeft || fabs(m_dRight - pBaseItem->m_dLeft) < c_dTHE_SAME_STRING_X_PRECISION_MM))
else if (m_dLeft < oSrc->m_dLeft && m_dRight < oSrc->m_dRight &&
(m_dRight >= oSrc->m_dLeft || fabs(m_dRight - oSrc->m_dLeft) < c_dTHE_SAME_STRING_X_PRECISION_MM))
{
return eHorizontalCrossingType::hctCurrentLeftOfNext;
}
else if (m_dLeft > pBaseItem->m_dLeft && m_dRight > pBaseItem->m_dRight &&
(m_dLeft <= pBaseItem->m_dRight || fabs(m_dLeft - pBaseItem->m_dRight) < c_dTHE_SAME_STRING_X_PRECISION_MM))
else if (m_dLeft > oSrc->m_dLeft && m_dRight > oSrc->m_dRight &&
(m_dLeft <= oSrc->m_dRight || fabs(m_dLeft - oSrc->m_dRight) < c_dTHE_SAME_STRING_X_PRECISION_MM))
{
return eHorizontalCrossingType::hctCurrentRightOfNext;
}
else if (m_dLeft == pBaseItem->m_dLeft && m_dRight == pBaseItem->m_dRight &&
m_dTop == pBaseItem->m_dTop && m_dBot == pBaseItem->m_dBot)
else if (m_dLeft == oSrc->m_dLeft && m_dRight == oSrc->m_dRight &&
m_dTop == oSrc->m_dTop && m_dBaselinePos == oSrc->m_dBaselinePos)
{
return eHorizontalCrossingType::hctDublicate;
}
else if (fabs(m_dLeft - pBaseItem->m_dLeft) < c_dTHE_SAME_STRING_Y_PRECISION_MM)
else if (fabs(m_dLeft - oSrc->m_dLeft) < c_dTHE_SAME_STRING_X_PRECISION_MM &&
fabs(m_dRight - oSrc->m_dRight) < c_dTHE_SAME_STRING_X_PRECISION_MM)
{
return eHorizontalCrossingType::hctLeftAndRightBordersMatch;
}
else if (fabs(m_dLeft - oSrc->m_dLeft) < c_dTHE_SAME_STRING_Y_PRECISION_MM)
{
return eHorizontalCrossingType::hctLeftBorderMatch;
}
else if (fabs(m_dRight - pBaseItem->m_dRight) < c_dTHE_SAME_STRING_Y_PRECISION_MM)
else if (fabs(m_dRight - oSrc->m_dRight) < c_dTHE_SAME_STRING_Y_PRECISION_MM)
{
return eHorizontalCrossingType::hctRightBorderMatch;
}
else if (m_dRight < pBaseItem->m_dLeft)
else if (m_dRight < oSrc->m_dLeft)
{
return eHorizontalCrossingType::hctNoCrossingCurrentLeftOfNext;
}
else if (m_dLeft > pBaseItem->m_dRight)
else if (m_dLeft > oSrc->m_dRight)
{
return eHorizontalCrossingType::hctNoCrossingCurrentRightOfNext;
}
@ -162,32 +136,31 @@ namespace NSDocxRenderer
}
}
bool CBaseItem::AreObjectsNoCrossingByVertically(const CBaseItem* pBaseItem) const noexcept
bool CBaseItem::AreObjectsNoCrossingByVertically(const CBaseItem* pObj) const noexcept
{
eVerticalCrossingType eVType = GetVerticalCrossingType(pBaseItem);
eVerticalCrossingType eVType = GetVerticalCrossingType(pObj);
return (eVType == eVerticalCrossingType::vctNoCrossingCurrentAboveNext ||
eVType == eVerticalCrossingType::vctNoCrossingCurrentBelowNext);
eVType == eVerticalCrossingType::vctNoCrossingCurrentBelowNext);
}
bool CBaseItem::AreObjectsNoCrossingByHorizontally(const CBaseItem* pBaseItem) const noexcept
bool CBaseItem::AreObjectsNoCrossingByHorizontally(const CBaseItem* pObj) const noexcept
{
eHorizontalCrossingType eHType = GetHorizontalCrossingType(pBaseItem);
eHorizontalCrossingType eHType = GetHorizontalCrossingType(pObj);
return (eHType == eHorizontalCrossingType::hctNoCrossingCurrentLeftOfNext ||
eHType == eHorizontalCrossingType::hctNoCrossingCurrentRightOfNext);
eHType == eHorizontalCrossingType::hctNoCrossingCurrentRightOfNext);
}
bool CBaseItem::IsEqual(double dTop, double dBot, double dLeft, double dRight) const noexcept
bool CBaseItem::IsEqual(double dTop, double dBaselinePos, double dLeft, double dRight) const noexcept
{
return m_dLeft == dLeft && m_dTop == dTop && m_dBot == dBot && m_dRight == dRight;
}
bool CBaseItem::operator==(const CBaseItem& other)
{
return IsEqual(other.m_dTop, other.m_dBot, other.m_dLeft, other.m_dRight);
return m_dLeft == dLeft &&
m_dTop == dTop &&
m_dBaselinePos == dBaselinePos &&
m_dRight == dRight;
}
void CBaseItem::RecalcWithNewItem(const CBaseItem* pItem)
{
m_dBot = std::max(m_dBot, pItem->m_dBot);
m_dBaselinePos = std::max(m_dBaselinePos, pItem->m_dBaselinePos);
if ((pItem->m_dLeft < m_dLeft) || (pItem->m_dLeft > 0 && m_dLeft == 0.0))
m_dLeft = pItem->m_dLeft;
@ -199,6 +172,6 @@ namespace NSDocxRenderer
m_dTop = pItem->m_dTop;
m_dWidth = m_dRight - m_dLeft;
m_dHeight = m_dBot - m_dTop;
m_dHeight = m_dBaselinePos - m_dTop;
}
}

View File

@ -1,10 +1,6 @@
#pragma once
#include <memory>
#include <vector>
#include "../../../../DesktopEditor/common/StringBuilder.h"
#include "../../../../DesktopEditor/graphics/pro/js/wasm/src/serialize.h"
namespace NSDocxRenderer
{
@ -43,112 +39,30 @@ namespace NSDocxRenderer
class CBaseItem
{
public:
double m_dTop {0.0};
double m_dBot {0.0};
double m_dLeft {0.0};
double m_dRight {0.0};
double m_dTop {0.0};
double m_dBaselinePos {0.0};
double m_dHeight {0.0};
double m_dWidth {0.0};
CBaseItem();
CBaseItem(const CBaseItem& other);
CBaseItem(CBaseItem&& other);
virtual ~CBaseItem();
double m_dLeft {0.0};
double m_dRight {0.0};
double m_dWidth {0.0};
CBaseItem& operator=(const CBaseItem& other);
CBaseItem& operator=(CBaseItem&& other);
CBaseItem() = default;
virtual ~CBaseItem() = default;
virtual eVerticalCrossingType GetVerticalCrossingType(const CBaseItem* pBaseItem) const;
virtual eHorizontalCrossingType GetHorizontalCrossingType(const CBaseItem* pBaseItem) const;
virtual void RecalcWithNewItem(const CBaseItem* pBaseItem);
bool AreObjectsNoCrossingByVertically(const CBaseItem* pBaseItem) const noexcept;
bool AreObjectsNoCrossingByHorizontally(const CBaseItem* pBaseItem) const noexcept;
bool IsEqual(double dTop, double dBot, double dLeft, double dRight) const noexcept;
bool operator==(const CBaseItem& other);
};
class IOoxmlItem
{
public:
virtual void Clear() = 0;
virtual void ToXml(NSStringUtils::CStringBuilder& oWriter) const = 0;
virtual void ToXmlPptx(NSStringUtils::CStringBuilder& oWriter) const = 0;
virtual void ToBin(NSWasm::CData& oWriter) const = 0;
static const BYTE kBin_g_nodeAttributeStart = 250;
static const BYTE kBin_g_nodeAttributeEnd = 251;
};
virtual eVerticalCrossingType GetVerticalCrossingType(const CBaseItem* oSrc) const;
virtual eHorizontalCrossingType GetHorizontalCrossingType(const CBaseItem* oSrc) const;
virtual void RecalcWithNewItem(const CBaseItem* pObj);
// using template to avoid downcasting
template <typename T>
class CBaseItemGroup : public CBaseItem
{
public:
std::vector<std::shared_ptr<T>> m_arItems;
bool AreObjectsNoCrossingByVertically(const CBaseItem* pObj) const noexcept;
bool AreObjectsNoCrossingByHorizontally(const CBaseItem* pObj) const noexcept;
bool IsEqual(double dTop, double dBaselinePos, double dLeft, double dRight) const noexcept;
CBaseItemGroup()
{
static_assert(std::is_base_of<CBaseItem, T>::value, "T should has base of CBaseItem!");
}
CBaseItemGroup(const CBaseItemGroup<T>& other) : CBaseItemGroup()
{
for (const auto value : other.m_arItems)
m_arItems.push_back(value);
}
CBaseItemGroup(CBaseItemGroup<T>&& other) : CBaseItemGroup()
{
m_arItems = std::move(other);
}
virtual ~CBaseItemGroup() {}
CBaseItemGroup<T>& operator=(const CBaseItemGroup<T>& other)
{
if (this == &other)
return *this;
m_arItems.clear();
for (const auto value : other.m_arItems)
m_arItems.push_back(value);
return *this;
}
CBaseItemGroup<T>& operator=(CBaseItemGroup<T>&& other)
{
if (this == &other)
return *this;
m_arItems = std::move(other);
return *this;
}
void AddItem(const std::shared_ptr<T>& pItem)
{
CBaseItem::RecalcWithNewItem(pItem.get());
m_arItems.push_back(pItem);
}
void AddItem(std::shared_ptr<T>&& pItem)
{
CBaseItem::RecalcWithNewItem(pItem.get());
m_arItems.push_back(std::move(pItem));
}
};
enum class eBaseItemCmpType
{
bictVertical,
bictHorizontal
};
template <eBaseItemCmpType CmpType>
struct CBaseItemCmp
{
bool operator() (const CBaseItem& item1, const CBaseItem& item2) const
{
if (CmpType == eBaseItemCmpType::bictVertical)
return item1.m_dBot < item2.m_dBot;
if (CmpType == eBaseItemCmpType::bictHorizontal)
return item1.m_dLeft < item2.m_dLeft;
}
CBaseItem& operator=(const CBaseItem& oSrc);
bool operator==(const CBaseItem& oSrc);
};
}

View File

@ -70,7 +70,7 @@ namespace NSDocxRenderer
m_dBotWithDescent = rCont.m_dBotWithDescent;
m_oSelectedFont = rCont.m_oSelectedFont;
m_bPossibleHorSplit = rCont.m_bPossibleHorSplit;
m_bPossibleSplit = rCont.m_bPossibleSplit;
m_bWriteStyleRaw = rCont.m_bWriteStyleRaw;
m_arSymWidths.clear();
@ -135,7 +135,7 @@ namespace NSDocxRenderer
m_dRight = cont->m_dLeft;
m_dWidth = m_dRight - m_dLeft;
m_arSymWidths.resize(index + 1);
m_bPossibleHorSplit = false;
m_bPossibleSplit = false;
return cont;
}
@ -181,18 +181,18 @@ namespace NSDocxRenderer
return eVerticalCrossingType::vctCurrentOutsideNext;
else if (this_top < other_top && this_bot < other_bot &&
(this_bot >= other_top || fabs(this_bot - other_top) < c_dTHE_SAME_STRING_Y_PRECISION_MM))
(this_bot >= other_top || fabs(this_bot - other_top) < c_dTHE_SAME_STRING_Y_PRECISION_MM))
return eVerticalCrossingType::vctCurrentAboveNext;
else if (this_top > other_top && this_bot > other_bot &&
(this_top <= other_bot || fabs(this_top - other_bot) < c_dTHE_SAME_STRING_Y_PRECISION_MM))
(this_top <= other_bot || fabs(this_top - other_bot) < c_dTHE_SAME_STRING_Y_PRECISION_MM))
return eVerticalCrossingType::vctCurrentBelowNext;
else if (this_top == other_top && this_bot == other_bot)
return eVerticalCrossingType::vctDublicate;
else if (fabs(this_top - other_top) < c_dTHE_SAME_STRING_Y_PRECISION_MM &&
fabs(this_bot - other_bot) < c_dTHE_SAME_STRING_Y_PRECISION_MM)
fabs(this_bot - other_bot) < c_dTHE_SAME_STRING_Y_PRECISION_MM)
return eVerticalCrossingType::vctTopAndBottomBordersMatch;
else if (fabs(this_top - other_top) < c_dTHE_SAME_STRING_Y_PRECISION_MM)
@ -475,7 +475,7 @@ namespace NSDocxRenderer
oWriter.WriteString(L" x=\"");
oWriter.AddDouble(m_dLeft, 4);
oWriter.WriteString(L"\" y=\"");
oWriter.AddDouble(m_dBot, 4);
oWriter.AddDouble(m_dBaselinePos, 4);
oWriter.WriteString(L"\" widths=\"");
for (auto& w : m_arSymWidths)
{
@ -490,117 +490,6 @@ namespace NSDocxRenderer
oWriter.WriteString(L"\" />");
oWriter.WriteString(L"</a:r>");
}
void CContText::ToBin(NSWasm::CData& oWriter) const
{
int lCalculatedSpacing = 0;
if (!m_oText.empty())
{
double dSpacing = (m_dWidth - m_oSelectedSizes.dWidth) / (m_oText.length());
dSpacing *= c_dMMToPt * 100;
lCalculatedSpacing = static_cast<LONG>(dSpacing);
}
lCalculatedSpacing -= 15;
const BYTE kPARRUN_TYPE_RUN = 1;
oWriter.StartRecord(kPARRUN_TYPE_RUN);
oWriter.WriteBYTE(kBin_g_nodeAttributeStart);
oWriter.WriteBYTE(0); oWriter.WriteStringUtf16(m_oText.ToStdWString());
oWriter.WriteBYTE(kBin_g_nodeAttributeEnd);
// WriteRecord WriteRunProperties
[&oWriter, this, lCalculatedSpacing] () {
oWriter.StartRecord(0);
oWriter.WriteBYTE(kBin_g_nodeAttributeStart);
oWriter.WriteBYTE(1); oWriter.WriteBool(m_pFontStyle->bBold);
oWriter.WriteBYTE(7); oWriter.WriteBool(m_pFontStyle->bItalic);
BYTE strike = 1;
if (m_bIsDoubleStrikeout) strike = 0;
else if (m_bIsStrikeoutPresent) strike = 2;
oWriter.WriteBYTE(16); oWriter.WriteBYTE(strike);
oWriter.WriteBYTE(15); oWriter.AddSInt(lCalculatedSpacing);
oWriter.WriteBYTE(18); oWriter.WriteBYTE(m_bIsUnderlinePresent ? 13 : 12);
unsigned int font_size = static_cast<unsigned int>(m_pFontStyle->dFontSize) * 100;
const unsigned int min_font_size = 100;
oWriter.WriteBYTE(17); oWriter.AddInt(std::max(font_size, std::max(font_size, min_font_size)));
oWriter.WriteBYTE(2);
if (m_eVertAlignType == eVertAlignType::vatSubscript)
oWriter.AddSInt(-25000);
else if (m_eVertAlignType == eVertAlignType::vatSuperscript)
oWriter.AddSInt(30000);
else
oWriter.AddInt(0);
oWriter.WriteBYTE(kBin_g_nodeAttributeEnd);
// WriteTextFontTypeface
auto WriteTextFontTypeface = [this, &oWriter] (const std::wstring& wsTypeface) {
oWriter.WriteBYTE(kBin_g_nodeAttributeStart);
oWriter.WriteBYTE(3); oWriter.WriteStringUtf16(wsTypeface);
oWriter.WriteBYTE(kBin_g_nodeAttributeEnd);
};
// WriteRecord WriteTextFontTypeface
oWriter.StartRecord(3); WriteTextFontTypeface(m_pFontStyle->wsFontName); oWriter.EndRecord();
oWriter.StartRecord(4); WriteTextFontTypeface(m_pFontStyle->wsFontName); oWriter.EndRecord();
oWriter.StartRecord(5); WriteTextFontTypeface(m_pFontStyle->wsFontName); oWriter.EndRecord();
// WriteUniColor
auto WriteUniColor = [&oWriter] (long color, long alpha) {
BYTE r = reinterpret_cast<BYTE*>(&color)[0];
BYTE g = reinterpret_cast<BYTE*>(&color)[1];
BYTE b = reinterpret_cast<BYTE*>(&color)[2];
oWriter.StartRecord(1); // COLOR_TYPE_SRGB
oWriter.WriteBYTE(kBin_g_nodeAttributeStart);
oWriter.WriteBYTE(0); oWriter.WriteBYTE(r);
oWriter.WriteBYTE(1); oWriter.WriteBYTE(g);
oWriter.WriteBYTE(2); oWriter.WriteBYTE(b);
oWriter.WriteBYTE(kBin_g_nodeAttributeEnd);
// WriteMods (alpha)
oWriter.StartRecord(0);
oWriter.AddInt(1);
oWriter.StartRecord(1);
oWriter.WriteBYTE(kBin_g_nodeAttributeStart);
oWriter.WriteBYTE(0); oWriter.WriteStringUtf16(L"alpha");
oWriter.WriteBYTE(1); oWriter.AddInt(alpha * 100000 / 255);
oWriter.WriteBYTE(kBin_g_nodeAttributeEnd);
oWriter.EndRecord();
oWriter.EndRecord();
oWriter.EndRecord();
};
auto WriteUniFill = [&oWriter, this, &WriteUniColor] () {
oWriter.StartRecord(3); // FILL_TYPE_SOLID
oWriter.StartRecord(0);
WriteUniColor(m_pFontStyle->oBrush.Color1, m_pFontStyle->oBrush.Alpha1);
oWriter.EndRecord();
oWriter.EndRecord();
};
// WriteRecord WriteUniFill
oWriter.StartRecord(1);
WriteUniFill();
oWriter.EndRecord();
// WriteRecord WriteHighlightColor
if (m_bIsHighlightPresent)
{
oWriter.StartRecord(12);
oWriter.WriteBYTE(kBin_g_nodeAttributeStart);
oWriter.WriteBYTE(kBin_g_nodeAttributeEnd);
oWriter.StartRecord(0);
WriteUniColor(m_lHighlightColor, 255);
oWriter.EndRecord();
oWriter.EndRecord();
}
oWriter.EndRecord();
}();
oWriter.EndRecord();
}
bool CContText::IsEqual(const CContText *pCont) const noexcept
{
@ -621,7 +510,7 @@ namespace NSDocxRenderer
bool bIf15 = m_eVertAlignType == eVertAlignType::vatBase && pCont->m_eVertAlignType == eVertAlignType::vatUnknown;
return (bIf1 && bIf2 && bIf3 && bIf4 && bIf5 && bIf6 && bIf7 &&
bIf8 && bIf9 && bIf10 && bIf11 && bIf12 && (bIf13 || bIf14 || bIf15));
bIf8 && bIf9 && bIf10 && bIf11 && bIf12 && (bIf13 || bIf14 || bIf15));
}
UINT CContText::GetNumberOfFeatures() const noexcept
@ -640,11 +529,10 @@ namespace NSDocxRenderer
bool CContText::IsDuplicate(CContText* pCont, eVerticalCrossingType eVType, eHorizontalCrossingType eHType) const noexcept
{
return m_oText == pCont->m_oText &&
eVType == eVerticalCrossingType::vctDublicate &&
(eHType == eHorizontalCrossingType::hctDublicate ||
eHType == eHorizontalCrossingType::hctCurrentLeftOfNext ||
eHType == eHorizontalCrossingType::hctCurrentRightOfNext ||
eHType == eHorizontalCrossingType::hctLeftAndRightBordersMatch);
eVType == eVerticalCrossingType::vctDublicate &&
(eHType == eHorizontalCrossingType::hctDublicate ||
eHType == eHorizontalCrossingType::hctCurrentLeftOfNext ||
eHType == eHorizontalCrossingType::hctCurrentRightOfNext);
}
bool CContText::IsOnlySpaces() const
@ -667,7 +555,7 @@ namespace NSDocxRenderer
void CContText::AddTextBack(const NSStringUtils::CStringUTF32& oText, const std::vector<double>& arSymWidths)
{
bool is_space_twice = m_oText.at(m_oText.length() - 1) == c_SPACE_SYM &&
oText.at(0) == c_SPACE_SYM;
oText.at(0) == c_SPACE_SYM;
for (size_t i = 0; i < arSymWidths.size(); ++i)
{
@ -772,10 +660,10 @@ namespace NSDocxRenderer
}
bool CContText::CheckFontEffects
(std::shared_ptr<CContText>& pFirstCont,
std::shared_ptr<CContText>& pSecondCont,
eVerticalCrossingType eVType,
eHorizontalCrossingType eHType)
(std::shared_ptr<CContText>& pFirstCont,
std::shared_ptr<CContText>& pSecondCont,
eVerticalCrossingType eVType,
eHorizontalCrossingType eHType)
{
//Условие пересечения по вертикали
bool bIf1 = eVType == eVerticalCrossingType::vctCurrentAboveNext; //текущий cont выше
@ -855,28 +743,28 @@ namespace NSDocxRenderer
}
bool CContText::CheckVertAlignTypeBetweenConts
(std::shared_ptr<CContText> pFirstCont,
std::shared_ptr<CContText> pSecondCont,
eVerticalCrossingType eVType,
eHorizontalCrossingType eHType)
(std::shared_ptr<CContText> pFirstCont,
std::shared_ptr<CContText> pSecondCont,
eVerticalCrossingType eVType,
eHorizontalCrossingType eHType)
{
bool bIf1 = eVType == eVerticalCrossingType::vctCurrentAboveNext ||
eVType == eVerticalCrossingType::vctCurrentInsideNext;
eVType == eVerticalCrossingType::vctCurrentInsideNext;
bool bIf2 = eVType == eVerticalCrossingType::vctCurrentBelowNext;
bool bIf3 = (eHType == eHorizontalCrossingType::hctNoCrossingCurrentLeftOfNext ||
eHType == eHorizontalCrossingType::hctCurrentLeftOfNext) &&
fabs(pFirstCont->m_dRight - pSecondCont->m_dLeft) < c_dTHE_STRING_X_PRECISION_MM * 3;
eHType == eHorizontalCrossingType::hctCurrentLeftOfNext) &&
fabs(pFirstCont->m_dRight - pSecondCont->m_dLeft) < c_dTHE_STRING_X_PRECISION_MM * 3;
bool bIf4 = (eHType == eHorizontalCrossingType::hctNoCrossingCurrentRightOfNext ||
eHType == eHorizontalCrossingType::hctCurrentRightOfNext) &&
fabs(pFirstCont->m_dLeft - pSecondCont->m_dRight) < c_dTHE_STRING_X_PRECISION_MM * 3;
eHType == eHorizontalCrossingType::hctCurrentRightOfNext) &&
fabs(pFirstCont->m_dLeft - pSecondCont->m_dRight) < c_dTHE_STRING_X_PRECISION_MM * 3;
//Размеры шрифта должны бать разными
bool bIf5 = pFirstCont->m_pFontStyle->dFontSize * 0.8 > pSecondCont->m_pFontStyle->dFontSize;
bool bIf6 = pFirstCont->m_pFontStyle->dFontSize < pSecondCont->m_pFontStyle->dFontSize * 0.8;
bool bIf5 = pFirstCont->m_pFontStyle->dFontSize * 0.7 > pSecondCont->m_pFontStyle->dFontSize;
bool bIf6 = pFirstCont->m_pFontStyle->dFontSize < pSecondCont->m_pFontStyle->dFontSize * 0.7;
if (bIf3 || bIf4)
{
@ -886,7 +774,7 @@ namespace NSDocxRenderer
pSecondCont->m_pCont = pFirstCont;
pFirstCont->m_eVertAlignType = eVertAlignType::vatBase;
pFirstCont->m_pCont = pSecondCont;
pFirstCont->m_bPossibleHorSplit = false;
pFirstCont->m_bPossibleSplit = false;
return true;
}
else if (bIf2 && bIf5)
@ -895,7 +783,7 @@ namespace NSDocxRenderer
pSecondCont->m_pCont = pFirstCont;
pFirstCont->m_eVertAlignType = eVertAlignType::vatBase;
pFirstCont->m_pCont = pSecondCont;
pFirstCont->m_bPossibleHorSplit = false;
pFirstCont->m_bPossibleSplit = false;
return true;
}
else if (bIf1 && bIf6)
@ -904,7 +792,7 @@ namespace NSDocxRenderer
pFirstCont->m_pCont = pSecondCont;
pSecondCont->m_eVertAlignType = eVertAlignType::vatBase;
pSecondCont->m_pCont = pFirstCont;
pSecondCont->m_bPossibleHorSplit = false;
pSecondCont->m_bPossibleSplit = false;
return true;
}
else if (bIf2 && bIf6)
@ -913,7 +801,7 @@ namespace NSDocxRenderer
pFirstCont->m_pCont = pSecondCont;
pSecondCont->m_eVertAlignType = eVertAlignType::vatBase;
pSecondCont->m_pCont = pFirstCont;
pSecondCont->m_bPossibleHorSplit = false;
pSecondCont->m_bPossibleSplit = false;
return true;
}
}
@ -936,15 +824,15 @@ namespace NSDocxRenderer
{
// more symbols of delims
bool is_bullet =
(cSym == 0x2022) || (cSym == 0x2023) || (cSym == 0x2043) || (cSym == 0x204C) ||
(cSym == 0x204D) || (cSym == 0x2219) || (cSym == 0x25CB) || (cSym == 0x25CF) ||
(cSym == 0x25D8) || (cSym == 0x25E6) || (cSym == 0x2619) || (cSym == 0x2765) ||
(cSym == 0x2767) || (cSym == 0x29BE) || (cSym == 0x29BF) || (cSym == 0x25C9);
(cSym == 0x2022) || (cSym == 0x2023) || (cSym == 0x2043) || (cSym == 0x204C) ||
(cSym == 0x204D) || (cSym == 0x2219) || (cSym == 0x25CB) || (cSym == 0x25CF) ||
(cSym == 0x25D8) || (cSym == 0x25E6) || (cSym == 0x2619) || (cSym == 0x2765) ||
(cSym == 0x2767) || (cSym == 0x29BE) || (cSym == 0x29BF) || (cSym == 0x25C9);
bool is_another =
(cSym == 0xB7) || (cSym == 0xA7) || (cSym == 0xF076) || (cSym == 0x2013) ||
(cSym == 0x2713) || (cSym == 0x2714) || (cSym == 0x2756) || (cSym == 0x25C6) ||
(cSym == 0x25C7) || (cSym == 0x25C8);
(cSym == 0xB7) || (cSym == 0xA7) || (cSym == 0xF076) || (cSym == 0x2013) ||
(cSym == 0x2713) || (cSym == 0x2714) || (cSym == 0x2756) || (cSym == 0x25C6) ||
(cSym == 0x25C7) || (cSym == 0x25C8);
return is_bullet || is_another;
}
@ -964,9 +852,9 @@ namespace NSDocxRenderer
bool CContText::IsUnicodeSymbol(uint32_t cSym )
{
bool is_unicode =
(( 0x0009 == cSym) || (0x000A == cSym ) || (0x000D == cSym ) ||
(( 0x0020 <= cSym) && (0xD7FF >= cSym )) || ((0xE000 <= cSym) && (cSym <= 0xFFFD )) ||
(( 0x10000 <= cSym) && cSym));
(( 0x0009 == cSym) || (0x000A == cSym ) || (0x000D == cSym ) ||
(( 0x0020 <= cSym) && (0xD7FF >= cSym )) || ((0xE000 <= cSym) && (cSym <= 0xFFFD )) ||
(( 0x10000 <= cSym) && cSym));
return is_unicode;
}
@ -981,42 +869,35 @@ namespace NSDocxRenderer
}
CContTextBuilder::CContTextBuilder(CFontStyleManager* pFontStyleManager, CFontSelector* pFontSelector) :
m_pFontStyleManager(pFontStyleManager), m_pFontSelector(pFontSelector)
m_pFontStyleManager(pFontStyleManager), m_pFontSelector(pFontSelector)
{}
std::vector<CContTextBuilder::cont_ptr_t> CContTextBuilder::GetConts()
{
return std::move(m_arConts);
m_pCurrCont = nullptr;
}
std::vector<CContTextBuilder::cont_ptr_t> CContTextBuilder::GetDiacs()
{
return std::move(m_arDiacs);
m_pCurrCont = nullptr;
}
void CContTextBuilder::AddUnicode(
double dTop,
double dBot,
double dLeft,
double dRight,
const NSStructures::CFont& oFont,
const NSStructures::CBrush& oBrush,
CFontManager* pFontManager,
const NSStringUtils::CStringUTF32& oText,
bool bForcedBold,
bool bUseDefaultFont,
bool bWriteStyleRaw)
double dTop,
double dBot,
double dLeft,
double dRight,
const NSStructures::CFont& oFont,
const NSStructures::CBrush& oBrush,
CFontManager* pFontManager,
const NSStringUtils::CStringUTF32& oText,
bool bForcedBold,
bool bUseDefaultFont,
bool bWriteStyleRaw)
{
double dWidth = dRight - dLeft;
double dHeight = dBot - dTop;
// if new text is close to current cont
if (m_pCurrCont != nullptr &&
fabs(m_pCurrCont->m_dBot - dBot) < c_dTHE_SAME_STRING_Y_PRECISION_MM &&
m_oPrevFont.IsEqual2(&oFont) &&
m_oPrevBrush.IsEqual(&oBrush) && !(
oText.length() == 1 && CContText::IsUnicodeDiacriticalMark(oText.at(0))))
fabs(m_pCurrCont->m_dBaselinePos - dBot) < c_dTHE_SAME_STRING_Y_PRECISION_MM &&
m_oPrevFont.IsEqual2(&oFont) &&
m_oPrevBrush.IsEqual(&oBrush))
{
double avg_width = dWidth / oText.length();
@ -1026,9 +907,9 @@ namespace NSDocxRenderer
double avg_space_width = m_pCurrCont->m_pFontStyle->GetAvgSpaceWidth();
double space_width =
avg_space_width != 0.0 ?
avg_space_width * c_dAVERAGE_SPACE_WIDTH_COEF :
m_pCurrCont->CalculateSpace() * c_dSPACE_WIDTH_COEF;
avg_space_width != 0.0 ?
avg_space_width * c_dAVERAGE_SPACE_WIDTH_COEF :
m_pCurrCont->CalculateSpace() * c_dSPACE_WIDTH_COEF;
bool is_added = false;
@ -1059,8 +940,8 @@ namespace NSDocxRenderer
if (is_added)
{
m_pCurrCont->m_dTop = std::min(m_pCurrCont->m_dTop, dTop);
m_pCurrCont->m_dBot = std::max(m_pCurrCont->m_dBot, dBot);
m_pCurrCont->m_dHeight = m_pCurrCont->m_dBot - m_pCurrCont->m_dTop;
m_pCurrCont->m_dBaselinePos = std::max(m_pCurrCont->m_dBaselinePos, dBot);
m_pCurrCont->m_dHeight = m_pCurrCont->m_dBaselinePos - m_pCurrCont->m_dTop;
m_pCurrCont->m_dWidth = m_pCurrCont->m_dRight - m_pCurrCont->m_dLeft;
return;
}
@ -1071,19 +952,19 @@ namespace NSDocxRenderer
const auto& oMetrics = pFontManager->GetFontMetrics();
m_pFontSelector->SelectFont(oParams, oMetrics, oText);
pCont->m_dBot = dBot;
pCont->m_dTop = dTop;
pCont->m_dHeight = dHeight;
pCont->m_dLeft = dLeft;
pCont->m_dBaselinePos = dBot;
pCont->m_dTop = dTop;
pCont->m_dHeight = dHeight;
pCont->m_dLeft = dLeft;
// первичное получение стиля для текущего символа
// при дальнейшем анализе может измениться
pCont->m_pFontStyle = m_pFontStyleManager->GetOrAddFontStyle(
oBrush,
m_pFontSelector->GetSelectedName(),
oFont.Size,
m_pFontSelector->IsSelectedItalic(),
m_pFontSelector->IsSelectedBold() || bForcedBold);
oBrush,
m_pFontSelector->GetSelectedName(),
oFont.Size,
m_pFontSelector->IsSelectedItalic(),
m_pFontSelector->IsSelectedBold() || bForcedBold);
// just in case if oText contains more than 1 symbol
std::vector<double> ar_widths;
@ -1104,8 +985,8 @@ namespace NSDocxRenderer
double em_height = oMetrics.dEmHeight;
double ratio = font_size / em_height * c_dPtToMM;
pCont->m_dTopWithAscent = pCont->m_dBot - (oMetrics.dAscent * ratio) - oMetrics.dBaselineOffset;
pCont->m_dBotWithDescent = pCont->m_dBot + (oMetrics.dDescent * ratio) - oMetrics.dBaselineOffset;
pCont->m_dTopWithAscent = pCont->m_dBaselinePos - (oMetrics.dAscent * ratio) - oMetrics.dBaselineOffset;
pCont->m_dBotWithDescent = pCont->m_dBaselinePos + (oMetrics.dDescent * ratio) - oMetrics.dBaselineOffset;
pCont->m_dSpaceWidthMM = pFontManager->GetSpaceWidthMM();
pCont->m_wsOriginFontName = oFont.Name;
@ -1124,31 +1005,10 @@ namespace NSDocxRenderer
pCont->m_oSelectedFont.Italic = m_pFontSelector->IsSelectedItalic();
}
pCont->m_bWriteStyleRaw = bWriteStyleRaw;
if (pCont->IsDiacritical())
{
m_arDiacs.push_back(std::move(pCont));
}
else
{
m_arConts.push_back(pCont);
}
m_arConts.push_back(pCont);
m_pCurrCont = pCont;
m_oPrevFont = oFont;
m_oPrevBrush = oBrush;
}
void CContTextBuilder::NullCurrCont()
{
m_pCurrCont = nullptr;
}
void CContTextBuilder::Clear()
{
m_pCurrCont = nullptr;
m_arConts.clear();
m_arDiacs.clear();
m_oPrevFont.SetDefaultParams();
m_oPrevBrush.SetDefaultParams();
}
}

View File

@ -2,15 +2,16 @@
#include "../../../../DesktopEditor/common/StringBuilder.h"
#include "BaseItem.h"
#include "Shape.h"
#include "../managers/FontManager.h"
#include "../managers/FontStyleManager.h"
#include "../managers//FontStyleManager.h"
#include "../styles/FontStyle.h"
#include "../../resources/Constants.h"
#include "../../resources/LinesTable.h"
namespace NSDocxRenderer
{
class CShape;
enum class eVertAlignType
{
vatUnknown,
@ -31,7 +32,7 @@ namespace NSDocxRenderer
CSelectedSizes& operator=(const CSelectedSizes& oSelectedSizes);
};
class CContText : public CBaseItem, public IOoxmlItem
class CContText : public CBaseItem
{
public:
// utils
@ -75,17 +76,16 @@ namespace NSDocxRenderer
bool m_bIsAddBrEnd{false};
bool m_bWriteStyleRaw{false};
bool m_bPossibleHorSplit{false};
bool m_bPossibleSplit{false};
CContText() = default;
CContText(CFontManager* pManager) : m_pManager(pManager) {}
CContText(const CContText& rCont);
virtual ~CContText();
virtual void Clear();
virtual void Clear() override final;
virtual void ToXml(NSStringUtils::CStringBuilder& oWriter) const override final;
virtual void ToXmlPptx(NSStringUtils::CStringBuilder& oWriter) const override final;
virtual void ToBin(NSWasm::CData& oWriter) const override final;
virtual eVerticalCrossingType GetVerticalCrossingType(const CContText* pItem) const noexcept;
// calc sizes in selected font (uses m_oSelectedFont & m_pManager)
@ -123,16 +123,16 @@ namespace NSDocxRenderer
// check font effect and delete not needed cont
// return true if was deleted
static bool CheckFontEffects
(std::shared_ptr<CContText>& pFirstCont,
std::shared_ptr<CContText>& pSecondCont,
eVerticalCrossingType eVType,
eHorizontalCrossingType eHType);
(std::shared_ptr<CContText>& pFirstCont,
std::shared_ptr<CContText>& pSecondCont,
eVerticalCrossingType eVType,
eHorizontalCrossingType eHType);
static bool CheckVertAlignTypeBetweenConts
(std::shared_ptr<CContText> pFirstCont,
std::shared_ptr<CContText> pSecondCont,
eVerticalCrossingType eVType,
eHorizontalCrossingType eHType);
(std::shared_ptr<CContText> pFirstCont,
std::shared_ptr<CContText> pSecondCont,
eVerticalCrossingType eVType,
eHorizontalCrossingType eHType);
static bool IsUnicodeRtl(uint32_t cSym);
static bool IsUnicodeBullet(uint32_t cSym);
@ -157,34 +157,24 @@ namespace NSDocxRenderer
CContTextBuilder(CFontStyleManager* pFontStyleManager, CFontSelector* pFontSelector);
~CContTextBuilder() = default;
// after call CContTextBuilder conts is empty
// after call CContTextBuilder is empty
std::vector<cont_ptr_t> GetConts();
// after call CContTextBuilder diacs is empty
std::vector<cont_ptr_t> GetDiacs();
void AddUnicode(
double dTop,
double dBot,
double dLeft,
double dRight,
const NSStructures::CFont& oFont,
const NSStructures::CBrush& oBrush,
CFontManager* pFontManager,
const NSStringUtils::CStringUTF32& oText,
bool bForcedBold = false,
bool bUseDefaultFont = false,
bool bWriteStyleRaw = false);
void NullCurrCont();
void Clear();
double dTop,
double dBot,
double dLeft,
double dRight,
const NSStructures::CFont& oFont,
const NSStructures::CBrush& oBrush,
CFontManager* pFontManager,
const NSStringUtils::CStringUTF32& oText,
bool bForcedBold = false,
bool bUseDefaultFont = false,
bool bWriteStyleRaw = false);
private:
std::vector<cont_ptr_t> m_arConts;
std::vector<cont_ptr_t> m_arDiacs;
cont_ptr_t m_pCurrCont {nullptr};
NSStructures::CFont m_oPrevFont;
NSStructures::CBrush m_oPrevBrush;

View File

@ -11,7 +11,7 @@ namespace NSDocxRenderer
void CParagraph::Clear()
{
m_arTextLines.clear();
m_arLines.clear();
}
void CParagraph::ToXml(NSStringUtils::CStringBuilder& oWriter) const
@ -20,7 +20,7 @@ namespace NSDocxRenderer
oWriter.WriteString(L"<w:pPr>");
// styles
if (!m_wsStyleId.empty()) oWriter.WriteString(L"<w:pStyle w:val=\"" + m_wsStyleId + L"\"/>");
if(!m_wsStyleId.empty()) oWriter.WriteString(L"<w:pStyle w:val=\"" + m_wsStyleId + L"\"/>");
oWriter.WriteString(L"<w:spacing");
@ -105,7 +105,7 @@ namespace NSDocxRenderer
}
oWriter.WriteString(L"</w:pPr>");
for(const auto& line : m_arTextLines)
for(const auto& line : m_arLines)
if(line)
line->ToXml(oWriter);
oWriter.WriteString(L"</w:p>");
@ -135,28 +135,14 @@ namespace NSDocxRenderer
break;
}
oWriter.WriteString(L"\" ");
oWriter.WriteString(L"\"");
if (m_bIsNeedFirstLineIndent)
{
oWriter.WriteString(L" indent=\" ");
oWriter.WriteString(L" indent=\"");
oWriter.AddInt(static_cast<int>(m_dFirstLine * c_dMMToEMU));
oWriter.WriteString(L"\"");
}
if (m_dLeftBorder > 0)
{
oWriter.WriteString(L" marL=\" ");
oWriter.AddInt(static_cast<int>(m_dLeftBorder * c_dMMToEMU));
oWriter.WriteString(L"\"");
}
if (m_dRightBorder > 0)
{
oWriter.WriteString(L" marR=\"");
oWriter.AddInt(static_cast<int>(m_dRightBorder * c_dMMToEMU));
oWriter.WriteString(L"\"");
}
oWriter.WriteString(L">");
oWriter.WriteString(L"<a:spcBef>");
@ -165,9 +151,10 @@ namespace NSDocxRenderer
oWriter.WriteString(L"\"/>");
oWriter.WriteString(L"</a:spcBef>");
oWriter.WriteString(L"<a:spcAft>");
oWriter.WriteString(L"<a:spcPts val=\"");
oWriter.AddInt(static_cast<int>(m_dSpaceAfter * c_dMMToPt * 100));
oWriter.AddInt(static_cast<int>(m_dSpaceBefore * c_dMMToPt * 100));
oWriter.WriteString(L"\"/>");
oWriter.WriteString(L"</a:spcAft>");
@ -178,113 +165,20 @@ namespace NSDocxRenderer
oWriter.WriteString(L"</a:lnSpc>");
oWriter.WriteString(L"</a:pPr>");
for(const auto& line : m_arTextLines)
for(const auto& line : m_arLines)
if(line)
line->ToXmlPptx(oWriter);
oWriter.WriteString(L"</a:p>");
}
void CParagraph::ToBin(NSWasm::CData& oWriter) const
{
// WriteRecord WriteTextParagraphPr
[this, &oWriter] () {
oWriter.StartRecord(0);
oWriter.WriteBYTE(kBin_g_nodeAttributeStart);
oWriter.WriteBYTE(0);
switch (m_eTextAlignmentType)
{
case tatByCenter:
oWriter.WriteBYTE(0);
break;
case tatByRight:
oWriter.WriteBYTE(5);
break;
case tatByWidth:
oWriter.WriteBYTE(2);
break;
case tatByLeft: // fallthrough
case tatUnknown: // fallthrough
default:
oWriter.WriteBYTE(4);
break;
}
// marL
if (m_dLeftBorder > 0)
{
oWriter.WriteBYTE(8);
oWriter.AddSInt(static_cast<int>(m_dLeftBorder * c_dMMToEMU));
}
// marR
if (m_dRightBorder > 0)
{
oWriter.WriteBYTE(9);
oWriter.AddSInt(static_cast<int>(m_dRightBorder * c_dMMToEMU));
}
// indent
if (m_bIsNeedFirstLineIndent)
{
oWriter.WriteBYTE(5);
oWriter.AddSInt(static_cast<int>(m_dFirstLine * c_dMMToEMU));
}
oWriter.WriteBYTE(kBin_g_nodeAttributeEnd);
const int max_value = 158400;
// line spacing
oWriter.StartRecord(0);
oWriter.WriteBYTE(kBin_g_nodeAttributeStart);
int height_value = static_cast<int>(m_dLineHeight * c_dMMToPt * 100);
if (fabs(height_value) > max_value)
height_value > 0 ? height_value = max_value : height_value = -max_value;
oWriter.WriteBYTE(1); oWriter.AddSInt(static_cast<int>(height_value));
oWriter.WriteBYTE(kBin_g_nodeAttributeEnd);
oWriter.EndRecord();
// space after
oWriter.StartRecord(1);
oWriter.WriteBYTE(kBin_g_nodeAttributeStart);
int after_value = static_cast<int>(m_dSpaceAfter * c_dMMToPt * 100);
if (fabs(after_value) > max_value)
after_value > 0 ? after_value = max_value : after_value = -max_value;
oWriter.WriteBYTE(1); oWriter.AddSInt(static_cast<int>(after_value));
oWriter.WriteBYTE(kBin_g_nodeAttributeEnd);
oWriter.EndRecord();
// space before
oWriter.StartRecord(2);
oWriter.WriteBYTE(kBin_g_nodeAttributeStart);
int before_value = static_cast<int>(m_dSpaceBefore * c_dMMToPt * 100);
if (fabs(before_value) > max_value)
before_value > 0 ? before_value = max_value : before_value = -max_value;
oWriter.WriteBYTE(1); oWriter.AddSInt(static_cast<int>(before_value));
oWriter.WriteBYTE(kBin_g_nodeAttributeEnd);
oWriter.EndRecord();
oWriter.EndRecord();
}();
oWriter.StartRecord(2);
unsigned int count = 0;
for (const auto& text_line : m_arTextLines)
count += text_line->m_arConts.size();
oWriter.AddInt(count);
for (const auto& text_line : m_arTextLines)
text_line->ToBin(oWriter);
oWriter.EndRecord();
}
void CParagraph::RemoveHighlightColor()
{
if (!m_bIsShadingPresent)
return;
for(size_t i = 0; i < m_arTextLines.size(); ++i)
for(size_t i = 0; i < m_arLines.size(); ++i)
{
auto& pLine = m_arTextLines[i];
auto& pLine = m_arLines[i];
if (pLine || pLine->m_pDominantShape)
{
for (size_t j = 0; j < pLine->m_arConts.size(); ++j)
@ -300,9 +194,9 @@ namespace NSDocxRenderer
void CParagraph::MergeLines()
{
for(size_t i = 0; i < m_arTextLines.size() - 1; ++i)
for(size_t i = 0; i < m_arLines.size() - 1; ++i)
{
auto pLine = m_arTextLines[i];
auto pLine = m_arLines[i];
auto pLastCont = pLine->m_arConts.back();
size_t iNumConts = pLine->m_arConts.size() - 1;
@ -312,7 +206,7 @@ namespace NSDocxRenderer
auto text = pLastCont->GetText();
auto last_sym = text[text.length() - 1];
if (last_sym != c_SPACE_SYM && m_arTextLines.size() != 1)
if (last_sym != c_SPACE_SYM && m_arLines.size() != 1)
pLastCont->AddSymBack(c_SPACE_SYM, 0);
}
}

View File

@ -4,7 +4,7 @@
namespace NSDocxRenderer
{
class CParagraph : public CBaseItem, public IOoxmlItem
class CParagraph : public CBaseItem
{
public:
enum TextAlignmentType
@ -31,16 +31,15 @@ namespace NSDocxRenderer
double m_dSpaceAfter {0.0}; // в shape по умолчанию выставляется 8pt, если отсутсвует w:after
double m_dLineHeight {0.0};
std::vector<std::shared_ptr<CTextLine>> m_arTextLines;
std::vector<std::shared_ptr<CTextLine>> m_arLines;
std::wstring m_wsStyleId;
public:
CParagraph() : CBaseItem() {}
virtual ~CParagraph();
virtual void Clear();
virtual void Clear() override final;
virtual void ToXml(NSStringUtils::CStringBuilder& oWriter) const override final;
virtual void ToXmlPptx(NSStringUtils::CStringBuilder& oWriter) const override final;
virtual void ToBin(NSWasm::CData& oWriter) const override final;
void RemoveHighlightColor();
void MergeLines();

View File

@ -25,7 +25,7 @@ namespace NSDocxRenderer
}
CShape::CShape(std::shared_ptr<CImageInfo> pInfo, const std::wstring& strDstMedia) :
m_strDstMedia(strDstMedia), m_pImageInfo(pInfo)
m_strDstMedia(strDstMedia), m_pImageInfo(pInfo)
{
m_nRelativeHeight = m_gRelativeHeight;
m_gRelativeHeight += c_iStandartRelativeHeight;
@ -94,7 +94,7 @@ namespace NSDocxRenderer
if (m_dHeight < 0.0001)
m_dHeight = 0.0001;
m_dBot = m_dTop + m_dHeight;
m_dBaselinePos = m_dTop + m_dHeight;
m_dRight = m_dLeft + m_dWidth;
}
@ -110,40 +110,40 @@ namespace NSDocxRenderer
double dHorNearby = 30;
double dVerNearby = 30;
if (
// только для фигур
(pShape->m_eGraphicsType == eGraphicsType::gtComplicatedFigure ||
pShape->m_eGraphicsType == eGraphicsType::gtRectangle) &&
if(
// только для фигур
(pShape->m_eGraphicsType == eGraphicsType::gtComplicatedFigure ||
pShape->m_eGraphicsType == eGraphicsType::gtRectangle) &&
(this->m_eGraphicsType == eGraphicsType::gtComplicatedFigure ||
this->m_eGraphicsType == eGraphicsType::gtRectangle) &&
(this->m_eGraphicsType == eGraphicsType::gtComplicatedFigure ||
this->m_eGraphicsType == eGraphicsType::gtRectangle) &&
// все совпадает
pShape->m_eType == this->m_eType &&
pShape->m_oPen.IsEqual(&m_oPen) &&
pShape->m_oBrush.IsEqual(&m_oBrush) &&
pShape->m_bIsNoFill == m_bIsNoFill &&
pShape->m_bIsNoStroke == m_bIsNoStroke &&
// все совпадает
pShape->m_eType == this->m_eType &&
pShape->m_oPen.IsEqual(&m_oPen) &&
pShape->m_oBrush.IsEqual(&m_oBrush) &&
pShape->m_bIsNoFill == m_bIsNoFill &&
pShape->m_bIsNoStroke == m_bIsNoStroke &&
// не картинка
pShape->m_pImageInfo == nullptr &&
this->m_pImageInfo == nullptr &&
// не картинка
pShape->m_pImageInfo == nullptr &&
this->m_pImageInfo == nullptr &&
// недалеко друг от друга по горизонтали
(fabs(pShape->m_dRight - this->m_dLeft) < dHorNearby ||
fabs(pShape->m_dLeft - this->m_dRight) < dHorNearby ||
// недалеко друг от друга по горизонтали
(fabs(pShape->m_dRight - this->m_dLeft) < dHorNearby ||
fabs(pShape->m_dLeft - this->m_dRight) < dHorNearby ||
// друг в друге тоже учитываем
fabs(pShape->m_dRight - this->m_dRight) < dHorNearby ||
fabs(pShape->m_dLeft - this->m_dLeft) < dHorNearby) &&
// друг в друге тоже учитываем
fabs(pShape->m_dRight - this->m_dRight) < dHorNearby ||
fabs(pShape->m_dLeft - this->m_dLeft) < dHorNearby) &&
// недалеко друг от друга по вертикали
(fabs(pShape->m_dBot - this->m_dTop) < dVerNearby ||
fabs(pShape->m_dTop - this->m_dBot) < dVerNearby ||
// недалеко друг от друга по вертикали
(fabs(pShape->m_dBaselinePos - this->m_dTop) < dVerNearby ||
fabs(pShape->m_dTop - this->m_dBaselinePos) < dVerNearby ||
// друг в друге
fabs(pShape->m_dBot - this->m_dBot) < dVerNearby ||
fabs(pShape->m_dTop - this->m_dTop) < dVerNearby))
// друг в друге
fabs(pShape->m_dBaselinePos - this->m_dBaselinePos) < dVerNearby ||
fabs(pShape->m_dTop - this->m_dTop) < dVerNearby))
{
RecalcWithNewItem(pShape.get());
m_oVector.Join(std::move(pShape->m_oVector));
@ -327,7 +327,7 @@ namespace NSDocxRenderer
return;
if (!pFirstShape->IsItFitLine() || !pSecondShape->IsItFitLine() || !pFirstShape->IsCorrelated(pSecondShape) ||
fabs(pFirstShape->m_dHeight - pSecondShape->m_dHeight) > c_dGRAPHICS_ERROR_IN_LINES_MM)
fabs(pFirstShape->m_dHeight - pSecondShape->m_dHeight) > c_dGRAPHICS_ERROR_IN_LINES_MM)
{
return; // линия должна быть одного размера по высоте
}
@ -360,8 +360,8 @@ namespace NSDocxRenderer
}
else if (fabs(pFirstShape->m_dTop - pSecondShape->m_dTop) < c_dGRAPHICS_ERROR_IN_LINES_MM * 5 &&
fabs(pFirstShape->m_dWidth - pSecondShape->m_dWidth) < c_dGRAPHICS_ERROR_IN_LINES_MM &&
fabs(pFirstShape->m_dLeft - pSecondShape->m_dLeft) < c_dGRAPHICS_ERROR_IN_LINES_MM)
fabs(pFirstShape->m_dWidth - pSecondShape->m_dWidth) < c_dGRAPHICS_ERROR_IN_LINES_MM &&
fabs(pFirstShape->m_dLeft - pSecondShape->m_dLeft) < c_dGRAPHICS_ERROR_IN_LINES_MM)
{
// условие первого определения
if (pFirstShape->m_eSimpleLineType == eSimpleLineType::sltHLongDash && pSecondShape->m_eSimpleLineType == eSimpleLineType::sltHLongDash)
@ -450,14 +450,14 @@ namespace NSDocxRenderer
if (pSecondShape->m_eSimpleLineType == eSimpleLineType::sltHDot)
{
if ((pFirstShape->m_eLineType == eLineType::ltUnknown || pFirstShape->m_eLineType == eLineType::ltDotted ||
pFirstShape->m_eLineType == eLineType::ltDottedHeavy) && pSecondShape->m_eLineType == eLineType::ltUnknown)
pFirstShape->m_eLineType == eLineType::ltDottedHeavy) && pSecondShape->m_eLineType == eLineType::ltUnknown)
{
pFirstShape->m_eLineType = pFirstShape->m_dHeight > 0.3 ? eLineType::ltDottedHeavy : eLineType::ltDotted;
passed = true;
}
else if ((pFirstShape->m_eLineType == eLineType::ltDotDash || pFirstShape->m_eLineType == eLineType::ltDashDotHeavy ||
pFirstShape->m_eLineType == eLineType::ltDotDotDash || pFirstShape->m_eLineType == eLineType::ltDashDotDotHeavy) &&
pSecondShape->m_eLineType == eLineType::ltUnknown)
pFirstShape->m_eLineType == eLineType::ltDotDotDash || pFirstShape->m_eLineType == eLineType::ltDashDotDotHeavy) &&
pSecondShape->m_eLineType == eLineType::ltUnknown)
{
pFirstShape->m_eLineType = pFirstShape->m_dHeight > 0.3 ? eLineType::ltDashDotDotHeavy : eLineType::ltDotDotDash;
pFirstShape->m_eSimpleLineType = eSimpleLineType::sltHDot;
@ -467,13 +467,13 @@ namespace NSDocxRenderer
else if (pSecondShape->m_eSimpleLineType == eSimpleLineType::sltHDash)
{
if ((pFirstShape->m_eLineType == eLineType::ltDotDash || pFirstShape->m_eLineType == eLineType::ltDashDotHeavy) &&
pSecondShape->m_eLineType == eLineType::ltUnknown)
pSecondShape->m_eLineType == eLineType::ltUnknown)
{
pFirstShape->m_eSimpleLineType = eSimpleLineType::sltHDash;
passed = true;
}
else if ((pFirstShape->m_eLineType == eLineType::ltDotDotDash || pFirstShape->m_eLineType == eLineType::ltDashDotDotHeavy) &&
pSecondShape->m_eLineType == eLineType::ltUnknown)
pSecondShape->m_eLineType == eLineType::ltUnknown)
{
pFirstShape->m_eSimpleLineType = eSimpleLineType::sltHDash;
passed = true;
@ -485,13 +485,13 @@ namespace NSDocxRenderer
if (pSecondShape->m_eSimpleLineType == eSimpleLineType::sltHDash)
{
if ((pFirstShape->m_eLineType == eLineType::ltUnknown || pFirstShape->m_eLineType == eLineType::ltDash ||
pFirstShape->m_eLineType == eLineType::ltDashedHeavy) && pSecondShape->m_eLineType == eLineType::ltUnknown)
pFirstShape->m_eLineType == eLineType::ltDashedHeavy) && pSecondShape->m_eLineType == eLineType::ltUnknown)
{
pFirstShape->m_eLineType = pFirstShape->m_dHeight > 0.3 ? eLineType::ltDashedHeavy : eLineType::ltDash;
passed = true;
}
else if ((pFirstShape->m_eLineType == eLineType::ltDotDash || pFirstShape->m_eLineType == eLineType::ltDashDotHeavy) &&
pSecondShape->m_eLineType == eLineType::ltUnknown)
pSecondShape->m_eLineType == eLineType::ltUnknown)
{
passed = true;
}
@ -499,14 +499,14 @@ namespace NSDocxRenderer
else if (pSecondShape->m_eSimpleLineType == eSimpleLineType::sltHDot)
{
if ((pFirstShape->m_eLineType == eLineType::ltUnknown || pFirstShape->m_eLineType == eLineType::ltDotDash ||
pFirstShape->m_eLineType == eLineType::ltDashDotHeavy) && pSecondShape->m_eLineType == eLineType::ltUnknown)
pFirstShape->m_eLineType == eLineType::ltDashDotHeavy) && pSecondShape->m_eLineType == eLineType::ltUnknown)
{
pFirstShape->m_eLineType = pFirstShape->m_dHeight > 0.3 ? eLineType::ltDashDotHeavy : eLineType::ltDotDash;
pFirstShape->m_eSimpleLineType = eSimpleLineType::sltHDot;
passed = true;
}
else if ((pFirstShape->m_eLineType == eLineType::ltDotDotDash || pFirstShape->m_eLineType == eLineType::ltDashDotDotHeavy) &&
pSecondShape->m_eLineType == eLineType::ltUnknown)
pSecondShape->m_eLineType == eLineType::ltUnknown)
{
pFirstShape->m_eSimpleLineType = eSimpleLineType::sltHDot;
passed = true;
@ -516,13 +516,13 @@ namespace NSDocxRenderer
case eSimpleLineType::sltHLongDash:
if (fabs(pFirstShape->m_dLeft +pFirstShape->m_dWidth - pSecondShape->m_dLeft) < 0.7 ||
pFirstShape->m_eLineType == eLineType::ltThick || pFirstShape->m_eLineType == eLineType::ltSingle)
pFirstShape->m_eLineType == eLineType::ltThick || pFirstShape->m_eLineType == eLineType::ltSingle)
{
pFirstShape->m_eLineType = pFirstShape->m_dHeight > 0.3 ? eLineType::ltThick : eLineType::ltSingle;
passed = true;
}
else if ((pFirstShape->m_eLineType == eLineType::ltUnknown || pFirstShape->m_eLineType == eLineType::ltDashLong ||
pFirstShape->m_eLineType == eLineType::ltDashLongHeavy) && pSecondShape->m_eLineType == eLineType::ltUnknown)
pFirstShape->m_eLineType == eLineType::ltDashLongHeavy) && pSecondShape->m_eLineType == eLineType::ltUnknown)
{
pFirstShape->m_eLineType = pFirstShape->m_dHeight > 0.3 ? eLineType::ltDashLongHeavy : eLineType::ltDashLong;
passed = true;
@ -531,8 +531,8 @@ namespace NSDocxRenderer
case eSimpleLineType::sltHWave:
if ((pFirstShape->m_eLineType == eLineType::ltUnknown || pFirstShape->m_eLineType == eLineType::ltWave ||
pFirstShape->m_eLineType == eLineType::ltWavyHeavy || pFirstShape->m_eLineType == eLineType::ltWavyDouble) &&
pSecondShape->m_eLineType == eLineType::ltUnknown)
pFirstShape->m_eLineType == eLineType::ltWavyHeavy || pFirstShape->m_eLineType == eLineType::ltWavyDouble) &&
pSecondShape->m_eLineType == eLineType::ltUnknown)
{
pFirstShape->m_eLineType = pFirstShape->m_oPen.Size > 0.3 ? eLineType::ltWavyHeavy : eLineType::ltWave;
passed = true;
@ -585,7 +585,7 @@ namespace NSDocxRenderer
double left = fabs(m_dRotation) > c_dMIN_ROTATION ? m_oNoRotVector.GetLeft() : m_dLeft;
double right = fabs(m_dRotation) > c_dMIN_ROTATION ? m_oNoRotVector.GetRight() : m_dRight;
double top = fabs(m_dRotation) > c_dMIN_ROTATION ? m_oNoRotVector.GetTop() : m_dTop;
double bot = fabs(m_dRotation) > c_dMIN_ROTATION ? m_oNoRotVector.GetBottom() : m_dBot;
double bot = fabs(m_dRotation) > c_dMIN_ROTATION ? m_oNoRotVector.GetBottom() : m_dBaselinePos;
double width = right - left;
double height = bot - top;
@ -707,7 +707,7 @@ namespace NSDocxRenderer
double left = fabs(m_dRotation) > c_dMIN_ROTATION ? m_oNoRotVector.GetLeft() : m_dLeft;
double right = fabs(m_dRotation) > c_dMIN_ROTATION ? m_oNoRotVector.GetRight() : m_dRight;
double top = fabs(m_dRotation) > c_dMIN_ROTATION ? m_oNoRotVector.GetTop() : m_dTop;
double bot = fabs(m_dRotation) > c_dMIN_ROTATION ? m_oNoRotVector.GetBottom() : m_dBot;
double bot = fabs(m_dRotation) > c_dMIN_ROTATION ? m_oNoRotVector.GetBottom() : m_dBaselinePos;
double height = bot - top;
double width = right - left;
@ -908,7 +908,7 @@ namespace NSDocxRenderer
double left = fabs(m_dRotation) > c_dMIN_ROTATION ? m_oNoRotVector.GetLeft() : m_dLeft;
double right = fabs(m_dRotation) > c_dMIN_ROTATION ? m_oNoRotVector.GetRight() : m_dRight;
double top = fabs(m_dRotation) > c_dMIN_ROTATION ? m_oNoRotVector.GetTop() : m_dTop;
double bot = fabs(m_dRotation) > c_dMIN_ROTATION ? m_oNoRotVector.GetBottom() : m_dBot;
double bot = fabs(m_dRotation) > c_dMIN_ROTATION ? m_oNoRotVector.GetBottom() : m_dBaselinePos;
double height = bot - top;
double width = right - left;
@ -1047,345 +1047,4 @@ namespace NSDocxRenderer
}
oWriter.WriteString(L"</p:sp>");
}
void CShape::ToBin(NSWasm::CData& oWriter) const
{
auto& vector = fabs(m_dRotation) > c_dMIN_ROTATION ? m_oNoRotVector : m_oVector;
auto& data = vector.GetData();
double left = fabs(m_dRotation) > c_dMIN_ROTATION ? m_oNoRotVector.GetLeft() : m_dLeft;
double right = fabs(m_dRotation) > c_dMIN_ROTATION ? m_oNoRotVector.GetRight() : m_dRight;
double top = fabs(m_dRotation) > c_dMIN_ROTATION ? m_oNoRotVector.GetTop() : m_dTop;
double bot = fabs(m_dRotation) > c_dMIN_ROTATION ? m_oNoRotVector.GetBottom() : m_dBot;
double height = bot - top;
double width = right - left;
// WriteUniColor
auto WriteUniColor = [&oWriter] (long color, long alpha) {
BYTE r = reinterpret_cast<BYTE*>(&color)[0];
BYTE g = reinterpret_cast<BYTE*>(&color)[1];
BYTE b = reinterpret_cast<BYTE*>(&color)[2];
oWriter.StartRecord(1); // COLOR_TYPE_SRGB
oWriter.WriteBYTE(kBin_g_nodeAttributeStart);
oWriter.WriteBYTE(0); oWriter.WriteBYTE(r);
oWriter.WriteBYTE(1); oWriter.WriteBYTE(g);
oWriter.WriteBYTE(2); oWriter.WriteBYTE(b);
oWriter.WriteBYTE(kBin_g_nodeAttributeEnd);
// WriteMods (alpha)
oWriter.StartRecord(0);
oWriter.AddInt(1);
oWriter.StartRecord(1);
oWriter.WriteBYTE(kBin_g_nodeAttributeStart);
oWriter.WriteBYTE(0); oWriter.WriteStringUtf16(L"alpha");
oWriter.WriteBYTE(1); oWriter.AddInt(alpha * 100000 / 255);
oWriter.WriteBYTE(kBin_g_nodeAttributeEnd);
oWriter.EndRecord();
oWriter.EndRecord();
oWriter.EndRecord();
};
auto WriteUniFill = [&oWriter, &WriteUniColor] (long color, long alpha) {
oWriter.StartRecord(3); // FILL_TYPE_SOLID
oWriter.StartRecord(0);
WriteUniColor(color, alpha);
oWriter.EndRecord();
oWriter.EndRecord();
};
auto write_spPr = [this, &oWriter, &vector, &data, &WriteUniFill, &top, &left, &height, &width] () {
oWriter.WriteBYTE(kBin_g_nodeAttributeStart);
oWriter.WriteBYTE(kBin_g_nodeAttributeEnd);
// WriteRecord WriteXfrm
oWriter.StartRecord(0);
oWriter.WriteBYTE(kBin_g_nodeAttributeStart);
oWriter.WriteBYTE(0); oWriter.AddInt(static_cast<unsigned int>(left * c_dMMToEMU));
oWriter.WriteBYTE(1); oWriter.AddInt(static_cast<unsigned int>(top * c_dMMToEMU));
oWriter.WriteBYTE(2); oWriter.AddInt(static_cast<unsigned int>(width * c_dMMToEMU));
oWriter.WriteBYTE(3); oWriter.AddInt(static_cast<unsigned int>(height * c_dMMToEMU));
if (fabs(m_dRotation) > c_dMIN_ROTATION)
{
double degree = m_dRotation;
if (m_dRotation < 0) degree = 360.0 - m_dRotation;
oWriter.WriteBYTE(10); oWriter.AddInt(degree * c_dDegreeToAngle);
}
oWriter.WriteBYTE(kBin_g_nodeAttributeEnd);
oWriter.EndRecord();
// end of WriteRecord WriteXfrm
// WriteRecord WriteGeometry
oWriter.StartRecord(1);
if (vector.IsEmpty())
{
oWriter.StartRecord(1);
oWriter.WriteBYTE(kBin_g_nodeAttributeStart);
oWriter.WriteBYTE(0); oWriter.WriteStringUtf16(L"rect"); // default rect for text
oWriter.WriteBYTE(kBin_g_nodeAttributeEnd);
oWriter.EndRecord();
}
else
{
oWriter.StartRecord(2);
// WritePathLst
oWriter.StartRecord(4);
oWriter.AddInt(1);
oWriter.StartRecord(1);
oWriter.WriteBYTE(kBin_g_nodeAttributeStart);
oWriter.WriteBYTE(2); oWriter.AddInt(height * c_dMMToEMU); // pathH
oWriter.WriteBYTE(4); oWriter.AddInt(width * c_dMMToEMU); // pathW
oWriter.WriteBYTE(kBin_g_nodeAttributeEnd);
oWriter.StartRecord(0);
oWriter.AddInt(static_cast<unsigned int>(data.size()));
auto write_coords = [&oWriter, &left, &top] (const CVectorGraphics::CPathCommand& command) {
BYTE byte_count = 0;
oWriter.WriteBYTE(kBin_g_nodeAttributeStart);
for (const auto& point : command.points)
{
int x_coord = static_cast<int>((point.x - left) * c_dMMToEMU);
int y_coord = static_cast<int>((point.y - top) * c_dMMToEMU);
oWriter.WriteBYTE(byte_count++);
oWriter.WriteStringUtf16(std::to_wstring(x_coord));
oWriter.WriteBYTE(byte_count++);
oWriter.WriteStringUtf16(std::to_wstring(y_coord));
}
oWriter.WriteBYTE(kBin_g_nodeAttributeEnd);
};
for (const auto& command : data)
{
oWriter.StartRecord(0);
switch (command.type)
{
case CVectorGraphics::ePathCommandType::pctMove:
oWriter.StartRecord(1);
write_coords(command);
oWriter.EndRecord();
break;
case CVectorGraphics::ePathCommandType::pctLine:
oWriter.StartRecord(2);
write_coords(command);
oWriter.EndRecord();
break;
case CVectorGraphics::ePathCommandType::pctCurve:
oWriter.StartRecord(4);
write_coords(command);
oWriter.EndRecord();
break;
case CVectorGraphics::ePathCommandType::pctClose:
oWriter.StartRecord(3);
oWriter.EndRecord();
break;
default:
break;
}
oWriter.EndRecord();
}
oWriter.EndRecord();
oWriter.EndRecord();
oWriter.EndRecord();
// end of WritePathLst
// WriteRecord WriteTextRect
oWriter.StartRecord(5);
oWriter.WriteBYTE(kBin_g_nodeAttributeStart);
oWriter.WriteBYTE(0); oWriter.WriteStringUtf16(L"l");
oWriter.WriteBYTE(1); oWriter.WriteStringUtf16(L"t");
oWriter.WriteBYTE(2); oWriter.WriteStringUtf16(L"r");
oWriter.WriteBYTE(3); oWriter.WriteStringUtf16(L"b");
oWriter.WriteBYTE(kBin_g_nodeAttributeEnd);
oWriter.EndRecord();
// end of WriteRecord WriteTextRect
oWriter.EndRecord();
}
oWriter.EndRecord();
// end of WriteRecord WriteGeometry
// WriteRecord WriteUniFill
if (!m_bIsNoFill && m_eType != CShape::eShapeType::stVectorTexture)
{
oWriter.StartRecord(2);
WriteUniFill(m_oBrush.Color1, m_oBrush.Alpha1);
oWriter.EndRecord();
}
if (!m_bIsNoStroke)
{
// WriteRecord WriteLn
oWriter.StartRecord(3);
oWriter.WriteBYTE(kBin_g_nodeAttributeStart);
oWriter.WriteBYTE(3); oWriter.AddInt(static_cast<unsigned int>(m_oPen.Size * c_dMMToEMU)); // ln w
oWriter.WriteBYTE(kBin_g_nodeAttributeEnd);
oWriter.StartRecord(0);
WriteUniFill(m_oPen.Color, m_oPen.Alpha);
oWriter.EndRecord();
oWriter.EndRecord();
}
};
if (m_eType == eShapeType::stVectorTexture)
{
oWriter.StartRecord(2);
// WriteRecord WriteUniNvPr
oWriter.StartRecord(0);
// WriteRecord Write_cNvPr
oWriter.StartRecord(0);
oWriter.WriteBYTE(kBin_g_nodeAttributeStart);
oWriter.WriteBYTE(0); oWriter.AddInt(m_pImageInfo->m_nId);
std::wstring name = L"Picture " + std::to_wstring(m_pImageInfo->m_nId);
oWriter.WriteBYTE(1); oWriter.WriteStringUtf16(name);
oWriter.WriteBYTE(kBin_g_nodeAttributeEnd);
oWriter.EndRecord();
// WriteRecord WritePicCNvPr
oWriter.StartRecord(1);
oWriter.WriteBYTE(kBin_g_nodeAttributeStart);
oWriter.WriteBYTE(3); oWriter.WriteBool(true); // noChangeAspect
oWriter.WriteBYTE(kBin_g_nodeAttributeEnd);
oWriter.EndRecord();
oWriter.EndRecord();
// end of WriteRecord WriteUniNvPr
// WriteRecord WriteUniFill (blip)
oWriter.StartRecord(1);
oWriter.StartRecord(1); // FILL_TYPE_BLIP
oWriter.WriteBYTE(kBin_g_nodeAttributeStart);
oWriter.WriteBYTE(kBin_g_nodeAttributeEnd);
// WriteBlip
oWriter.StartRecord(0);
oWriter.WriteBYTE(kBin_g_nodeAttributeStart);
oWriter.WriteBYTE(kBin_g_nodeAttributeEnd);
oWriter.StartRecord(2);
oWriter.AddInt(0); // effects
oWriter.EndRecord();
std::wstring rId = L"rId" + std::to_wstring(c_iStartingIdForImages + m_pImageInfo->m_nId);
oWriter.WriteBYTE(10); oWriter.WriteStringUtf16(rId); // embed
oWriter.EndRecord();
// end of WriteBlip
if (m_oBrush.Image == NULL)
{
oWriter.StartRecord(1);
oWriter.WriteBYTE(kBin_g_nodeAttributeStart);
// coeff
double src_offset_left = 1 - (width / (right - m_dImageLeft));
double src_offset_right = 1 - (width / (m_dImageRight - left));
double src_offset_top = 1 - (height / (bot - m_dImageTop));
double src_offset_bot = 1 - (height / (m_dImageBot - top));
// percentage
src_offset_left *= 100;
src_offset_right *= 100;
src_offset_top *= 100;
src_offset_bot *= 100;
std::wstring l = std::to_wstring(static_cast<int>(src_offset_left * 1000));
std::wstring t = std::to_wstring(static_cast<int>(src_offset_top * 1000));
std::wstring r = std::to_wstring(static_cast<int>(src_offset_right * 1000));
std::wstring b = std::to_wstring(static_cast<int>(src_offset_bot * 1000));
oWriter.WriteBYTE(0); oWriter.WriteStringUtf16(l);
oWriter.WriteBYTE(1); oWriter.WriteStringUtf16(t);
oWriter.WriteBYTE(2); oWriter.WriteStringUtf16(r);
oWriter.WriteBYTE(3); oWriter.WriteStringUtf16(b);
oWriter.WriteBYTE(kBin_g_nodeAttributeEnd);
oWriter.EndRecord();
oWriter.StartRecord(3);
oWriter.EndRecord();
}
else // tile
{
oWriter.StartRecord(2);
oWriter.WriteBYTE(kBin_g_nodeAttributeStart);
oWriter.WriteBYTE(0); oWriter.AddInt(100);
oWriter.WriteBYTE(1); oWriter.AddInt(100);
oWriter.WriteBYTE(kBin_g_nodeAttributeEnd);
oWriter.EndRecord();
}
oWriter.EndRecord();
oWriter.EndRecord();
// end of WriteRecord WriteUniFill (blip)
// WriteRecord WriteSpPr
oWriter.StartRecord(2); write_spPr(); oWriter.EndRecord();
oWriter.EndRecord();
return;
}
oWriter.StartRecord(1);
oWriter.WriteBYTE(kBin_g_nodeAttributeStart);
oWriter.WriteBYTE(kBin_g_nodeAttributeEnd);
// WriteRecord WriteSpPr
oWriter.StartRecord(1); write_spPr(); oWriter.EndRecord();
if (m_eType == eShapeType::stTextBox && !m_arOutputObjects.empty())
{
// WriteRecord WriteTxBody
oWriter.StartRecord(3);
// WriteRecord WriteBodyPr
oWriter.StartRecord(0);
oWriter.WriteBYTE(kBin_g_nodeAttributeStart);
oWriter.WriteBYTE(1); oWriter.WriteBYTE(1); // anchor
oWriter.WriteBYTE(2); oWriter.WriteBool(false); // anchorCtr
oWriter.WriteBYTE(3); oWriter.AddInt(0); // bIns
oWriter.WriteBYTE(4); oWriter.WriteBool(true); // compatLnSpc
oWriter.WriteBYTE(5); oWriter.WriteBool(false); // forceAA
oWriter.WriteBYTE(6); oWriter.WriteBool(false); // fromWordArt
oWriter.WriteBYTE(7); oWriter.WriteBYTE(1); // horzOverflow
oWriter.WriteBYTE(8); oWriter.AddInt(0); // lIns
oWriter.WriteBYTE(9); oWriter.AddInt(1); // numCol
oWriter.WriteBYTE(10); oWriter.AddInt(0); // rIns
oWriter.WriteBYTE(11); oWriter.AddInt(0); // rot
oWriter.WriteBYTE(12); oWriter.WriteBool(false); // rtlCol
oWriter.WriteBYTE(13); oWriter.AddInt(0); // spcCol
oWriter.WriteBYTE(14); oWriter.WriteBool(false); // spcFirstLastPara
oWriter.WriteBYTE(15); oWriter.AddInt(0); // tIns
// 16 is upright param
oWriter.WriteBYTE(17); oWriter.WriteBYTE(1); // vert
oWriter.WriteBYTE(18); oWriter.WriteBYTE(1); // vertOverflow
oWriter.WriteBYTE(19); oWriter.WriteBYTE(1); // vert
oWriter.WriteBYTE(kBin_g_nodeAttributeEnd);
// todo WritePrstTxWarp
oWriter.EndRecord();
// end of WriteRecord WriteBodyPr
// WriteRecordArray WriteParagraph
oWriter.StartRecord(2);
unsigned int len = static_cast<unsigned int>(m_arOutputObjects.size());
oWriter.AddInt(len);
for (const auto& o : m_arOutputObjects)
{
oWriter.StartRecord(0);
o->ToBin(oWriter);
oWriter.EndRecord();
}
oWriter.EndRecord();
// end of WriteRecordArray WriteParagraph
oWriter.EndRecord();
// end of WriteRecord WriteTxBody
}
oWriter.EndRecord();
}
}; // namespace NSDocxRenderer

View File

@ -20,7 +20,7 @@ namespace NSDocxRenderer
gtNoGraphics,
};
class CShape : public CBaseItem, public IOoxmlItem
class CShape : public CBaseItem
{
public:
enum class eShapeType
@ -63,16 +63,15 @@ namespace NSDocxRenderer
eSimpleLineType m_eSimpleLineType{eSimpleLineType::sltUnknown};
eLineType m_eLineType {eLineType::ltUnknown};
std::vector<std::shared_ptr<IOoxmlItem>> m_arOutputObjects;
std::vector<std::shared_ptr<CBaseItem>> m_arOutputObjects;
public:
CShape();
CShape(std::shared_ptr<CImageInfo> pInfo, const std::wstring& strDstMedia);
virtual ~CShape();
virtual void Clear();
virtual void Clear() override final;
virtual void ToXml(NSStringUtils::CStringBuilder& oWriter) const override final;
virtual void ToXmlPptx(NSStringUtils::CStringBuilder& oWriter)const override final;
virtual void ToBin(NSWasm::CData& oWriter) const override final;
void SetVector(CVectorGraphics&& oVector);
void CalcNoRotVector();

View File

@ -5,11 +5,7 @@
namespace NSDocxRenderer
{
CTable::CCell::CCell(const CCell& other)
{
*this = other;
}
void CTable::CCell::Clear()
void CTable::CCell::Clear()
{
m_arParagraphs.clear();
}
@ -19,33 +15,17 @@ namespace NSDocxRenderer
oWriter.WriteString(L"<w:tcPr>");
oWriter.WriteString(L"<w:tcW w:w=\"");
oWriter.AddUInt(static_cast<unsigned int>(m_dWidth * c_dMMToDx));
oWriter.WriteString(L"\" w:type=\"dxa\"/>");
oWriter.WriteString(L"<w:gridSpan w:val=\"");
oWriter.AddUInt(m_nGridSpan);
oWriter.WriteString(L"\"/>");
oWriter.WriteString(L"<w:vMerge w:val=\"");
switch (m_eVMerge) {
case eVMerge::vmContinue:
oWriter.WriteString(L"continue");
break;
case eVMerge::vmRestart:
oWriter.WriteString(L"restart");
break;
default:
break;
}
oWriter.WriteString(L"\"/>");
oWriter.WriteString(L"\"w:type=\"dxa\"/>");
oWriter.WriteString(L"<w:tcBorders>");
auto write_border = [&oWriter] (const CBorder& border, const std::wstring& prefix) {
oWriter.WriteString(L"<w:");
oWriter.WriteString(prefix);
oWriter.WriteString(L" w:val=");
oWriter.WriteString(SingletonInstance<LinesTable>().ConvertLineToString(border.lineType));
oWriter.WriteString(L" w:sz=\"");
oWriter.AddUInt(static_cast<unsigned int>(border.dWidth * c_dMMToPt * 8));
oWriter.AddUInt(static_cast<unsigned int>(border.dWidth * c_dMMToPt / 8));
oWriter.WriteString(L"\" w:space=\"");
oWriter.AddUInt(static_cast<unsigned int>(border.dSpacing * c_dMMToPt));
oWriter.WriteString(L"\" w:color=\"");
@ -54,7 +34,7 @@ namespace NSDocxRenderer
};
write_border(m_oBorderTop, L"top");
write_border(m_oBorderBot, L"bottom");
write_border(m_oBorderBot, L"bot");
write_border(m_oBorderLeft, L"left");
write_border(m_oBorderRight, L"right");
@ -69,28 +49,6 @@ namespace NSDocxRenderer
void CTable::CCell::ToXmlPptx(NSStringUtils::CStringBuilder& oWriter) const
{
}
void CTable::CCell::ToBin(NSWasm::CData& oWriter) const
{
}
CTable::CCell& CTable::CCell::operator=(const CCell& other)
{
CBaseItem::operator=(other);
m_oBorderBot = other.m_oBorderBot;
m_oBorderTop = other.m_oBorderTop;
m_oBorderLeft = other.m_oBorderLeft;
m_oBorderRight = other.m_oBorderRight;
m_nGridSpan = other.m_nGridSpan;
m_eVMerge = other.m_eVMerge;
m_arParagraphs.clear();
for (const auto& p : other.m_arParagraphs)
m_arParagraphs.push_back(p);
return *this;
}
void CTable::CCell::AddParagraph(const paragraph_ptr_t& pParagraph)
{
@ -119,10 +77,6 @@ namespace NSDocxRenderer
void CTable::CRow::ToXmlPptx(NSStringUtils::CStringBuilder& oWriter) const
{
}
void CTable::CRow::ToBin(NSWasm::CData& oWriter) const
{
}
void CTable::CRow::AddCell(const cell_ptr_t& pCell)
{
@ -143,26 +97,12 @@ namespace NSDocxRenderer
oWriter.WriteString(L"<w:tbl>");
oWriter.WriteString(L"<w:tblPr>");
oWriter.WriteString(L"<w:tblpPr ");
oWriter.WriteString(L"w:horzAnchor=\"page\" w:vertAnchor=\"page\" w:tblpX=\"");
oWriter.AddInt64(static_cast<long long>(m_dLeft * c_dMMToDx));
oWriter.WriteString(L"\" w:tblpY=\"");
oWriter.AddInt64(static_cast<long long>(m_dTop * c_dMMToDx));
oWriter.WriteString(L"\" />");
oWriter.WriteString(L"<w:tblW w:w=\"");
oWriter.AddUInt(static_cast<unsigned int>(m_dWidth * c_dMMToDx));
oWriter.WriteString(L"\" w:type=\"dxa\"/>");
oWriter.WriteString(L"\"w:type=\"dxa\"/>");
oWriter.WriteString(L"</w:tblPr>");
oWriter.WriteString(L"<w:tblGrid>");
for (const auto& gc : m_arGridCols)
{
oWriter.WriteString(L"<w:gridCol w:w=\"");
oWriter.AddUInt(static_cast<unsigned int>(gc * c_dMMToDx));
oWriter.WriteString(L"\" />");
}
oWriter.WriteString(L"</w:tblGrid>");
for (const auto& r : m_arRows)
@ -173,58 +113,15 @@ namespace NSDocxRenderer
void CTable::ToXmlPptx(NSStringUtils::CStringBuilder& oWriter) const
{
}
void CTable::ToBin(NSWasm::CData& oWriter) const
{
}
void CTable::AddRow(const row_ptr_t& pRow)
{
CBaseItem::RecalcWithNewItem(pRow.get());
m_arRows.push_back(pRow);
}
void CTable::CalcGridCols()
{
std::vector<double> cells_left;
auto add_if_no_exists = [&cells_left] (double val) {
bool exists = false;
for (const auto& curr : cells_left)
{
if (fabs(curr - val) < c_dMAX_TABLE_LINE_WIDTH_MM)
{
exists = true;
break;
}
}
if (!exists)
cells_left.push_back(val);
};
double right = 0;
for (const auto& row : m_arRows)
{
for (const auto& cell : row->m_arCells)
{
right = std::max(right, cell->m_dRight);
add_if_no_exists(cell->m_dLeft);
}
}
std::sort(cells_left.begin(), cells_left.end(), std::less<double>{});
for (size_t i = 0; i < cells_left.size() - 1; ++i)
m_arGridCols.push_back(cells_left[i + 1] - cells_left[i]);
m_arGridCols.push_back(right - cells_left.back());
}
bool CTable::IsEmpty() const
{
return m_arRows.empty();
}
void CTextCell::AddTextLine(const std::shared_ptr<CTextLine>& pTextLine)
{
CBaseItem::RecalcWithNewItem(pTextLine.get());
m_arTextLines.push_back(pTextLine);
}
} // namespace NSDocxRenderer

View File

@ -5,16 +5,12 @@
#include "BaseItem.h"
#include "Paragraph.h"
#include "Shape.h"
#include "../../resources/LinesTable.h"
namespace NSDocxRenderer
{
class CGraphicalCell;
class CTextCell;
class CTable : public CBaseItem, public IOoxmlItem
class CTable : public CBaseItem
{
public:
class CCell;
@ -25,33 +21,22 @@ namespace NSDocxRenderer
using paragraph_ptr_t = std::shared_ptr<CParagraph>;
public:
class CCell : public CBaseItem, public IOoxmlItem
class CCell : public CBaseItem
{
friend class CTable;
public:
struct CBorder
{
double dWidth{};
double dSpacing{};
long lColor{};
eLineType lineType{eLineType::ltNone};
};
enum class eVMerge
{
vmRestart,
vmContinue
eLineType lineType{};
};
CCell() = default;
CCell(const CCell& other);
virtual ~CCell() = default;
virtual void Clear();
virtual void Clear() override final;
virtual void ToXml(NSStringUtils::CStringBuilder& oWriter) const override final;
virtual void ToXmlPptx(NSStringUtils::CStringBuilder& oWriter) const override final;
virtual void ToBin(NSWasm::CData& oWriter) const override final;
CCell& operator=(const CCell& other);
void AddParagraph(const paragraph_ptr_t& pParagraph);
@ -60,21 +45,17 @@ namespace NSDocxRenderer
CBorder m_oBorderLeft;
CBorder m_oBorderRight;
unsigned int m_nGridSpan = 1;
eVMerge m_eVMerge = CTable::CCell::eVMerge::vmRestart;
private:
std::vector<paragraph_ptr_t> m_arParagraphs;
};
class CRow : public CBaseItem, IOoxmlItem
class CRow : public CBaseItem
{
friend class CTable;
public:
CRow() = default;
virtual ~CRow() = default;
virtual void Clear();
virtual void Clear() override final;
virtual void ToXml(NSStringUtils::CStringBuilder& oWriter) const override final;
virtual void ToXmlPptx(NSStringUtils::CStringBuilder& oWriter) const override final;
virtual void ToBin(NSWasm::CData& oWriter) const override final;
void AddCell(const cell_ptr_t& pCell);
bool IsEmpty() const;
@ -85,37 +66,15 @@ namespace NSDocxRenderer
CTable() = default;
virtual ~CTable() = default;
virtual void Clear();
virtual void Clear() override final;
virtual void ToXml(NSStringUtils::CStringBuilder& oWriter) const override final;
virtual void ToXmlPptx(NSStringUtils::CStringBuilder& oWriter) const override final;
virtual void ToBin(NSWasm::CData& oWriter) const override final;
void AddRow(const row_ptr_t& pRow);
void CalcGridCols();
bool IsEmpty() const;
private:
std::vector<row_ptr_t> m_arRows;
std::vector<double> m_arGridCols;
};
class CGraphicalCell : public CBaseItem
{
public:
// realization
};
class CTextCell : public CBaseItem
{
public:
void AddTextLine(const std::shared_ptr<CTextLine>& pTextLine);
std::vector<std::shared_ptr<CTextLine>> m_arTextLines;
double m_dMinPossibleTop = std::numeric_limits<double>::lowest();
double m_dMinPossibleLeft = std::numeric_limits<double>::lowest();
double m_dMaxPossibleBot = std::numeric_limits<double>::max();
double m_dMaxPossibleRight = std::numeric_limits<double>::max();
};
} // namespace NSDocxRenderer

View File

@ -17,14 +17,14 @@ namespace NSDocxRenderer
m_arConts.clear();
m_pLine = nullptr;
}
void CTextLine::AddCont(const std::shared_ptr<CContText>& oCont)
void CTextLine::AddCont(std::shared_ptr<CContText> oCont)
{
RecalcWithNewItem(oCont.get());
m_arConts.push_back(oCont);
}
void CTextLine::AddConts(const std::vector<std::shared_ptr<CContText>>& arConts)
{
for (const auto& cont : arConts)
for (auto& cont : arConts)
AddCont(cont);
}
@ -71,7 +71,7 @@ namespace NSDocxRenderer
std::shared_ptr<CContText> pFirst;
size_t j = 0;
for (; j < m_arConts.size() && !pFirst; ++j)
for(; j < m_arConts.size() && !pFirst; ++j)
pFirst = m_arConts[j];
for (size_t i = j; i < m_arConts.size(); ++i)
@ -82,8 +82,8 @@ namespace NSDocxRenderer
double avg_space_width = pCurrent->m_pFontStyle->GetAvgSpaceWidth();
double space_width = avg_space_width != 0.0 ?
avg_space_width * c_dAVERAGE_SPACE_WIDTH_COEF :
pCurrent->CalculateSpace() * c_dSPACE_WIDTH_COEF;
avg_space_width * c_dAVERAGE_SPACE_WIDTH_COEF :
pCurrent->CalculateSpace() * c_dSPACE_WIDTH_COEF;
double dDifference = pCurrent->m_dLeft - pFirst->m_dRight;
@ -91,7 +91,7 @@ namespace NSDocxRenderer
bool bIsSpaceDelta = dDifference > space_width;
bool bIsWideSpaceDelta = dDifference > space_width * 3;
if (bIsWideSpaceDelta || (pCurrent->m_bPossibleHorSplit && bIsSpaceDelta))
if (bIsWideSpaceDelta || (pCurrent->m_bPossibleSplit && bIsSpaceDelta))
{
if (CContText::IsUnicodeSpace(pFirst->GetLastSym()))
pFirst->RemoveLastSym();
@ -104,7 +104,7 @@ namespace NSDocxRenderer
wide_space->m_dRight = pCurrent->m_dLeft;
wide_space->m_dWidth = wide_space->m_dRight - wide_space->m_dLeft;
wide_space->m_dBot = pCurrent->m_dBot;
wide_space->m_dBaselinePos = pCurrent->m_dBaselinePos;
wide_space->m_dTop = pCurrent->m_dTop;
wide_space->m_dTopWithAscent = pCurrent->m_dTopWithAscent;
@ -217,7 +217,7 @@ namespace NSDocxRenderer
m_dTop = 0.0;
m_dWidth = 0.0;
m_dHeight = 0.0;
m_dBot = 0.0;
m_dBaselinePos = 0.0;
m_dRight = 0.0;
m_dHeight = 0.0;
@ -241,19 +241,19 @@ namespace NSDocxRenderer
return eVerticalCrossingType::vctCurrentOutsideNext;
else if (this_top < other_top && this_bot < other_bot &&
(this_bot >= other_top || fabs(this_bot - other_top) < c_dTHE_SAME_STRING_Y_PRECISION_MM))
(this_bot >= other_top || fabs(this_bot - other_top) < c_dTHE_SAME_STRING_Y_PRECISION_MM))
return eVerticalCrossingType::vctCurrentAboveNext;
else if (this_top > other_top && this_bot > other_bot &&
(this_top <= other_bot || fabs(this_top - other_bot) < c_dTHE_SAME_STRING_Y_PRECISION_MM))
(this_top <= other_bot || fabs(this_top - other_bot) < c_dTHE_SAME_STRING_Y_PRECISION_MM))
return eVerticalCrossingType::vctCurrentBelowNext;
else if (this_top == other_top && this_bot == other_bot &&
m_dLeft == pLine->m_dLeft && m_dRight == pLine->m_dRight)
m_dLeft == pLine->m_dLeft && m_dRight == pLine->m_dRight)
return eVerticalCrossingType::vctDublicate;
else if (fabs(this_top - other_top) < c_dTHE_SAME_STRING_Y_PRECISION_MM &&
fabs(this_bot - other_bot) < c_dTHE_SAME_STRING_Y_PRECISION_MM)
fabs(this_bot - other_bot) < c_dTHE_SAME_STRING_Y_PRECISION_MM)
return eVerticalCrossingType::vctTopAndBottomBordersMatch;
else if (fabs(this_top - other_top) < c_dTHE_SAME_STRING_Y_PRECISION_MM)
@ -294,33 +294,24 @@ namespace NSDocxRenderer
bool CTextLine::IsShadingPresent(const CTextLine *pLine) const noexcept
{
return (m_pDominantShape && pLine->m_pDominantShape &&
m_pDominantShape->m_oBrush.Color1 == pLine->m_pDominantShape->m_oBrush.Color1 &&
fabs(m_pDominantShape->m_dLeft - pLine->m_pDominantShape->m_dLeft) < c_dGRAPHICS_ERROR_IN_LINES_MM &&
fabs(m_pDominantShape->m_dWidth - pLine->m_pDominantShape->m_dWidth) < c_dGRAPHICS_ERROR_IN_LINES_MM);
m_pDominantShape->m_oBrush.Color1 == pLine->m_pDominantShape->m_oBrush.Color1 &&
fabs(m_pDominantShape->m_dLeft - pLine->m_pDominantShape->m_dLeft) < c_dGRAPHICS_ERROR_IN_LINES_MM &&
fabs(m_pDominantShape->m_dWidth - pLine->m_pDominantShape->m_dWidth) < c_dGRAPHICS_ERROR_IN_LINES_MM);
}
void CTextLine::ToXml(NSStringUtils::CStringBuilder& oWriter) const
{
for (const auto& cont : m_arConts)
if (cont)
if(cont)
cont->ToXml(oWriter);
}
void CTextLine::ToXmlPptx(NSStringUtils::CStringBuilder& oWriter) const
{
for (const auto& cont : m_arConts)
if (cont)
if(cont)
cont->ToXmlPptx(oWriter);
}
void CTextLine::ToBin(NSWasm::CData& oWriter) const
{
for (const auto& cont : m_arConts)
{
oWriter.StartRecord(0);
cont->ToBin(oWriter);
oWriter.EndRecord();
}
}
size_t CTextLine::GetLength() const
{

View File

@ -4,7 +4,7 @@
namespace NSDocxRenderer
{
class CTextLine : public CBaseItem, public IOoxmlItem
class CTextLine : public CBaseItem
{
public:
enum AssumedTextAlignmentType
@ -31,19 +31,16 @@ namespace NSDocxRenderer
double m_dFirstWordWidth{0.0};
bool m_bIsPossibleVerSplit = false;
public:
CTextLine() = default;
virtual ~CTextLine();
virtual void Clear();
virtual void Clear() override final;
virtual void ToXml(NSStringUtils::CStringBuilder& oWriter) const override final;
virtual void ToXmlPptx(NSStringUtils::CStringBuilder& oWriter) const override final;
virtual void ToBin(NSWasm::CData& oWriter) const override final;
virtual void RecalcWithNewItem(const CContText* pCont);
virtual eVerticalCrossingType GetVerticalCrossingType(const CTextLine* pLine) const noexcept;
void AddCont(const std::shared_ptr<CContText>& pCont);
void AddCont(std::shared_ptr<CContText> pCont);
void AddConts(const std::vector<std::shared_ptr<CContText>>& arConts);
void MergeConts();
void CalcFirstWordWidth();

View File

@ -10,8 +10,8 @@
namespace NSDocxRenderer
{
CUnicodeRange::CUnicodeRange(const int& _start, const int& _end,
const BYTE& _range, const BYTE& _rangenum):
RangeNum(_rangenum), Range(_range), Start(_start), End(_end)
const BYTE& _range, const BYTE& _rangenum):
RangeNum(_rangenum), Range(_range), Start(_start), End(_end)
{
}
@ -314,13 +314,13 @@ namespace NSDocxRenderer
void CFontSelector::ClearCache()
{
if (!m_arParamsCache.empty())
if(!m_arParamsCache.empty())
m_arParamsCache.clear();
}
void CFontSelector::SelectFont(const CFontSelectParams& oFontSelectParams,
const CFontMetrics& oFontMetrics,
const NSStringUtils::CStringUTF32& oText)
const CFontMetrics& oFontMetrics,
const NSStringUtils::CStringUTF32& oText)
{
BYTE lRangeNum = 0xFF;
BYTE lRange = 0xFF;
@ -605,14 +605,14 @@ namespace NSDocxRenderer
}
void CFontManager::MeasureString(
const std::wstring& wsText,
double x,
double y,
double& dBoxX,
double& dBoxY,
double& dBoxWidth,
double& dBoxHeight,
MeasureType measureType) const
const std::wstring& wsText,
double x,
double y,
double& dBoxX,
double& dBoxY,
double& dBoxWidth,
double& dBoxHeight,
MeasureType measureType) const
{
dBoxX = 0;
dBoxY = 0;
@ -640,15 +640,15 @@ namespace NSDocxRenderer
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) const
unsigned int* pGids,
unsigned int count,
double x,
double y,
double& dBoxX,
double& dBoxY,
double& dBoxWidth,
double& dBoxHeight,
MeasureType measureType) const
{
dBoxX = 0;
dBoxY = 0;

View File

@ -80,8 +80,8 @@ namespace NSDocxRenderer
~CFontSelector();
void SelectFont(const CFontSelectParams& oFontSelectParams,
const CFontMetrics& oFontMetrics,
const NSStringUtils::CStringUTF32& oText);
const CFontMetrics& oFontMetrics,
const NSStringUtils::CStringUTF32& oText);
std::wstring GetSelectedName() const noexcept;
bool IsSelectedBold() const noexcept;
bool IsSelectedItalic() const noexcept;
@ -129,25 +129,25 @@ namespace NSDocxRenderer
void SetStringGid(const LONG& lGid);
void MeasureString(
const std::wstring& wsText,
double x,
double y,
double& dBoxX,
double& dBoxY,
double& dBoxWidth,
double& dBoxHeight,
MeasureType measureType) const;
const std::wstring& wsText,
double x,
double y,
double& dBoxX,
double& dBoxY,
double& dBoxWidth,
double& dBoxHeight,
MeasureType measureType) const;
void MeasureStringGids(
unsigned int* pGids,
unsigned int count,
double x,
double y,
double& dBoxX,
double& dBoxY,
double& dBoxWidth,
double& dBoxHeight,
MeasureType measureType) const;
unsigned int* pGids,
unsigned int count,
double x,
double y,
double& dBoxX,
double& dBoxY,
double& dBoxWidth,
double& dBoxHeight,
MeasureType measureType) const;
void ClearCache();
private:

View File

@ -27,30 +27,30 @@ namespace NSDocxRenderer
std::shared_ptr<CFontStyle> CFontStyleManager::GetOrAddFontStyle(const CFontStyle& oFontStyle)
{
return GetOrAddFontStyle(
oFontStyle.oBrush,
oFontStyle.wsFontName,
oFontStyle.dFontSize,
oFontStyle.bItalic,
oFontStyle.bBold);
oFontStyle.oBrush,
oFontStyle.wsFontName,
oFontStyle.dFontSize,
oFontStyle.bItalic,
oFontStyle.bBold);
}
std::shared_ptr<CFontStyle> CFontStyleManager::GetOrAddFontStyle(
const NSStructures::CBrush& oBrush,
const std::wstring& wsFontName,
double dFontSize,
bool bItalic,
bool bBold)
const NSStructures::CBrush& oBrush,
const std::wstring& wsFontName,
double dFontSize,
bool bItalic,
bool bBold)
{
for(auto it = m_arFontStyles.begin(); it != m_arFontStyles.end(); ++it)
{
if (oBrush.Type == (*it)->oBrush.Type &&
oBrush.Color1 == (*it)->oBrush.Color1 &&
oBrush.Color2 == (*it)->oBrush.Color2 &&
oBrush.Alpha1 == (*it)->oBrush.Alpha1 &&
oBrush.Alpha2 == (*it)->oBrush.Alpha2 &&
oBrush.LinearAngle == (*it)->oBrush.LinearAngle &&
dFontSize == (*it)->dFontSize &&
wsFontName == (*it)->wsFontName &&
(bItalic == (*it)->bItalic) && (bBold == (*it)->bBold))
oBrush.Color1 == (*it)->oBrush.Color1 &&
oBrush.Color2 == (*it)->oBrush.Color2 &&
oBrush.Alpha1 == (*it)->oBrush.Alpha1 &&
oBrush.Alpha2 == (*it)->oBrush.Alpha2 &&
oBrush.LinearAngle == (*it)->oBrush.LinearAngle &&
dFontSize == (*it)->dFontSize &&
wsFontName == (*it)->wsFontName &&
(bItalic == (*it)->bItalic) && (bBold == (*it)->bBold))
{
auto val = *it;

View File

@ -16,11 +16,11 @@ namespace NSDocxRenderer
std::shared_ptr<CFontStyle> GetOrAddFontStyle(const CFontStyle& oFontStyle);
std::shared_ptr<CFontStyle> GetOrAddFontStyle(
const NSStructures::CBrush& oBrush,
const std::wstring& wsFontName,
double dFontSize,
bool bItalic,
bool bBold);
const NSStructures::CBrush& oBrush,
const std::wstring& wsFontName,
double dFontSize,
bool bItalic,
bool bBold);
private:
std::list<std::shared_ptr<CFontStyle>> m_arFontStyles;

View File

@ -29,11 +29,11 @@ namespace NSDocxRenderer
std::wstring CParagraphStyleManager::GetDefaultParagraphStyleId(const CParagraph& oParagraph) const noexcept
{
if (oParagraph.m_arTextLines.size() > 1) return L"Normal";
if(oParagraph.m_arLines.size() > 1) return L"Normal";
bool isHeading = true;
for (auto& val : oParagraph.m_arTextLines[0]->m_arConts)
if (val && val->m_pFontStyle->dFontSize <= m_dAvgFontSize + 1 && !val->m_pFontStyle->bBold)
for(auto& val : oParagraph.m_arLines[0]->m_arConts)
if(val && val->m_pFontStyle->dFontSize <= m_dAvgFontSize + 1 && !val->m_pFontStyle->bBold)
isHeading = false;
return isHeading ? L"Heading1" : L"Normal";

View File

@ -21,7 +21,7 @@ namespace NSDocxRenderer
oWriter.WriteString(L"w:styleId=\"" + wsStyleId + L"\">");
oWriter.WriteString(L"<w:name w:val=\"" + wsName + L"\"/>");
if (!wsBasedOn.empty()) oWriter.WriteString(L"<w:basedOn w:val=\"" + wsBasedOn + L"\"/>");
if(!wsBasedOn.empty()) oWriter.WriteString(L"<w:basedOn w:val=\"" + wsBasedOn + L"\"/>");
if(bIsUnhideWhenUsed) oWriter.WriteString(L"<w:unhideWhenUsed/>");
if(bIsSemiHidden) oWriter.WriteString(L"<w:semiHidden/>");
oWriter.WriteString(L"<w:uiPriority w:val=\"" + std::to_wstring(nUiPriority) + L"\"/>");

View File

@ -1,6 +1,5 @@
#pragma once
#include <type_traits>
#include <cstdlib>
#include <limits>
#include "../../../DesktopEditor/common/Types.h"
@ -28,26 +27,22 @@ const double c_dTHE_SAME_STRING_Y_PRECISION_MM = 0.02;
const double c_dTHE_SAME_STRING_X_PRECISION_MM = 0.02;
const double c_dLINE_DISTANCE_ERROR_MM = 0.3;
const double c_dERROR_OF_PARAGRAPH_BORDERS_MM = 1.0;
const double c_dERROR_GAP = 1.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_dMAX_TABLE_LINE_WIDTH_MM = 2.2;
const double c_dMAX_TABLE_CELL_DIFF_MM = 7.0;
const double c_dGRAPHICS_ERROR_IN_LINES_MM = 0.3;
const double c_dMAX_LINE_HEIGHT_MM = 2.5;
const double c_dMAX_LINE_WITH_TEXT_ERROR_MM = 2.5;
const double c_dCELL_GROUP_SPLIT_MM = 12.0;
const double c_dLINE_GROUP_SPLIT_MM = 12.0;
const double c_dCORRECTION_FIRST_PARAGRAPH_MM = -1.5;
const double c_dCORRECTION_FOR_FIRST_PARAGRAPH = -1.5;
const double c_dLINE_DISTANCE_MAX_MM = 50.0;
const double c_dSHAPE_TROUGH_MAX_MM = 80.0;
const double c_dSHAPE_TROUGH_MAX_MM = 120.0;
const double c_dLINE_SPLIT_DISTANCE_MM = 10.0;
const double c_dSHAPE_X_OFFSET_MM = 1.5;
const double c_dSHAPE_X_OFFSET = 1.5;
const double c_dAVERAGE_SPACE_WIDTH_COEF = 0.9;
const double c_dSPACE_WIDTH_COEF = 0.4;
const double c_dMIN_ROTATION = 0.01;
const double c_dMAX_FIRST_LINE_INDENT = 20.0;
const UINT c_iWhiteColor = 0xFFFFFF;
const UINT c_iBlackColor = 0x000000;

View File

@ -14,17 +14,17 @@ namespace NSDocxRenderer
ResetBorders();
}
CVectorGraphics::CVectorGraphics(const CVectorGraphics& other) noexcept
: CVectorGraphics()
: CVectorGraphics()
{
*this = other;
}
CVectorGraphics::CVectorGraphics(CVectorGraphics&& other) noexcept
: CVectorGraphics()
: CVectorGraphics()
{
*this = std::move(other);
}
CVectorGraphics::CVectorGraphics(const Aggplus::CGraphicsPath& other) noexcept
: CVectorGraphics()
: CVectorGraphics()
{
size_t close_count = other.GetCloseCount();
size_t count = static_cast<size_t>(other.GetPointCount()) + close_count;
@ -35,11 +35,11 @@ namespace NSDocxRenderer
if (other.IsMovePoint(idx))
MoveTo(point.X, point.Y);
else if (other.IsLinePoint(idx))
LineTo(point.X, point.Y);
LineTo(point.X, point.Y);
else if (idx < count - 2 &&
other.IsCurvePoint(idx) &&
other.IsCurvePoint(idx + 1) &&
other.IsCurvePoint(idx + 2))
other.IsCurvePoint(idx) &&
other.IsCurvePoint(idx + 1) &&
other.IsCurvePoint(idx + 2))
{
const auto& point1 = points[idx + 1];
const auto& point2 = points[idx + 2];
@ -86,23 +86,23 @@ namespace NSDocxRenderer
bool CVectorGraphics::operator<(const CVectorGraphics& other) const noexcept
{
return m_dBottom < other.m_dBottom &&
m_dTop > other.m_dTop &&
m_dRight < other.m_dRight &&
m_dLeft > other.m_dLeft;
m_dTop > other.m_dTop &&
m_dRight < other.m_dRight &&
m_dLeft > other.m_dLeft;
}
bool CVectorGraphics::operator>(const CVectorGraphics& other) const noexcept
{
return m_dBottom > other.m_dBottom &&
m_dTop < other.m_dTop &&
m_dRight > other.m_dRight &&
m_dLeft < other.m_dLeft;
m_dTop < other.m_dTop &&
m_dRight > other.m_dRight &&
m_dLeft < other.m_dLeft;
}
bool CVectorGraphics::operator==(const CVectorGraphics& other) const noexcept
{
return fabs(m_dBottom - other.m_dBottom < c_dGRAPHICS_ERROR_MM) &&
fabs(m_dTop - other.m_dTop < c_dGRAPHICS_ERROR_MM) &&
fabs(m_dRight - other.m_dRight < c_dGRAPHICS_ERROR_MM) &&
fabs(m_dLeft - other.m_dLeft < c_dGRAPHICS_ERROR_MM);
fabs(m_dTop - other.m_dTop < c_dGRAPHICS_ERROR_MM) &&
fabs(m_dRight - other.m_dRight < c_dGRAPHICS_ERROR_MM) &&
fabs(m_dLeft - other.m_dLeft < c_dGRAPHICS_ERROR_MM);
}
bool CVectorGraphics::operator!=(const CVectorGraphics& other) const noexcept
{
@ -111,16 +111,16 @@ namespace NSDocxRenderer
bool CVectorGraphics::operator<=(const CVectorGraphics& other) const noexcept
{
return m_dBottom - c_dGRAPHICS_ERROR_MM < other.m_dBottom &&
m_dTop + c_dGRAPHICS_ERROR_MM > other.m_dTop &&
m_dRight - c_dGRAPHICS_ERROR_MM < other.m_dRight &&
m_dLeft + c_dGRAPHICS_ERROR_MM > other.m_dLeft;
m_dTop + c_dGRAPHICS_ERROR_MM > other.m_dTop &&
m_dRight - c_dGRAPHICS_ERROR_MM < other.m_dRight &&
m_dLeft + c_dGRAPHICS_ERROR_MM > other.m_dLeft;
}
bool CVectorGraphics::operator>=(const CVectorGraphics& other) const noexcept
{
return m_dBottom + c_dGRAPHICS_ERROR_MM > other.m_dBottom &&
m_dTop - c_dGRAPHICS_ERROR_MM < other.m_dTop &&
m_dRight + c_dGRAPHICS_ERROR_MM > other.m_dRight &&
m_dLeft - c_dGRAPHICS_ERROR_MM < other.m_dLeft;
m_dTop - c_dGRAPHICS_ERROR_MM < other.m_dTop &&
m_dRight + c_dGRAPHICS_ERROR_MM > other.m_dRight &&
m_dLeft - c_dGRAPHICS_ERROR_MM < other.m_dLeft;
}
void CVectorGraphics::ResetBorders() noexcept
@ -164,7 +164,7 @@ namespace NSDocxRenderer
return m_arData.empty();
}
const std::list<CVectorGraphics::CPathCommand>& CVectorGraphics::GetData() const
const std::list<CVectorGraphics::PathCommand>& CVectorGraphics::GetData() const
{
return m_arData;
}
@ -188,9 +188,9 @@ namespace NSDocxRenderer
}
void CVectorGraphics::CurveTo(
const double &x1, const double &y1,
const double &x2, const double &y2,
const double &x3, const double &y3)
const double &x1, const double &y1,
const double &x2, const double &y2,
const double &x3, const double &y3)
{
double x0 = m_arData.back().points.back().x;
double y0 = m_arData.back().points.back().y;
@ -200,7 +200,7 @@ namespace NSDocxRenderer
m_arData.push_back({type, points});
std::vector<Point> curve_points = GetPointsCurve(
{Point{x0, y0}, Point{x1, y1}, Point{x2, y2}, Point{x3, y3}}, 0.1);
{Point{x0, y0}, Point{x1, y1}, Point{x2, y2}, Point{x3, y3}}, 0.1);
for(auto& point : curve_points)
CheckPoint(point);
@ -218,7 +218,7 @@ namespace NSDocxRenderer
ResetBorders();
}
void CVectorGraphics::Add(const CPathCommand& command)
void CVectorGraphics::Add(const PathCommand& command)
{
m_arData.push_back(command);
}
@ -279,9 +279,9 @@ namespace NSDocxRenderer
points.push_back(point);
CurveTo(
points[0].x, points[0].y,
points[1].x, points[1].y,
points[2].x, points[2].y);
points[0].x, points[0].y,
points[1].x, points[1].y,
points[2].x, points[2].y);
}
}
}
@ -302,9 +302,9 @@ namespace NSDocxRenderer
points.push_back(point);
renderer->PathCommandCurveTo(
points[0].x, points[0].y,
points[1].x, points[1].y,
points[2].x, points[2].y);
points[0].x, points[0].y,
points[1].x, points[1].y,
points[2].x, points[2].y);
}
}
}
@ -344,9 +344,9 @@ namespace NSDocxRenderer
points.push_back(point);
ret_value.CurveTo(
points[0].x, points[0].y,
points[1].x, points[1].y,
points[2].x, points[2].y);
points[0].x, points[0].y,
points[1].x, points[1].y,
points[2].x, points[2].y);
}
}
@ -370,13 +370,13 @@ namespace NSDocxRenderer
auto calc = [&curve] (double t) -> Point {
Point point;
point.x = pow(1 - t, 3) * curve[0].x +
3 * pow(1 - t, 2) * t * curve[1].x +
3 * (1 - t) * t * t * curve[2].x +
t * t * t * curve[3].x;
3 * pow(1 - t, 2) * t * curve[1].x +
3 * (1 - t) * t * t * curve[2].x +
t * t * t * curve[3].x;
point.y = pow(1 - t, 3) * curve[0].y +
3 * pow(1 - t, 2) * t * curve[1].y +
3 * (1 - t) * t * t * curve[2].y +
t * t * t * curve[3].y;
3 * pow(1 - t, 2) * t * curve[1].y +
3 * (1 - t) * t * t * curve[2].y +
t * t * t * curve[3].y;
return point;
};
@ -416,10 +416,10 @@ namespace NSDocxRenderer
double x = command.points.front().x;
double y = command.points.front().y;
if (fabs(x - last_x) <= std::numeric_limits<double>::epsilon())
if (x - last_x <= std::numeric_limits<double>::epsilon())
m_arVertical.push_back({std::min(last_y, y), std::max(last_y, y), x});
else if (fabs(y - last_y) <= std::numeric_limits<double>::epsilon())
else if (y - last_y <= std::numeric_limits<double>::epsilon())
m_arHorizontal.push_back({std::min(last_x, x), std::max(last_x, x), y});
}
if (!command.points.empty())

View File

@ -28,7 +28,7 @@ namespace NSDocxRenderer
pctClose = 3
};
struct CPathCommand
struct PathCommand
{
ePathCommandType type;
std::list<Point> points;
@ -50,7 +50,7 @@ namespace NSDocxRenderer
bool operator<=(const CVectorGraphics& other) const noexcept;
bool operator>=(const CVectorGraphics& other) const noexcept;
const std::list<CPathCommand>& GetData() const;
const std::list<PathCommand>& GetData() const;
double GetLeft() const noexcept;
double GetTop() const noexcept;
@ -64,12 +64,12 @@ namespace NSDocxRenderer
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);
const double& x1, const double& y1,
const double& x2, const double& y2,
const double& x3, const double& y3);
void Close();
void Add(const CPathCommand& command);
void Add(const PathCommand& command);
void Join(CVectorGraphics&& other);
void Clear();
@ -83,7 +83,7 @@ namespace NSDocxRenderer
static CVectorGraphics CalcBoolean(const CVectorGraphics& vg1, const CVectorGraphics& vg2, long clipType, long fillType = c_nWindingFillMode);
private:
std::list<CPathCommand> m_arData;
std::list<PathCommand> m_arData;
double m_dLeft;
double m_dTop;

View File

@ -1,15 +1,15 @@
#pragma once
#include <type_traits>
#include <limits>
#include <algorithm>
#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)));
}
// перемещает nullptr в конец и возвращает итератор, после которого начинаются nullptr
template<typename It>
It MoveNullptr(It start, It end)
{
@ -27,12 +27,3 @@ It MoveNullptr(It start, It end)
return right;
}
template <class T, class Cmp = std::less<T>>
bool CmpOrEqual(const T& val1,
const T& val2,
const T& eps = std::numeric_limits<T>::epsilon(),
const Cmp& cmp = Cmp())
{
return std::abs(val1 - val2) < eps || cmp(val1, val2);
}

View File

@ -1,976 +0,0 @@
/*
*(c) Copyright Ascensio System SIA 2010-2023
*
* 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-6 Ernesta Birznieka-Upish
* 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 "TextCommandRenderer.h"
#include <array>
#include "../../../DesktopEditor/graphics/pro/Graphics.h"
#include "Utils.h"
class CTextCommandRenderer::CTextCommandRendererImpl
{
public:
CTextCommandRendererImpl() = delete;
explicit CTextCommandRendererImpl(NSFonts::IApplicationFonts* pFonts);
CTextCommandRendererImpl(const CTextCommandRendererImpl& other) = delete;
CTextCommandRendererImpl(CTextCommandRendererImpl&& other) = delete;
virtual ~CTextCommandRendererImpl();
void BeginCommand(const DWORD& lType);
void EndCommand (const DWORD& lType);
void AddText(double x, double y, double w, double h);
void NewPage();
void SetFolder(const std::wstring& wsFolder);
Aggplus::CMatrix m_oTransform{};
NSStructures::CFont m_oFont{};
double m_dWidth = 0.0;
double m_dHeight = 0.0;
double m_dDpiX = c_dDpiX;
double m_dDpiY = c_dDpiY;
private:
void CreateFrame();
void ResetMinMax();
long GetNextColor();
std::unique_ptr<NSGraphics::IGraphicsRenderer> m_pRenderer{nullptr};
std::unique_ptr<CBgraFrame> m_pFrame{nullptr};
std::unique_ptr<NSFonts::IFontManager> m_pManager{nullptr};
double m_dXMin = c_dX_MIN_DEFAULT;
double m_dYMin = c_dY_MIN_DEFAULT;
double m_dXMax = c_dX_MAX_DEFAULT;
double m_dYMax = c_dY_MAX_DEFAULT;
double m_dPrevCenterX = 0;
double m_dPrevCenterY = 0;
bool m_bIsFirst = true;
std::wstring m_wsFolder = L"./output";
size_t m_nPage = 1;
const double m_dPenSizeRect = 0.6;
const double m_dPenSizeLine = 0.3;
const double m_dPenSizeDot = 1;
const std::wstring m_wsBaseFilename = L"page";
const std::wstring m_wsBaseExt = L".png";
const std::wstring m_wsBaseSep = L"/";
size_t m_nCurrColorIndex = 0;
const std::array<long, 20> m_arColors = {
0xFF400000, // Deep Red
0xFF800000, // Dark Red
0xFFFF0000, // Pure Red
0xFFFF4000, // Red-Orange
0xFFFF8000, // Orange
0xFFFFC000, // Light Orange
0xFFFFFF00, // Yellow
0xFFC0FF00, // Yellow-Green
0xFF80FF00, // Lime
0xFF40FF00, // Green-Yellow
0xFF00FF00, // Pure Green
0xFF00FF80, // Green-Cyan
0xFF00FFFF, // Cyan
0xFF0080FF, // Light Blue
0xFF0040FF, // Blue
0xFF0000FF, // Pure Blue
0xFF4000FF, // Blue-Purple
0xFF8000FF, // Purple
0xFFC000FF, // Violet
0xFFFF00FF // Magenta
};
};
CTextCommandRenderer::CTextCommandRendererImpl::CTextCommandRendererImpl(NSFonts::IApplicationFonts* pFonts)
: m_pRenderer(NSGraphics::Create()), m_pManager(pFonts->GenerateFontManager())
{
m_pManager->CreateOwnerCache(8);
}
CTextCommandRenderer::CTextCommandRendererImpl::~CTextCommandRendererImpl()
{
}
void CTextCommandRenderer::CTextCommandRendererImpl::BeginCommand(const DWORD& lType)
{
if (lType == c_nTextType)
{
if (!m_pFrame) CreateFrame();
ResetMinMax();
}
}
void CTextCommandRenderer::CTextCommandRendererImpl::EndCommand(const DWORD& lType)
{
if (lType == c_nPageType)
{
// if no text on the page
if (!m_pFrame) CreateFrame();
std::wstring filename = m_wsFolder + m_wsBaseSep + m_wsBaseFilename + std::to_wstring(m_nPage) + m_wsBaseExt;
m_pFrame->SaveFile(filename, _CXIMAGE_FORMAT_PNG);
m_pFrame = nullptr;
++m_nPage;
}
else if (lType == c_nTextType)
{
// 1. draw rect of command
double w = m_dXMax - m_dXMin;
double h = m_dYMax - m_dYMin;
m_pRenderer->BeginCommand(c_nPathType);
m_pRenderer->AddRect(m_dXMin, m_dYMin, w, h);
m_pRenderer->put_PenSize(m_dPenSizeRect);
long color = GetNextColor();
m_pRenderer->put_PenColor(color);
m_pRenderer->Stroke();
m_pRenderer->PathCommandEnd();
m_pRenderer->EndCommand(c_nPathType);
// 2. draw line from prev command to curr
double curr_center_x = m_dXMin + w / 2;
double curr_center_y = m_dYMin + h / 2;
if (m_bIsFirst)
{
m_bIsFirst = false;
m_dPrevCenterX = curr_center_x;
m_dPrevCenterY = curr_center_y;
return;
}
m_pRenderer->BeginCommand(c_nPathType);
m_pRenderer->PathCommandMoveTo(m_dPrevCenterX, m_dPrevCenterY);
m_pRenderer->PathCommandLineTo(curr_center_x, curr_center_y);
m_pRenderer->PathCommandClose();
m_pRenderer->put_PenSize(m_dPenSizeLine);
m_pRenderer->put_PenColor(0); // black color
m_pRenderer->Stroke();
m_pRenderer->PathCommandEnd();
m_pRenderer->EndCommand(c_nPathType);
m_dPrevCenterX = curr_center_x;
m_dPrevCenterY = curr_center_y;
// 3. draw a point of center
const double half_dot_size = m_dPenSizeDot / 2;
const double dot_x = curr_center_x - half_dot_size;
const double dot_y = curr_center_y - half_dot_size;
const double dot_w = m_dPenSizeDot;
const double dot_h = m_dPenSizeDot;
m_pRenderer->BeginCommand(c_nPathType);
m_pRenderer->AddRect(dot_x, dot_y, dot_w, dot_h);
m_pRenderer->put_PenSize(m_dPenSizeLine);
m_pRenderer->put_PenColor(0); // black color
m_pRenderer->Stroke();
m_pRenderer->PathCommandEnd();
m_pRenderer->EndCommand(c_nPathType);
}
}
void CTextCommandRenderer::CTextCommandRendererImpl::AddText(double x, double y, double w, double h)
{
MAYBE_UNUSED(h);
m_pManager->LoadFontFromFile(m_oFont.Path, (int)m_oFont.FaceIndex, (float)m_oFont.Size, c_dDpiX, c_dDpiY);
m_pManager->AfterLoad();
double line_height = m_pManager->GetLineHeight();
double em_height = m_pManager->GetUnitsPerEm();
h = c_dPtToMM * (line_height * m_oFont.Size) / em_height;
double x2 = x + w;
double y2 = y + h;
m_oTransform.TransformPoint(x, y);
m_oTransform.TransformPoint(x2, y2);
m_dXMin = std::min(m_dXMin, x);
m_dYMin = std::min(m_dYMin, y);
m_dXMax = std::max(m_dXMax, x2);
m_dYMax = std::max(m_dYMax, y2);
}
void CTextCommandRenderer::CTextCommandRendererImpl::NewPage()
{
ResetMinMax();
m_nCurrColorIndex = 0;
m_bIsFirst = true;
}
void CTextCommandRenderer::CTextCommandRendererImpl::SetFolder(const std::wstring& wsFolder)
{
m_wsFolder = wsFolder;
}
void CTextCommandRenderer::CTextCommandRendererImpl::CreateFrame()
{
long width_pix = static_cast<long>(m_dWidth * c_dMMToPix);
long height_pix = static_cast<long>(m_dHeight * c_dMMToPix);
const long step = 4;
const long stride = -step * width_pix;
m_pFrame = std::unique_ptr<CBgraFrame>(new CBgraFrame());
size_t data_size = width_pix * height_pix * step;
BYTE* data = new BYTE[data_size];
// white and alpha is min (full transparent)
for (long i = 0; i < width_pix * height_pix; ++i)
reinterpret_cast<unsigned int*>(data)[i] = 0xffffffff;
m_pFrame->put_Data(data);
m_pFrame->put_Height(height_pix);
m_pFrame->put_Width(width_pix);
m_pFrame->put_Stride(stride);
m_pRenderer->NewPage();
m_pRenderer->CreateFromBgraFrame(m_pFrame.get());
m_pRenderer->SetSwapRGB(true);
m_pRenderer->put_Width(m_dWidth);
m_pRenderer->put_Height(m_dHeight);
}
void CTextCommandRenderer::CTextCommandRendererImpl::ResetMinMax()
{
m_dXMin = c_dX_MIN_DEFAULT;
m_dYMin = c_dY_MIN_DEFAULT;
m_dXMax = c_dX_MAX_DEFAULT;
m_dYMax = c_dY_MAX_DEFAULT;
}
long CTextCommandRenderer::CTextCommandRendererImpl::GetNextColor()
{
m_nCurrColorIndex = (m_nCurrColorIndex + 1) % m_arColors.size();
return m_arColors[m_nCurrColorIndex];
}
CTextCommandRenderer::CTextCommandRenderer(NSFonts::IApplicationFonts* pFonts)
: m_pImpl(std::unique_ptr<CTextCommandRendererImpl>(new CTextCommandRendererImpl(pFonts)))
{
}
CTextCommandRenderer::~CTextCommandRenderer()
{
}
// base settings
HRESULT CTextCommandRenderer::get_Type(LONG* lType)
{
MAYBE_UNUSED(lType);
return S_FALSE;
}
HRESULT CTextCommandRenderer::NewPage()
{
m_pImpl->NewPage();
return S_OK;
}
HRESULT CTextCommandRenderer::get_Height(double* dHeight)
{
*dHeight = m_pImpl->m_dHeight;
return S_OK;
}
HRESULT CTextCommandRenderer::put_Height(const double& dHeight)
{
m_pImpl->m_dHeight = dHeight;
return S_OK;
}
HRESULT CTextCommandRenderer::get_Width(double* dWidth)
{
*dWidth = m_pImpl->m_dWidth;
return S_OK;
}
HRESULT CTextCommandRenderer::put_Width(const double& dWidth)
{
m_pImpl->m_dWidth = dWidth;
return S_OK;
}
HRESULT CTextCommandRenderer::get_DpiX(double* dDpiX)
{
*dDpiX = m_pImpl->m_dDpiX;
return S_OK;
}
HRESULT CTextCommandRenderer::get_DpiY(double* dDpiY)
{
*dDpiY = m_pImpl->m_dDpiY;
return S_OK;
}
// pen settings
HRESULT CTextCommandRenderer::get_PenColor(LONG* lColor)
{
MAYBE_UNUSED(lColor);
return S_FALSE;
}
HRESULT CTextCommandRenderer::put_PenColor(const LONG& lColor)
{
MAYBE_UNUSED(lColor);
return S_FALSE;
}
HRESULT CTextCommandRenderer::get_PenAlpha(LONG* lAlpha)
{
MAYBE_UNUSED(lAlpha);
return S_FALSE;
}
HRESULT CTextCommandRenderer::put_PenAlpha(const LONG& lAlpha)
{
MAYBE_UNUSED(lAlpha);
return S_FALSE;
}
HRESULT CTextCommandRenderer::get_PenSize(double* dSize)
{
MAYBE_UNUSED(dSize);
return S_FALSE;
}
HRESULT CTextCommandRenderer::put_PenSize(const double& dSize)
{
MAYBE_UNUSED(dSize);
return S_FALSE;
}
HRESULT CTextCommandRenderer::get_PenDashStyle(BYTE* nDashStyle)
{
MAYBE_UNUSED(nDashStyle);
return S_FALSE;
}
HRESULT CTextCommandRenderer::put_PenDashStyle(const BYTE& nDashStyle)
{
MAYBE_UNUSED(nDashStyle);
return S_FALSE;
}
HRESULT CTextCommandRenderer::get_PenLineStartCap(BYTE* nCapStyle)
{
MAYBE_UNUSED(nCapStyle);
return S_FALSE;
}
HRESULT CTextCommandRenderer::put_PenLineStartCap(const BYTE& nCapStyle)
{
MAYBE_UNUSED(nCapStyle);
return S_FALSE;
}
HRESULT CTextCommandRenderer::get_PenLineEndCap(BYTE* nCapStyle)
{
MAYBE_UNUSED(nCapStyle);
return S_FALSE;
}
HRESULT CTextCommandRenderer::put_PenLineEndCap(const BYTE& nCapStyle)
{
MAYBE_UNUSED(nCapStyle);
return S_FALSE;
}
HRESULT CTextCommandRenderer::get_PenLineJoin(BYTE* nJoinStyle)
{
MAYBE_UNUSED(nJoinStyle);
return S_FALSE;
}
HRESULT CTextCommandRenderer::put_PenLineJoin(const BYTE& nJoinStyle)
{
MAYBE_UNUSED(nJoinStyle);
return S_FALSE;
}
HRESULT CTextCommandRenderer::get_PenDashOffset(double* dOffset)
{
MAYBE_UNUSED(dOffset);
return S_FALSE;
}
HRESULT CTextCommandRenderer::put_PenDashOffset(const double& dOffset)
{
MAYBE_UNUSED(dOffset);
return S_FALSE;
}
HRESULT CTextCommandRenderer::get_PenAlign(LONG* lAlign)
{
MAYBE_UNUSED(lAlign);
return S_FALSE;
}
HRESULT CTextCommandRenderer::put_PenAlign(const LONG& lAlign)
{
MAYBE_UNUSED(lAlign);
return S_FALSE;
}
HRESULT CTextCommandRenderer::get_PenMiterLimit(double* dMiter)
{
MAYBE_UNUSED(dMiter);
return S_FALSE;
}
HRESULT CTextCommandRenderer::put_PenMiterLimit(const double& dMiter)
{
MAYBE_UNUSED(dMiter);
return S_FALSE;
}
HRESULT CTextCommandRenderer::PenDashPattern(double* pPattern, LONG lCount)
{
MAYBE_UNUSED(pPattern); MAYBE_UNUSED(lCount);
return S_FALSE;
}
// brush settings
HRESULT CTextCommandRenderer::get_BrushType(LONG* lType)
{
MAYBE_UNUSED(lType);
return S_FALSE;
}
HRESULT CTextCommandRenderer::put_BrushType(const LONG& lType)
{
MAYBE_UNUSED(lType);
return S_FALSE;
}
HRESULT CTextCommandRenderer::get_BrushColor1(LONG* lColor)
{
MAYBE_UNUSED(lColor);
return S_FALSE;
}
HRESULT CTextCommandRenderer::put_BrushColor1(const LONG& lColor)
{
MAYBE_UNUSED(lColor);
return S_FALSE;
}
HRESULT CTextCommandRenderer::get_BrushAlpha1(LONG* lAlpha)
{
MAYBE_UNUSED(lAlpha);
return S_FALSE;
}
HRESULT CTextCommandRenderer::put_BrushAlpha1(const LONG& lAlpha)
{
MAYBE_UNUSED(lAlpha);
return S_FALSE;
}
HRESULT CTextCommandRenderer::get_BrushColor2(LONG* lColor)
{
MAYBE_UNUSED(lColor);
return S_FALSE;
}
HRESULT CTextCommandRenderer::put_BrushColor2(const LONG& lColor)
{
MAYBE_UNUSED(lColor);
return S_FALSE;
}
HRESULT CTextCommandRenderer::get_BrushAlpha2(LONG* lAlpha)
{
MAYBE_UNUSED(lAlpha);
return S_FALSE;
}
HRESULT CTextCommandRenderer::put_BrushAlpha2(const LONG& lAlpha)
{
MAYBE_UNUSED(lAlpha);
return S_FALSE;
}
HRESULT CTextCommandRenderer::get_BrushTexturePath(std::wstring* wsPath)
{
MAYBE_UNUSED(wsPath);
return S_FALSE;
}
HRESULT CTextCommandRenderer::put_BrushTexturePath(const std::wstring& wsPath)
{
MAYBE_UNUSED(wsPath);
return S_FALSE;
}
HRESULT CTextCommandRenderer::get_BrushTextureMode(LONG* lMode)
{
MAYBE_UNUSED(lMode);
return S_FALSE;
}
HRESULT CTextCommandRenderer::put_BrushTextureMode(const LONG& lMode)
{
MAYBE_UNUSED(lMode);
return S_FALSE;
}
HRESULT CTextCommandRenderer::get_BrushTextureAlpha(LONG* lAlpha)
{
MAYBE_UNUSED(lAlpha);
return S_FALSE;
}
HRESULT CTextCommandRenderer::put_BrushTextureAlpha(const LONG& lAlpha)
{
MAYBE_UNUSED(lAlpha);
return S_FALSE;
}
HRESULT CTextCommandRenderer::get_BrushLinearAngle(double* dAngle)
{
MAYBE_UNUSED(dAngle);
return S_FALSE;
}
HRESULT CTextCommandRenderer::put_BrushLinearAngle(const double& dAngle)
{
MAYBE_UNUSED(dAngle);
return S_FALSE;
}
HRESULT CTextCommandRenderer::BrushRect(const INT& nVal,
const double& dLeft,
const double& dTop,
const double& dWidth,
const double& dHeight)
{
MAYBE_UNUSED(nVal); MAYBE_UNUSED(dLeft); MAYBE_UNUSED(dTop);
MAYBE_UNUSED(dWidth); MAYBE_UNUSED(dHeight);
return S_FALSE;
}
HRESULT CTextCommandRenderer::BrushBounds(const double& dLeft,
const double& dTop,
const double& dWidth,
const double& dHeight)
{
MAYBE_UNUSED(dLeft); MAYBE_UNUSED(dTop); MAYBE_UNUSED(dWidth); MAYBE_UNUSED(dHeight);
return S_FALSE;
}
HRESULT CTextCommandRenderer::put_BrushGradientColors(LONG* pColors,
double* pPositions,
LONG lCount)
{
MAYBE_UNUSED(pColors); MAYBE_UNUSED(pPositions); MAYBE_UNUSED(lCount);
return S_FALSE;
}
HRESULT CTextCommandRenderer::get_BrushTextureImage(Aggplus::CImage** pImage)
{
MAYBE_UNUSED(pImage);
return S_FALSE;
}
HRESULT CTextCommandRenderer::put_BrushTextureImage(Aggplus::CImage* pImage)
{
MAYBE_UNUSED(pImage);
return S_FALSE;
}
HRESULT CTextCommandRenderer::get_BrushTransform(Aggplus::CMatrix& oMatrix)
{
MAYBE_UNUSED(oMatrix);
return S_FALSE;
}
HRESULT CTextCommandRenderer::put_BrushTransform(const Aggplus::CMatrix& oMatrix)
{
MAYBE_UNUSED(oMatrix);
return S_FALSE;
}
void CTextCommandRenderer::put_BrushGradInfo(void* pGradInfo)
{
MAYBE_UNUSED(pGradInfo);
}
// font settings
HRESULT CTextCommandRenderer::get_FontName(std::wstring* wsName)
{
*wsName = m_pImpl->m_oFont.Name;
return S_OK;
}
HRESULT CTextCommandRenderer::put_FontName(const std::wstring& wsName)
{
m_pImpl->m_oFont.Name = wsName;
return S_OK;
}
HRESULT CTextCommandRenderer::get_FontPath(std::wstring* wsPath)
{
*wsPath = m_pImpl->m_oFont.Path;
return S_OK;
}
HRESULT CTextCommandRenderer::put_FontPath(const std::wstring& wsPath)
{
m_pImpl->m_oFont.Path = wsPath;
return S_OK;
}
HRESULT CTextCommandRenderer::get_FontSize(double* dSize)
{
*dSize = m_pImpl->m_oFont.Size;
return S_OK;
}
HRESULT CTextCommandRenderer::put_FontSize(const double& dSize)
{
m_pImpl->m_oFont.Size = dSize;
return S_OK;
}
HRESULT CTextCommandRenderer::get_FontStyle(LONG* lStyle)
{
*lStyle = m_pImpl->m_oFont.GetStyle();
return S_OK;
}
HRESULT CTextCommandRenderer::put_FontStyle(const LONG& lStyle)
{
m_pImpl->m_oFont.SetStyle(lStyle);
return S_OK;
}
HRESULT CTextCommandRenderer::get_FontStringGID(INT* bGid)
{
*bGid = m_pImpl->m_oFont.StringGID;
return S_OK;
}
HRESULT CTextCommandRenderer::put_FontStringGID(const INT& bGid)
{
m_pImpl->m_oFont.StringGID = bGid;
return S_OK;
}
HRESULT CTextCommandRenderer::get_FontCharSpace(double* dSpace)
{
*dSpace = m_pImpl->m_oFont.CharSpace;
return S_OK;
}
HRESULT CTextCommandRenderer::put_FontCharSpace(const double& dSpace)
{
m_pImpl->m_oFont.CharSpace = dSpace;
return S_OK;
}
HRESULT CTextCommandRenderer::get_FontFaceIndex(int* lFaceIndex)
{
*lFaceIndex = m_pImpl->m_oFont.FaceIndex;
return S_OK;
}
HRESULT CTextCommandRenderer::put_FontFaceIndex(const int& lFaceIndex)
{
m_pImpl->m_oFont.FaceIndex = lFaceIndex;
return S_OK;
}
// text commands
HRESULT CTextCommandRenderer::CommandDrawTextCHAR(const LONG& lUnicode,
const double& dX,
const double& dY,
const double& dW,
const double& dH)
{
MAYBE_UNUSED(lUnicode);
m_pImpl->AddText(dX, dY, dW, dH);
return S_OK;
}
HRESULT CTextCommandRenderer::CommandDrawTextExCHAR(const LONG& lUnicode,
const LONG& lGid,
const double& dX,
const double& dY,
const double& dW,
const double& dH)
{
MAYBE_UNUSED(lUnicode); MAYBE_UNUSED(lGid);
m_pImpl->AddText(dX, dY, dW, dH);
return S_OK;
}
HRESULT CTextCommandRenderer::CommandDrawText(const std::wstring& wsUnicodeText,
const double& dX,
const double& dY,
const double& dW,
const double& dH)
{
MAYBE_UNUSED(wsUnicodeText);
m_pImpl->AddText(dX, dY, dW, dH);
return S_OK;
}
HRESULT CTextCommandRenderer::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)
{
MAYBE_UNUSED(wsUnicodeText); MAYBE_UNUSED(pGids); MAYBE_UNUSED(nGidsCount);
m_pImpl->AddText(dX, dY, dW, dH);
return S_OK;
}
// command type
HRESULT CTextCommandRenderer::BeginCommand(const DWORD& lType)
{
m_pImpl->BeginCommand(lType);
return S_OK;
}
HRESULT CTextCommandRenderer::EndCommand(const DWORD& lType)
{
m_pImpl->EndCommand(lType);
return S_OK;
}
// graphic commands
HRESULT CTextCommandRenderer::PathCommandMoveTo(const double& dX, const double& dY)
{
MAYBE_UNUSED(dX); MAYBE_UNUSED(dY);
return S_FALSE;
}
HRESULT CTextCommandRenderer::PathCommandLineTo(const double& dX, const double& dY)
{
MAYBE_UNUSED(dX); MAYBE_UNUSED(dY);
return S_FALSE;
}
HRESULT CTextCommandRenderer::PathCommandLinesTo(double* pPoints, const int& nCount)
{
MAYBE_UNUSED(pPoints); MAYBE_UNUSED(nCount);
return S_FALSE;
}
HRESULT CTextCommandRenderer::PathCommandCurveTo(const double& dX1,
const double& dY1,
const double& dX2,
const double& dY2,
const double& dXe,
const double& dYe)
{
MAYBE_UNUSED(dX1); MAYBE_UNUSED(dY1); MAYBE_UNUSED(dX2);
MAYBE_UNUSED(dY2); MAYBE_UNUSED(dXe); MAYBE_UNUSED(dYe);
return S_FALSE;
}
HRESULT CTextCommandRenderer::PathCommandCurvesTo(double* pPoints, const int& nCount)
{
MAYBE_UNUSED(pPoints); MAYBE_UNUSED(nCount);
return S_FALSE;
}
HRESULT CTextCommandRenderer::PathCommandArcTo(const double& dX,
const double& dY,
const double& dW,
const double& dH,
const double& dStartAngle,
const double& dSweepAngle)
{
MAYBE_UNUSED(dX); MAYBE_UNUSED(dY); MAYBE_UNUSED(dW);
MAYBE_UNUSED(dH); MAYBE_UNUSED(dStartAngle); MAYBE_UNUSED(dSweepAngle);
return S_FALSE;
}
HRESULT CTextCommandRenderer::PathCommandClose()
{
return S_FALSE;
}
HRESULT CTextCommandRenderer::PathCommandEnd()
{
return S_FALSE;
}
HRESULT CTextCommandRenderer::DrawPath(const LONG& lType)
{
MAYBE_UNUSED(lType);
return S_FALSE;
}
HRESULT CTextCommandRenderer::PathCommandStart()
{
return S_FALSE;
}
HRESULT CTextCommandRenderer::PathCommandGetCurrentPoint(double* dX, double* dY)
{
MAYBE_UNUSED(dX); MAYBE_UNUSED(dY);
return S_FALSE;
}
HRESULT CTextCommandRenderer::PathCommandTextCHAR(const LONG& lUnicode,
const double& dX,
const double& dY,
const double& dW,
const double& dH)
{
MAYBE_UNUSED(lUnicode);
m_pImpl->AddText(dX, dY, dW, dH);
return S_OK;
}
HRESULT CTextCommandRenderer::PathCommandTextExCHAR(const LONG& lUnicode,
const LONG& lGid,
const double& dX,
const double& dY,
const double& dW,
const double& dH)
{
MAYBE_UNUSED(lUnicode); MAYBE_UNUSED(lGid);
m_pImpl->AddText(dX, dY, dW, dH);
return S_OK;
}
HRESULT CTextCommandRenderer::PathCommandText(const std::wstring& wsUnicodeText,
const double& dX,
const double& dY,
const double& dW,
const double& dH)
{
MAYBE_UNUSED(wsUnicodeText);
m_pImpl->AddText(dX, dY, dW, dH);
return S_OK;
}
HRESULT CTextCommandRenderer::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)
{
MAYBE_UNUSED(wsUnicodeText); MAYBE_UNUSED(pGids); MAYBE_UNUSED(nGidsCount);
m_pImpl->AddText(dX, dY, dW, dH);
return S_OK;
}
// image commands
HRESULT CTextCommandRenderer::DrawImage(IGrObject* pImage,
const double& dX,
const double& dY,
const double& dW,
const double& dH)
{
MAYBE_UNUSED(pImage); MAYBE_UNUSED(dX); MAYBE_UNUSED(dY);
MAYBE_UNUSED(dW); MAYBE_UNUSED(dH);
return S_FALSE;
}
HRESULT CTextCommandRenderer::DrawImageFromFile(const std::wstring& wsImagePath,
const double& dX,
const double& dY,
const double& dW,
const double& dH,
const BYTE& nAlpha)
{
MAYBE_UNUSED(wsImagePath); MAYBE_UNUSED(dX); MAYBE_UNUSED(dY);
MAYBE_UNUSED(dW); MAYBE_UNUSED(dH); MAYBE_UNUSED(nAlpha);
return S_FALSE;
}
// transform commands
HRESULT CTextCommandRenderer::SetTransform(const double& dM11,
const double& dM12,
const double& dM21,
const double& dM22,
const double& dX,
const double& dY)
{
m_pImpl->m_oTransform.SetElements(dM11, dM12, dM21, dM22, dX, dY);
return S_OK;
}
HRESULT CTextCommandRenderer::GetTransform(double* dM11,
double* dM12,
double* dM21,
double* dM22,
double* dX,
double* dY)
{
MAYBE_UNUSED(dM11); MAYBE_UNUSED(dM12); MAYBE_UNUSED(dM21);
MAYBE_UNUSED(dM22); MAYBE_UNUSED(dX); MAYBE_UNUSED(dY);
return S_FALSE;
}
HRESULT CTextCommandRenderer::ResetTransform()
{
m_pImpl->m_oTransform.Reset();
return S_OK;
}
HRESULT CTextCommandRenderer::get_ClipMode(LONG* lMode)
{
MAYBE_UNUSED(lMode);
return S_FALSE;
}
HRESULT CTextCommandRenderer::put_ClipMode(const LONG& lMode)
{
MAYBE_UNUSED(lMode);
return S_FALSE;
}
HRESULT CTextCommandRenderer::CommandLong(const LONG& lType, const LONG& lCommand)
{
MAYBE_UNUSED(lType); MAYBE_UNUSED(lCommand);
return S_FALSE;
}
HRESULT CTextCommandRenderer::CommandDouble(const LONG& lType, const double& dCommand)
{
MAYBE_UNUSED(lType); MAYBE_UNUSED(dCommand);
return S_FALSE;
}
HRESULT CTextCommandRenderer::CommandString(const LONG& lType, const std::wstring& sCommand)
{
MAYBE_UNUSED(lType); MAYBE_UNUSED(sCommand);
return S_FALSE;
}
HRESULT CTextCommandRenderer::IsSupportAdvancedCommand(const IAdvancedCommand::AdvancedCommandType& type)
{
MAYBE_UNUSED(type);
return S_FALSE;
}
HRESULT CTextCommandRenderer::AdvancedCommand(IAdvancedCommand* command)
{
MAYBE_UNUSED(command);
return S_FALSE;
}
void CTextCommandRenderer::Do(IOfficeDrawingFile* pFile, const std::wstring& wsFolder)
{
m_pImpl->SetFolder(wsFolder);
int pages_count = pFile->GetPagesCount();
for (int i = 0; i < pages_count; ++i)
DrawPage(pFile, i);
}
void CTextCommandRenderer::DrawPage(IOfficeDrawingFile* pFile, int nPage)
{
NewPage();
double width, height, dpi_x, dpi_y;
pFile->GetPageInfo(nPage, &width, &height, &dpi_x, &dpi_y);
width *= 25.4 / dpi_x;
height *= 25.4 / dpi_y;
put_Width(width);
put_Height(height);
pFile->DrawPageOnRenderer(this, nPage, nullptr);
}

View File

@ -1,305 +0,0 @@
/*
* (c) Copyright Ascensio System SIA 2010-2023
*
* 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-6 Ernesta Birznieka-Upish
* 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 <memory>
#include "../../../DesktopEditor/graphics/IRenderer.h"
#include "../../../DesktopEditor/graphics/pro/officedrawingfile.h"
#include "../../../DesktopEditor/graphics/pro/Fonts.h"
#ifndef TEXTCOMMANDRENDERER_USE_DYNAMIC_LIBRARY
#define TEXTCOMMANDRENDERER_DECL_EXPORT
#else
#include "../../../DesktopEditor/common/base_export.h"
#define TEXTCOMMANDRENDERER_DECL_EXPORT Q_DECL_EXPORT
#endif
class TEXTCOMMANDRENDERER_DECL_EXPORT CTextCommandRenderer : public IRenderer
{
public:
CTextCommandRenderer() = delete;
explicit CTextCommandRenderer(NSFonts::IApplicationFonts* pFonts);
CTextCommandRenderer(const CTextCommandRenderer& other) = delete;
CTextCommandRenderer(CTextCommandRenderer&& other) = delete;
virtual ~CTextCommandRenderer();
// base settings
virtual HRESULT get_Type (LONG* lType) override;
virtual HRESULT NewPage () override;
virtual HRESULT get_Height(double* dHeight) override;
virtual HRESULT put_Height(const double& dHeight) override;
virtual HRESULT get_Width (double* dWidth) override;
virtual HRESULT put_Width (const double& dWidth) override;
virtual HRESULT get_DpiX (double* dDpiX) override;
virtual HRESULT get_DpiY (double* dDpiY) override;
// pen settings
virtual HRESULT get_PenColor(LONG* lColor) override;
virtual HRESULT put_PenColor(const LONG& lColor) override;
virtual HRESULT get_PenAlpha(LONG* lAlpha) override;
virtual HRESULT put_PenAlpha(const LONG& lAlpha) override;
virtual HRESULT get_PenSize(double* dSize) override;
virtual HRESULT put_PenSize(const double& dSize) override;
virtual HRESULT get_PenDashStyle(BYTE* nDashStyle) override;
virtual HRESULT put_PenDashStyle(const BYTE& nDashStyle) override;
virtual HRESULT get_PenLineStartCap(BYTE* nCapStyle) override;
virtual HRESULT put_PenLineStartCap(const BYTE& nCapStyle) override;
virtual HRESULT get_PenLineEndCap(BYTE* nCapStyle) override;
virtual HRESULT put_PenLineEndCap(const BYTE& nCapStyle) override;
virtual HRESULT get_PenLineJoin(BYTE* nJoinStyle) override;
virtual HRESULT put_PenLineJoin(const BYTE& nJoinStyle) override;
virtual HRESULT get_PenDashOffset(double* dOffset) override;
virtual HRESULT put_PenDashOffset(const double& dOffset) override;
virtual HRESULT get_PenAlign(LONG* lAlign) override;
virtual HRESULT put_PenAlign(const LONG& lAlign) override;
virtual HRESULT get_PenMiterLimit(double* dMiter) override;
virtual HRESULT put_PenMiterLimit(const double& dMiter) override;
virtual HRESULT PenDashPattern(double* pPattern, LONG lCount) override;
// brush settings
virtual HRESULT get_BrushType(LONG* lType) override;
virtual HRESULT put_BrushType(const LONG& lType)override;
virtual HRESULT get_BrushColor1(LONG* lColor) override;
virtual HRESULT put_BrushColor1(const LONG& lColor) override;
virtual HRESULT get_BrushAlpha1(LONG* lAlpha) override;
virtual HRESULT put_BrushAlpha1(const LONG& lAlpha) override;
virtual HRESULT get_BrushColor2(LONG* lColor) override;
virtual HRESULT put_BrushColor2(const LONG& lColor) override;
virtual HRESULT get_BrushAlpha2(LONG* lAlpha) override;
virtual HRESULT put_BrushAlpha2(const LONG& lAlpha) override;
virtual HRESULT get_BrushTexturePath(std::wstring* wsPath) override;
virtual HRESULT put_BrushTexturePath(const std::wstring& wsPath) override;
virtual HRESULT get_BrushTextureMode(LONG* lMode) override;
virtual HRESULT put_BrushTextureMode(const LONG& lMode) override;
virtual HRESULT get_BrushTextureAlpha(LONG* lAlpha) override;
virtual HRESULT put_BrushTextureAlpha(const LONG& lAlpha) override;
virtual HRESULT get_BrushLinearAngle(double* dAngle) override;
virtual HRESULT put_BrushLinearAngle(const double& dAngle) override;
virtual HRESULT BrushRect (const INT& nVal,
const double& dLeft,
const double& dTop,
const double& dWidth,
const double& dHeight) override;
virtual HRESULT BrushBounds(const double& dLeft,
const double& dTop,
const double& dWidth,
const double& dHeight) override;
virtual HRESULT put_BrushGradientColors(LONG* pColors,
double* pPositions,
LONG lCount) override;
virtual HRESULT get_BrushTextureImage(Aggplus::CImage** pImage) override;
virtual HRESULT put_BrushTextureImage(Aggplus::CImage* pImage) override;
virtual HRESULT get_BrushTransform(Aggplus::CMatrix& oMatrix) override;
virtual HRESULT put_BrushTransform(const Aggplus::CMatrix& oMatrix) override;
virtual void put_BrushGradInfo(void* pGradInfo) override;
// font settings
virtual HRESULT get_FontName(std::wstring* wsName) override;
virtual HRESULT put_FontName(const std::wstring& wsName) override;
virtual HRESULT get_FontPath(std::wstring* wsPath) override;
virtual HRESULT put_FontPath(const std::wstring& wsPath) override;
virtual HRESULT get_FontSize(double* dSize) override;
virtual HRESULT put_FontSize(const double& dSize) override;
virtual HRESULT get_FontStyle(LONG* lStyle) override;
virtual HRESULT put_FontStyle(const LONG& lStyle) override;
virtual HRESULT get_FontStringGID(INT* bGid) override;
virtual HRESULT put_FontStringGID(const INT& bGid) override;
virtual HRESULT get_FontCharSpace(double* dSpace) override;
virtual HRESULT put_FontCharSpace(const double& dSpace) override;
virtual HRESULT get_FontFaceIndex(int* lFaceIndex) override;
virtual HRESULT put_FontFaceIndex(const int& lFaceIndex) override;
// text commands
virtual HRESULT CommandDrawTextCHAR(const LONG& lUnicode,
const double& dX,
const double& dY,
const double& dW,
const double& dH) override;
virtual HRESULT CommandDrawTextExCHAR(const LONG& lUnicode,
const LONG& lGid,
const double& dX,
const double& dY,
const double& dW,
const double& dH) override;
virtual HRESULT CommandDrawText(const std::wstring& wsUnicodeText,
const double& dX,
const double& dY,
const double& dW,
const double& dH) override;
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) override;
// command type
virtual HRESULT BeginCommand(const DWORD& lType) override;
virtual HRESULT EndCommand(const DWORD& lType) override;
// graphic commands
virtual HRESULT PathCommandMoveTo (const double& dX, const double& dY) override;
virtual HRESULT PathCommandLineTo (const double& dX, const double& dY) override;
virtual HRESULT PathCommandLinesTo (double* pPoints, const int& nCount) override;
virtual HRESULT PathCommandCurveTo (const double& dX1,
const double& dY1,
const double& dX2,
const double& dY2,
const double& dXe,
const double& dYe) override;
virtual HRESULT PathCommandCurvesTo(double* pPoints, const int& nCount) override;
virtual HRESULT PathCommandArcTo (const double& dX,
const double& dY,
const double& dW,
const double& dH,
const double& dStartAngle,
const double& dSweepAngle) override;
virtual HRESULT PathCommandClose () override;
virtual HRESULT PathCommandEnd () override;
virtual HRESULT DrawPath (const LONG& lType) override;
virtual HRESULT PathCommandStart () override;
virtual HRESULT PathCommandGetCurrentPoint(double* dX, double* dY) override;
virtual HRESULT PathCommandTextCHAR(const LONG& lUnicode,
const double& dX,
const double& dY,
const double& dW,
const double& dH) override;
virtual HRESULT PathCommandTextExCHAR(const LONG& lUnicode,
const LONG& lGid,
const double& dX,
const double& dY,
const double& dW,
const double& dH) override;
virtual HRESULT PathCommandText(const std::wstring& wsUnicodeText,
const double& dX,
const double& dY,
const double& dW,
const double& dH) override;
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) override;
// image commands
virtual HRESULT DrawImage(IGrObject* pImage,
const double& dX,
const double& dY,
const double& dW,
const double& dH) override;
virtual HRESULT DrawImageFromFile(const std::wstring& wsImagePath,
const double& dX,
const double& dY,
const double& dW,
const double& dH,
const BYTE& nAlpha = 255) override;
// transform commands
virtual HRESULT SetTransform(const double& dM11,
const double& dM12,
const double& dM21,
const double& dM22,
const double& dX,
const double& dY) override;
virtual HRESULT GetTransform(double* dM11,
double* dM12,
double* dM21,
double* dM22,
double* dX,
double* dY) override;
virtual HRESULT ResetTransform() override;
virtual HRESULT get_ClipMode(LONG* lMode) override;
virtual HRESULT put_ClipMode(const LONG& lMode) override;
// advanced
virtual HRESULT CommandLong(const LONG& lType, const LONG& lCommand) override;
virtual HRESULT CommandDouble(const LONG& lType, const double& dCommand) override;
virtual HRESULT CommandString(const LONG& lType, const std::wstring& sCommand) override;
virtual HRESULT IsSupportAdvancedCommand(const IAdvancedCommand::AdvancedCommandType& type) override;
virtual HRESULT AdvancedCommand(IAdvancedCommand* command) override;
// main methods
void Do(IOfficeDrawingFile* pFile, const std::wstring& wsFolder = L"./output");
void DrawPage(IOfficeDrawingFile* pFile, int nPage);
private:
class CTextCommandRendererImpl;
std::unique_ptr<CTextCommandRendererImpl> m_pImpl;
};

View File

@ -1,32 +0,0 @@
QT -= core gui
VERSION = 1.0.0
TARGET = TextCommandRenderer
TEMPLATE = lib
CONFIG += c++11
CONFIG += shared
CONFIG += plugin
CORE_ROOT_DIR = $$PWD/../../../
PWD_ROOT_DIR = $$PWD
include(../../../Common/base.pri)
DEFINES += TEXTCOMMANDRENDERER_USE_DYNAMIC_LIBRARY
ADD_DEPENDENCY(UnicodeConverter, kernel, graphics)
core_windows {
LIBS += \
-lgdi32 \
-ladvapi32 \
-luser32 \
-lshell32
}
HEADERS += \
TextCommandRenderer.h \
Utils.h
SOURCES += \
TextCommandRenderer.cpp

View File

@ -1,17 +0,0 @@
#pragma once
#define MAYBE_UNUSED(x) (void)(x)
const double c_dDpiX = 72.0;
const double c_dDpiY = 72.0;
constexpr double c_dMMToPix = 72.0 / 25.4;
constexpr double c_dPixToMM = 25.4 / 72.0;
constexpr double c_dMMToPt = 72.0 / 25.4;
constexpr double c_dPtToMM = 25.4 / 72.0;
const double c_dX_MIN_DEFAULT = 10000;
const double c_dY_MIN_DEFAULT = 10000;
const double c_dX_MAX_DEFAULT = -10000;
const double c_dY_MAX_DEFAULT = -10000;

View File

@ -40,8 +40,6 @@
#include "../DocxRenderer.h"
#include "../../Common/OfficeFileFormatChecker.h"
#include "TextCommandRenderer/TextCommandRenderer.h"
#include <fstream>
#ifdef TEST_FOR_HTML_RENDERER_TEXT
@ -77,8 +75,6 @@ int main(int argc, char *argv[])
oWorker.m_sDirectory = NSFile::GetProcessDirectory() + L"/fonts_cache";
oWorker.m_bIsNeedThumbnails = false;
// oWorker.m_arAdditionalFolders.push_back(L"");
if (!NSDirectory::Exists(oWorker.m_sDirectory))
NSDirectory::CreateDirectory(oWorker.m_sDirectory);
@ -182,10 +178,6 @@ int main(int argc, char *argv[])
// auto shapes = oDocxRenderer.ScanPagePptx(pReader, 0);
// for (auto& s : shapes)
// fin << U_TO_UTF8(s);
CTextCommandRenderer oTextCommandRenderer(pFonts);
oTextCommandRenderer.Do(pReader);
#endif
RELEASEOBJECT(pReader);
RELEASEOBJECT(pExternalImagheStorage);

View File

@ -10,7 +10,7 @@ CORE_ROOT_DIR = $$PWD/../..
PWD_ROOT_DIR = $$PWD
include($$CORE_ROOT_DIR/Common/base.pri)
ADD_DEPENDENCY(UnicodeConverter, kernel, kernel_network, graphics, PdfFile, DjVuFile, XpsFile, DocxRenderer, TextCommandRenderer)
ADD_DEPENDENCY(UnicodeConverter, kernel, kernel_network, graphics, PdfFile, DjVuFile, XpsFile, DocxRenderer)
core_linux:include($$PWD/../../Common/3dParty/icu/icu.pri)
core_windows:LIBS += -lgdi32 -ladvapi32 -luser32 -lshell32

View File

@ -264,7 +264,6 @@ struct CTextSettings
bool bAddSpaces; // Добавлять пробелы перед текстом?
bool bMergeText; // Объединять подяр идущий текст в 1?
int nLi; // Уровень списка
bool bNumberingLi; // Является ли список нумерованным
std::wstring sPStyle;
@ -278,12 +277,11 @@ struct CTextSettings
NSCSS::CCompiledStyle oAdditionalStyle;
CTextSettings()
: bBdo(false), bPre(false), bQ(false), bAddSpaces(true), bMergeText(false), nLi(-1), bNumberingLi(false), eTextMode(Normal)
: bBdo(false), bPre(false), bQ(false), bAddSpaces(true), bMergeText(false), nLi(-1), eTextMode(Normal)
{}
CTextSettings(const CTextSettings& oTS) :
bBdo(oTS.bBdo), bPre(oTS.bPre), bQ(oTS.bQ), bAddSpaces(oTS.bAddSpaces), bMergeText(oTS.bMergeText),
nLi(oTS.nLi),bNumberingLi(oTS.bNumberingLi), sPStyle(oTS.sPStyle), eTextMode(oTS.eTextMode)
bBdo(oTS.bBdo), bPre(oTS.bPre), bQ(oTS.bQ), bAddSpaces(oTS.bAddSpaces), bMergeText(oTS.bMergeText), nLi(oTS.nLi), sPStyle(oTS.sPStyle), eTextMode(oTS.eTextMode)
{}
void AddPStyle(const std::wstring& wsStyle)
@ -2290,9 +2288,6 @@ private:
{
oNode.m_wsId = EncodeXmlString(m_oLightReader.GetText());
WriteBookmark(oXml, oNode.m_wsId);
if (!m_oStylesCalculator.HaveStylesById(oNode.m_wsId))
oNode.m_wsId.clear();
}
else if(sName == L"style")
oNode.m_wsStyle += m_oLightReader.GetText();
@ -2386,30 +2381,7 @@ private:
std::wstring sText = m_oLightReader.GetText();
if (sText.empty())
return false;
m_oStylesCalculator.CalculateCompiledStyle(arSelectors);
bool bPre = oTS.bPre;
if (!bPre && nullptr != arSelectors.back().m_pCompiledStyle)
{
NSCSS::CCompiledStyle* pCompiledStyle{arSelectors.back().m_pCompiledStyle};
// TODO::поведение должно быть немного разное (реализовать)
switch(pCompiledStyle->m_oDisplay.GetWhiteSpace().ToInt())
{
case NSCSS::NSProperties::EWhiteSpace::Pre:
case NSCSS::NSProperties::EWhiteSpace::Pre_Wrap:
case NSCSS::NSProperties::EWhiteSpace::Pre_Line:
bPre = true;
default:
break;
}
}
if (!bPre && sText.end() == std::find_if_not(sText.begin(), sText.end(), [](wchar_t wchChar){ return iswspace(wchChar) && 0xa0 != wchChar;}))
if (sText.end() == std::find_if_not(sText.begin(), sText.end(), [](wchar_t wchChar){ return iswspace(wchChar) && 0xa0 != wchChar;}))
return false;
if(oTS.bBdo)
@ -2417,14 +2389,22 @@ private:
const bool bInT = m_oState.m_bInT;
if (oTS.bPre)
{
CloseT(pXml);
CloseR(pXml);
}
GetSubClass(pXml, arSelectors);
//TODO:: сделать так, чтобы параграф (со своими стилями) открывался при чтении сооответствующей ноды, а не при чтении текста
if (oTS.bAddSpaces && m_oState.m_bInP && !m_oState.m_bInR && !iswspace(sText.front()) && !m_oState.m_bWasSpace && CTextSettings::Normal == oTS.eTextMode)
WriteSpace(pXml);
OpenP(pXml);
NSStringUtils::CStringBuilder oPPr;
const std::wstring sPStyle = wrP(&oPPr, arSelectors, oTS);
std::wstring sPStyle = wrP(&oPPr, arSelectors, oTS);
WriteToStringBuilder(oPPr, *pXml);
@ -2444,79 +2424,89 @@ private:
if (oTS.bQ)
pXml->WriteString(L"<w:t xml:space=\"preserve\">&quot;</w:t>");
if (!bPre && oTS.bAddSpaces && m_oState.m_bInP && !m_oState.m_bInR && !iswspace(sText.front()) && !iswpunct(sText.front()) && !m_oState.m_bWasSpace && CTextSettings::Normal == oTS.eTextMode)
WriteSpace(pXml);
if(bPre)
if(oTS.bPre)
{
size_t unBegin = 0, unEnd = sText.find_first_of(L"\n\r\t");
if (L'\n' == sText.front() || L'\r' == sText.front())
sText.erase(0, 1);
while (std::wstring::npos != unBegin)
size_t nAfter = sText.find_first_of(L"\n\r\t");
while(nAfter != std::wstring::npos)
{
if (OpenR(pXml))
if (L'\t' == sText[0])
{
pXml->WriteString(L"<w:test/>");
WriteToStringBuilder(oRPr, *pXml);
pXml->WriteString(L"<w:tab/>");
sText.erase(0, 1);
if (0 == nAfter)
{
nAfter = sText.find_first_of(L"\n\r\t");
continue;
}
nAfter--;
}
OpenT(pXml);
if (unEnd == std::wstring::npos)
{
pXml->WriteEncodeXmlString(sText.c_str() + unBegin, sText.length() - unBegin);
break;
}
pXml->WriteEncodeXmlString(sText.c_str(), nAfter);
CloseT(pXml);
CloseR(pXml);
if (unBegin != unEnd)
if (L'\t' == sText[nAfter])
{
pXml->WriteEncodeXmlString(sText.c_str() + unBegin, unEnd - unBegin);
CloseT(pXml);
sText.erase(0, nAfter);
nAfter = 1;
}
else
{
CloseP(pXml, arSelectors);
OpenP(pXml);
WriteToStringBuilder(oPPr, *pXml);
sText.erase(0, nAfter + 1);
nAfter = 0;
}
OpenR(pXml);
WriteToStringBuilder(oRPr, *pXml);
nAfter = sText.find_first_of(L"\n\r\t", nAfter);
}
if (L'\n' == sText[unEnd])
{
pXml->WriteString(L"<w:br/>");
}
else if (L'\t' == sText[unEnd])
{
pXml->WriteString(L"<w:tab/>");
}
unBegin = unEnd + 1;
unEnd = sText.find_first_of(L"\n\r\t", unBegin);
if (sText.empty())
{
arSelectors.pop_back();
return true;
}
}
else
{
ReplaceSpaces(sText);
if (!sText.empty() && L'\t' == sText[0])
{
pXml->WriteString(L"<w:tab/>");
sText.erase(0, 1);
}
if (!sText.empty() && L'\t' == sText[0])
{
pXml->WriteString(L"<w:tab/>");
sText.erase(0, 1);
}
if (!sText.empty() && std::iswspace(sText.front()) && m_oState.m_bWasSpace)
sText.erase(0, 1);
if (!oTS.bPre && !sText.empty() && std::iswspace(sText.front()) && m_oState.m_bWasSpace)
sText.erase(0, 1);
if (!sText.empty())
{
OpenT(pXml);
if (oTS.bMergeText && !m_oState.m_bWasSpace && bInT && !bPre)
if (oTS.bMergeText && !m_oState.m_bWasSpace && bInT && !oTS.bPre)
pXml->WriteEncodeXmlString(L" ");
if (!sText.empty())
{
m_oState.m_bWasSpace = std::iswspace(sText.back());
pXml->WriteEncodeXmlString(sText);
}
m_oState.m_bWasSpace = std::iswspace(sText.back());
pXml->WriteEncodeXmlString(sText);
}
if (oTS.bQ)
pXml->WriteString(L"<w:t xml:space=\"preserve\">&quot;</w:t>");
CloseT(pXml);
if (!oTS.bMergeText)
{
CloseT(pXml);
CloseR(pXml);
}
arSelectors.pop_back();
return true;
@ -2626,6 +2616,7 @@ private:
CTextSettings oTSR(oTS);
oTSR.oAdditionalStyle.m_oFont.SetFamily(L"Courier New", UINT_MAX, true);
oTSR.oAdditionalStyle.m_oFont.SetSize(20, UINT_MAX, true);
return readStream(pXml, arSelectors, oTSR);
}
@ -2766,10 +2757,7 @@ private:
if (NULL == pXml || arSelectors.empty() || arSelectors.back().m_wsClass == L"MsoFootnoteReference")
return false;
CTextSettings oTSR(oTS);
oTSR.bAddSpaces = false;
return readStream(pXml, arSelectors, oTSR);
return readStream(pXml, arSelectors, oTS);
}
bool ReadNobr(NSStringUtils::CStringBuilder* pXml, std::vector<NSCSS::CNode>& arSelectors, CTextSettings& oTS)
@ -3934,8 +3922,6 @@ private:
CTextSettings oTSLiP(oTS);
oTSLiP.bNumberingLi = !bType;
std::wstring wsValue;
const std::wstring wsParentName{(!sSelectors.empty()) ? sSelectors.back().m_wsName : L""};
@ -3958,11 +3944,27 @@ private:
oTSLiP.oAdditionalStyle.m_oText.SetColor(L"#808080", NEXT_LEVEL);
else if (L"selected" == wsArgumentName)
oTSLiP.oAdditionalStyle.m_oText.SetDecoration(L"underline", NEXT_LEVEL);
// oTSLiP.AddRStyle(L"<w:u w:val=\"single\"/>");
}
m_oLightReader.MoveToElement();
if (std::wstring::npos != oTS.sPStyle.find(L"<w:numPr>"))
{
wrP(oXml, sSelectors, oTS);
CloseP(oXml, sSelectors);
oTSLiP.sPStyle.clear();
}
oTSLiP.nLi++;
const std::wstring wsOldPStyle{oTSLiP.sPStyle};
oTSLiP.sPStyle += L"<w:numPr><w:ilvl w:val=\"" + std::to_wstring(oTSLiP.nLi) + L"\"/><w:numId w:val=\"" +
(bType ? L"1" : std::to_wstring(m_nNumberingId + 1)) + L"\"/></w:numPr>";
wrP(oXml, sSelectors, oTSLiP);
oTSLiP.sPStyle = wsOldPStyle;
if (!wsValue.empty())
{
OpenR(oXml);
@ -4093,8 +4095,6 @@ private:
{
if (m_oState.m_bInHyperlink)
{
CloseT(oXml);
CloseR(oXml);
oXml->WriteString(L"</w:hyperlink>");
m_oState.m_bInHyperlink = false;
}
@ -4369,7 +4369,7 @@ private:
if (sPStyle.empty() && !ElementInTable(sSelectors))
sPStyle = L"normal-web";
if (sPStyle.empty() && oTS.sPStyle.empty() && 0 > oTS.nLi)
if (sPStyle.empty() && oTS.sPStyle.empty())
return L"";
m_oXmlStyle.WriteLitePStyle(oTS.oAdditionalStyle);
@ -4385,10 +4385,6 @@ private:
oXml->WriteString(L"\"/>");
}
if (oTS.nLi >= 0)
oXml->WriteString(L"<w:numPr><w:ilvl w:val=\"" + std::to_wstring(oTS.nLi) + L"\"/><w:numId w:val=\"" +
(!oTS.bNumberingLi ? L"1" : std::to_wstring(m_nNumberingId + 1)) + L"\"/></w:numPr>");
oXml->WriteString(oTS.sPStyle + sPSettings);
oXml->WriteNodeEnd(L"w:pPr");
m_oState.m_bWasPStyle = true;

View File

@ -108,7 +108,7 @@ namespace NSStringFinder
wsEndingValue.pop_back();
wsRegexValue += L"\\s*[" + wsEndingValue + L"]?(.[^" + wsEndingValue + L"]*)\\s*[" + wsEndingValue + L"]?";
wsRegexValue += L"\\s*(.[^" + wsEndingValue + L"]*)\\s*[" + wsEndingValue + L"]?";
}
else
wsRegexValue += L"\\s*(.*)[\\n|\\r]?";

View File

@ -28,7 +28,6 @@ SOURCES += \
HwpDoc/Conversion/FootnoteConverter.cpp \
HwpDoc/Conversion/NumberingConverter.cpp \
HwpDoc/Conversion/OleConverter.cpp \
HwpDoc/Conversion/StyleConverter.cpp \
HwpDoc/HWPDocInfo.cpp \
HwpDoc/HWPElements/HWPRecord.cpp \
HwpDoc/HWPElements/HWPRecordBinData.cpp \
@ -101,12 +100,10 @@ HEADERS += \
HwpDoc/Common/Common.h \
HwpDoc/Common/XMLNode.h \
HwpDoc/Common/WriterContext.h \
HwpDoc/Conversion/ConversionState.h \
HwpDoc/Conversion/Converter2OOXML.h \
HwpDoc/Conversion/FootnoteConverter.h \
HwpDoc/Conversion/NumberingConverter.h \
HwpDoc/Conversion/OleConverter.h \
HwpDoc/Conversion/StyleConverter.h \
HwpDoc/Conversion/Transform.h \
HwpDoc/Conversion/Types.h \
HwpDoc/Errors.h \

View File

@ -250,7 +250,7 @@ const CHWPRecordNumbering* CWriterContext::GetNumbering(short shId)
if (nullptr == pDocInfo)
return nullptr;
return (CHWPRecordNumbering*)pDocInfo->GetNumbering(shId - 1);
return (CHWPRecordNumbering*)pDocInfo->GetNumbering(shId);
}
const CHWPRecordBullet* CWriterContext::GetBullet(short shId)
@ -299,8 +299,7 @@ bool CWriterContext::GetBinBytes(const HWP_STRING& sId, CHWPStream& oBuffer, HWP
if (nullptr == pBinData)
return false;
if (EType::LINK == pBinData->GetType() ||
EType::EMBEDDING == pBinData->GetType())
if (EType::LINK == pBinData->GetType())
{
switch (m_eType)
{
@ -310,28 +309,30 @@ bool CWriterContext::GetBinBytes(const HWP_STRING& sId, CHWPStream& oBuffer, HWP
return m_pHWPXFile->GetChildStream(pBinData->GetPath(), oBuffer);
}
default:
break;
return false;
}
}
std::wostringstream oStringStream;
switch (m_eType)
else
{
case EHanType::HWP:
std::wostringstream oStringStream;
switch (m_eType)
{
oStringStream << L"BIN" << std::setw(4) << std::setfill(L'0') << std::hex << pBinData->GetBinDataID() << L"." << pBinData->GetFormat();
sFileName = oStringStream.str();
return m_pHWPFile->GetChildStream(oStringStream.str(), pBinData->GetCompressed(), oBuffer);
case EHanType::HWP:
{
oStringStream << L"BIN" << std::setw(4) << std::setfill(L'0') << std::hex << pBinData->GetBinDataID() << L"." << pBinData->GetFormat();
sFileName = oStringStream.str();
return m_pHWPFile->GetChildStream(oStringStream.str(), pBinData->GetCompressed(), oBuffer);
}
case EHanType::HWPX:
{
oStringStream << sId << L"." << pBinData->GetFormat();
sFileName = oStringStream.str();
return m_pHWPXFile->GetChildStream(L"BinData/" + oStringStream.str(), oBuffer);
}
default:
return false;
}
case EHanType::HWPX:
{
oStringStream << sId << L"." << pBinData->GetFormat();
sFileName = oStringStream.str();
return m_pHWPXFile->GetChildStream(L"BinData/" + oStringStream.str(), oBuffer);
}
default:
break;
}
return false;

View File

@ -1,76 +0,0 @@
#ifndef CONVERSIONSTATE_H
#define CONVERSIONSTATE_H
#include "Types.h"
#include "../Paragraph/CtrlHeadFoot.h"
#include "../Paragraph/CtrlSectionDef.h"
#include "../Paragraph/CtrlPageNumPos.h"
#include "../Paragraph/CtrlNewNumber.h"
#include "../Paragraph/CtrlColumnDef.h"
#include "../Paragraph/CtrlField.h"
namespace HWP
{
struct TConversionState
{
bool m_bOpenedP;
bool m_bOpenedR;
bool m_bIsNote;
bool m_bInTable;
struct TLastNode
{
unsigned int m_unParaIndex;
enum class ELastNodeType
{
Empty,
Paragraph,
Table
} m_eType;
TLastNode()
: m_unParaIndex(0), m_eType(ELastNodeType::Empty)
{}
void Clear()
{
m_unParaIndex = 0;
m_eType = ELastNodeType::Empty;
}
} m_oLastNode;
bool m_bInTextBox; // TODO:: используется, чтобы в wps:txbx не появилась новая фигура (посмотреть этот момент нужно подробнее)
unsigned short m_ushLastCharShapeId;
unsigned short m_ushSecdIndex;
unsigned int m_unParaIndex;
VECTOR<const CCtrlHeadFoot*> m_arCtrlsHeadFoot; //only for hwpx
std::stack<int> m_arOpenedBookmarks;
const CCtrlSectionDef* m_pSectionDef;
const CCtrlColumnDef* m_pColumnDef;
const CCtrlPageNumPos* m_pPageNum;
const CCtrlNewNumber* m_pNewNumber;
VECTOR<TRelationship>* m_pRelationships;
enum class EBreakType
{
Page,
Column,
TextWrapping,
None
} m_eBreakType;
std::map<unsigned int, const CCtrlField*> m_mOpenField;
TConversionState()
: m_bOpenedP(false), m_bOpenedR(false), m_bIsNote(false), m_bInTable(false), m_bInTextBox(false), m_ushLastCharShapeId(-1), m_ushSecdIndex(0), m_unParaIndex(0),
m_pSectionDef(nullptr), m_pColumnDef(nullptr), m_pPageNum(nullptr), m_pNewNumber(nullptr), m_pRelationships(nullptr), m_eBreakType(EBreakType::None)
{}
};
}
#endif // CONVERSIONSTATE_H

File diff suppressed because it is too large Load Diff

View File

@ -3,9 +3,12 @@
#include "../../../DesktopEditor/common/StringBuilder.h"
#include "../Paragraph/CtrlField.h"
#include "../Paragraph/CtrlAutoNumber.h"
#include "../Paragraph/CtrlSectionDef.h"
#include "../Paragraph/CtrlShapeVideo.h"
#include "../Paragraph/CtrlCharacter.h"
#include "../Paragraph/CtrlColumnDef.h"
#include "../Paragraph/CtrlShapePic.h"
#include "../Paragraph/CtrlShapeOle.h"
#include "../Paragraph/CtrlEqEdit.h"
@ -18,13 +21,58 @@
#include "FootnoteConverter.h"
#include "OleConverter.h"
#include "NumberingConverter.h"
#include "StyleConverter.h"
#include "../Common/WriterContext.h"
namespace HWP
{
struct THWPColor
{
BYTE m_uchRed;
BYTE m_uchGreen;
BYTE m_uchBlue;
};
struct TConversionState
{
bool m_bOpenedP;
bool m_bOpenedR;
bool m_bIsNote;
bool m_bInTextBox; // TODO:: используется, чтобы в wps:txbx не появилась новая фигура (посмотреть этот момент нужно подробнее)
unsigned short m_ushLastCharShapeId;
unsigned short m_ushSecdIndex;
unsigned int m_unParaIndex;
THWPColor *m_pHighlightColor;
VECTOR<const CCtrlHeadFoot*> m_arCtrlsHeadFoot; //only for hwpx
std::stack<int> m_arOpenedBookmarks;
const CCtrlSectionDef* m_pSectionDef;
const CCtrlColumnDef* m_pColumnDef;
enum class EBreakType
{
Page,
Column,
TextWrapping,
None
} m_eBreakType;
std::map<unsigned int, const CCtrlField*> m_mOpenField;
TConversionState();
};
struct TRelationship
{
HWP_STRING m_wsID;
HWP_STRING m_wsType;
HWP_STRING m_wsTarget;
};
struct TContentType
{
@ -41,11 +89,10 @@ enum class ECellCreator
class CConverter2OOXML
{
friend class CNumberingConverter;
CWriterContext * m_pContext;
HWP_STRING m_sTempDirectory;
NSStringUtils::CStringBuilder m_oStylesXml; // styles.xml
NSStringUtils::CStringBuilder m_oDocXml; // document.xml
NSStringUtils::CStringBuilder m_oNoteXmlRels; // footnotes.xml.rels
NSStringUtils::CStringBuilder m_oWebSettings; // webSettings.xml
@ -57,7 +104,6 @@ class CConverter2OOXML
CNumberingConverter m_oNumberingConverter;
CFootnoteConverter m_oFootnoteConverter;
COleConverter m_oOleConverter;
CStyleConverter m_oStyleConverter;
unsigned short m_ushShapeCount;
unsigned short m_ushPageCount;
@ -73,60 +119,56 @@ class CConverter2OOXML
bool IsRasterFormat(const HWP_STRING& sFormat);
void WriteParagraphProperties(short shParaShapeID, short shParaStyleID, NSStringUtils::CStringBuilder& oBuilder, TConversionState& oState);
void WriteTable(const CCtrlTable* pTable, short shParaShapeID, short shParaStyleID, NSStringUtils::CStringBuilder& oBuilder, TConversionState& oState);
void WriteTableProperties(const CCtrlTable* pTable, short shParaShapeID, short shParaStyleID, NSStringUtils::CStringBuilder& oBuilder, TConversionState& oState);
void WriteParagraphProperties(short shParaShapeID, NSStringUtils::CStringBuilder& oBuilder, TConversionState& oState);
void WriteTable(const CCtrlTable* pTable, short shParaShapeID, NSStringUtils::CStringBuilder& oBuilder, TConversionState& oState);
void WriteTableProperties(const CCtrlTable* pTable, short shParaShapeID, NSStringUtils::CStringBuilder& oBuilder, TConversionState& oState);
void WriteCell(const CTblCell* pCell, NSStringUtils::CStringBuilder& oBuilder, TConversionState& oState, ECellCreator eCellCreator);
void WriteCellProperties(short shBorderFillID, NSStringUtils::CStringBuilder& oBuilder);
void WriteBorder(const TBorder& oBorder, const HWP_STRING& sBorderName, NSStringUtils::CStringBuilder& oBuilder);
void WriteGeometryShape(const CCtrlGeneralShape* pGeneralShape, short shParaShapeID, short shParaStyleID, NSStringUtils::CStringBuilder& oBuilder, TConversionState& oState);
void WriteEqEditShape(const CCtrlEqEdit* pEqEditShape, short shParaShapeID, short shParaStyleID, NSStringUtils::CStringBuilder& oBuilder, TConversionState& oState);
void WriteOleShape(const CCtrlShapeOle* pOleShape, short shParaShapeID, short shParaStyleID, NSStringUtils::CStringBuilder& oBuilder, TConversionState& oState);
void WriteContainer(const CCtrlContainer* pContainer, short shParaShapeID, short shParaStyleID, NSStringUtils::CStringBuilder& oBuilder, TConversionState& oState);
void WriteGeometryShape(const CCtrlGeneralShape* pGeneralShape, short shParaShapeID, NSStringUtils::CStringBuilder& oBuilder, TConversionState& oState);
void WriteEqEditShape(const CCtrlEqEdit* pEqEditShape, short shParaShapeID, NSStringUtils::CStringBuilder& oBuilder, TConversionState& oState);
void WriteOleShape(const CCtrlShapeOle* pOleShape, short shParaShapeID, NSStringUtils::CStringBuilder& oBuilder, TConversionState& oState);
void WriteSectionSettings(TConversionState& oState);
void WritePicture(const CCtrlShapePic* pCtrlPic, short shParaShapeID, short shParaStyleID, NSStringUtils::CStringBuilder& oBuilder, TConversionState& oState);
void WriteVideo(const CCtrlShapeVideo* pCtrlVideo, short shParaShapeID, short shParaStyleID, NSStringUtils::CStringBuilder& oBuilder, TConversionState& oState);
void WritePicture(const CCtrlShapePic* pCtrlPic, short shParaShapeID, NSStringUtils::CStringBuilder& oBuilder, TConversionState& oState);
void WriteVideo(const CCtrlShapeVideo* pCtrlVideo, short shParaShapeID, NSStringUtils::CStringBuilder& oBuilder, TConversionState& oState);
bool SaveSVGFile(const HWP_STRING& sSVG, HWP_STRING& sFileName);
HWP_STRING SavePicture(const HWP_STRING& sBinItemId, TConversionState& oState);
HWP_STRING SavePicture(const HWP_STRING& sBinItemId);
void WriteParaShapeProperties(short shParaShapeID, short shParaStyleID, NSStringUtils::CStringBuilder& oBuilder, TConversionState& oState);
void WriteRunnerStyle(short shCharShapeID, NSStringUtils::CStringBuilder& oBuilder, TConversionState& oState, const CRunnerStyle& sExternStyles = CRunnerStyle());
void WriteParaShapeProperties(short shParaShapeID, NSStringUtils::CStringBuilder& oBuilder, TConversionState& oState);
void WriteRunnerStyle(short shCharShapeID, NSStringUtils::CStringBuilder& oBuilder, TConversionState& oState, const HWP_STRING& sExternStyles = L"");
void WriteTextBorderStyle(short shBorderFillId, NSStringUtils::CStringBuilder& oBuilder, TConversionState& oState);
void OpenDrawingNode(const CCtrlObjElement* pCtrlShape, NSStringUtils::CStringBuilder& oBuilder, int* pWidth = nullptr, int *pHeight = nullptr);
void CloseDrawingNode(const CCtrlObjElement* pCtrlShape, NSStringUtils::CStringBuilder& oBuilder);
void OpenDrawingNode(const CCtrlCommon* pCtrlShape, NSStringUtils::CStringBuilder& oBuilder);
void CloseDrawingNode(const CCtrlCommon* pCtrlShape, NSStringUtils::CStringBuilder& oBuilder);
void WriteShapePosition(const CCtrlCommon* pCtrlShape, NSStringUtils::CStringBuilder& oBuilder);
void WriteShapeExtent(const CCtrlObjElement* pCtrlShape, NSStringUtils::CStringBuilder& oBuilder, int* pWidth = nullptr, int *pHeight = nullptr);
void WriteShapeExtent(const CCtrlCommon* pCtrlShape, NSStringUtils::CStringBuilder& oBuilder);
void WriteShapeWrapMode(const CCtrlCommon* pCtrlShape, NSStringUtils::CStringBuilder& oBuilder);
void WriteShapeProperty(const CCtrlCommon* pCtrlShape, NSStringUtils::CStringBuilder& oBuilder);
void OpenParagraph(short shParaShapeID, short shParaStyleID, NSStringUtils::CStringBuilder& oBuilder, TConversionState& oState);
void OpenParagraph(short shParaShapeID, NSStringUtils::CStringBuilder& oBuilder, TConversionState& oState);
void CloseParagraph(NSStringUtils::CStringBuilder& oBuilder, TConversionState& oState);
void WriteText(const CParaText* pParaText, const VECTOR<TRangeTag>& arRangeTags, short shParaShapeID, short shParaStyleID, NSStringUtils::CStringBuilder& oBuilder, TConversionState& oState);
void WriteText(const HWP_STRING& wsText, short shParaShapeID, short shParaStyleID, short shCharShapeID, NSStringUtils::CStringBuilder& oBuilder, TConversionState& oState, const CRunnerStyle& oExternalStyle = CRunnerStyle());
void WriteText(const CParaText* pParaText, const VECTOR<TRangeTag>& arRangeTags, short shParaShapeID, NSStringUtils::CStringBuilder& oBuilder, TConversionState& oState);
void WriteText(const HWP_STRING& wsText, short shParaShapeID, short shCharShapeID, NSStringUtils::CStringBuilder& oBuilder, TConversionState& oState);
void WriteLineSettings(const CCtrlGeneralShape* pCtrlGeneralShape, NSStringUtils::CStringBuilder& oBuilder);
void WriteLineSettings(ELineStyle2 eLineStyle, int nColor, int nThick, HWP_BYTE nCompoundLineType, NSStringUtils::CStringBuilder& oBuilder);
void WriteBorderSettings(const CCtrlShapePic* pCtrlPic, NSStringUtils::CStringBuilder& oBuilder);
void WriteAutoNumber(const CCtrlAutoNumber* pAutoNumber, short shParaShapeID, short shParaStyleID, short shCharShapeID, NSStringUtils::CStringBuilder& oBuilder, TConversionState& oState);
void WriteCharacter(const CCtrlCharacter* pCharacter, short shParaShapeID, short shParaStyleID, NSStringUtils::CStringBuilder& oBuilder, TConversionState& oState);
void WriteShape(const CCtrlGeneralShape* pShape, short shParaShapeID, short shParaStyleID, NSStringUtils::CStringBuilder& oBuilder, TConversionState& oState);
void WriteAutoNumber(const CCtrlAutoNumber* pAutoNumber, short shParaShapeID, short shCharShapeID, NSStringUtils::CStringBuilder& oBuilder, TConversionState& oState);
void WriteCharacter(const CCtrlCharacter* pCharacter, short shParaShapeID, NSStringUtils::CStringBuilder& oBuilder, TConversionState& oState);
void WriteShape(const CCtrlGeneralShape* pShape, short shParaShapeID, NSStringUtils::CStringBuilder& oBuilder, TConversionState& oState);
void WriteNote(const CCtrlNote* pNote, short shParaShapeID, NSStringUtils::CStringBuilder& oBuilder, TConversionState& oState);
void WriteField(const CCtrlField* pHyperlink, short shParaShapeID, short shParaStyleID, NSStringUtils::CStringBuilder& oBuilder, TConversionState& oState);
void WriteField(const CCtrlField* pHyperlink, short shParaShapeID, NSStringUtils::CStringBuilder& oBuilder, TConversionState& oState);
void CloseField(const CCtrlField* pHyperlink, NSStringUtils::CStringBuilder& oBuilder, TConversionState& oState);
void WriteCaption(const CCtrlCommon* pCtrlCommon, NSStringUtils::CStringBuilder& oBuilder, TConversionState& oState);
void WriteEmptyParagraph(short shParaShapeID, short shParaStyleID, short shCharShapeID, NSStringUtils::CStringBuilder& oBuilder, TConversionState& oState);
HWP_STRING AddRelationship(const HWP_STRING& wsType, const HWP_STRING& wsTarget, TConversionState* pState = nullptr);
HWP_STRING AddRelationship(const HWP_STRING& wsType, const HWP_STRING& wsTarget);
void AddContentType(const HWP_STRING& wsName, const HWP_STRING& wsType);
void AddDefaultContentType(const HWP_STRING& wsName);
public:

View File

@ -54,9 +54,6 @@ std::wstring CFootnoteConverter::CreateHeadOrFoot(const CCtrlHeadFoot* pCtrlHead
TConversionState oState;
VECTOR<TRelationship> arRelationships;
oState.m_pRelationships = &arRelationships;
for (const CHWPPargraph* pParagraphs : pCtrlHeadFoot->GetParagraphs())
oConverter.WriteParagraph(pParagraphs, oNewDocumentBuilder, oState);
@ -107,156 +104,6 @@ std::wstring CFootnoteConverter::CreateHeadOrFoot(const CCtrlHeadFoot* pCtrlHead
oFile.WriteStringUTF8(oNewDocumentBuilder.GetData());
oFile.WriteStringUTF8(L"</w:" + wsNodeName + L">");
oFile.CloseFile();
if (arRelationships.empty())
return wsFileName;
// TODO:: пока это копия из Converter2OOXML
NSFile::CFileBinary oRelsWriter;
if (oRelsWriter.CreateFileW(oConverter.GetTempDirectory() + L"/word/_rels/" + wsFileName + L".rels"))
{
oRelsWriter.WriteStringUTF8(L"<?xml version=\"1.0\" encoding=\"UTF-8\" standalone=\"yes\"?><Relationships xmlns=\"http://schemas.openxmlformats.org/package/2006/relationships\">");
for (const TRelationship& oRelationship : arRelationships)
{
oRelsWriter.WriteStringUTF8(L"<Relationship Id=\"" + oRelationship.m_wsID + L"\" Type=\"http://schemas.openxmlformats.org/officeDocument/2006/relationships/" + oRelationship.m_wsType + L"\" Target=\"" + oRelationship.m_wsTarget + L'\"');
if (L"hyperlink" == oRelationship.m_wsType)
oRelsWriter.WriteStringUTF8(L" TargetMode=\"External\"/>");
else
oRelsWriter.WriteStringUTF8(L"/>");
}
oRelsWriter.WriteStringUTF8(L"</Relationships>");
oRelsWriter.CloseFile();
}
return wsFileName;
}
std::wstring CFootnoteConverter::CreatePageNum(const CCtrlPageNumPos* pCtrlPageNumPos, CConverter2OOXML& oConverter)
{
if (nullptr == pCtrlPageNumPos || ENumberShape2::DIGIT != pCtrlPageNumPos->GetFormatType() ||
ENumPos::NONE == pCtrlPageNumPos->GetPos())
return std::wstring();
std::wstring wsNodeName, wsJs;
switch(pCtrlPageNumPos->GetPos())
{
case ENumPos::TOP_LEFT:
{
wsNodeName = L"hdr";
wsJs = L"left";
break;
}
case ENumPos::TOP_CENTER:
case ENumPos::TOP_OUTER:
case ENumPos::TOP_INNER:
{
wsNodeName = L"hdr";
wsJs = L"center";
break;
}
case ENumPos::TOP_RIGHT:
{
wsNodeName = L"hdr";
wsJs = L"right";
break;
}
case ENumPos::BOTTOM_LEFT:
{
wsNodeName = L"ftr";
wsJs = L"left";
break;
}
case ENumPos::BOTTOM_CENTER:
case ENumPos::BOTTOM_OUTER:
case ENumPos::BOTTOM_INNER:
{
wsNodeName = L"ftr";
wsJs = L"center";
break;
}
case ENumPos::BOTTOM_RIGHT:
{
wsNodeName = L"ftr";
wsJs = L"right";
break;
}
case ENumPos::NONE:
break;
}
const std::wstring wsFileName((L"hdr" == wsNodeName) ? (L"header" + std::to_wstring(++m_ushHeaderCount)) : (L"footer" + std::to_wstring(++m_ushFooterCount)) + L".xml");
NSFile::CFileBinary oFile;
if (!oFile.CreateFileW(oConverter.GetTempDirectory() + L"/word/" + wsFileName))
return std::wstring();
oFile.WriteStringUTF8(L"<w:" + wsNodeName);
oFile.WriteStringUTF8(L" 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:oel=\"http://schemas.microsoft.com/office/2019/extlst\" "
"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: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:w16du=\"http://schemas.microsoft.com/office/word/2023/wordml/word16du\" "
"xmlns:w16sdtdh=\"http://schemas.microsoft.com/office/word/2020/wordml/sdtdatahash\" "
"xmlns:w16sdtfl=\"http://schemas.microsoft.com/office/word/2024/wordml/sdtformatlock\" "
"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\">");
oFile.WriteStringUTF8(L"<w:sdt><w:sdtContent><w:p>");
oFile.WriteStringUTF8(L"<w:pPr>");
oFile.WriteStringUTF8(L"<w:jc w:val=\"" + wsJs + L"\"/>");
oFile.WriteStringUTF8(L"</w:pPr>");
if (!pCtrlPageNumPos->GetPrefix().empty())
oFile.WriteStringUTF8(L"<w:r><w:rPr><w:sz w:val=\"28\"/><w:szCs w:val=\"28\"/></w:rPr><w:t>" + pCtrlPageNumPos->GetPrefix() + L"</w:t></w:r>");
oFile.WriteStringUTF8(L"<w:r><w:fldChar w:fldCharType=\"begin\"/></w:r>");
oFile.WriteStringUTF8(L"<w:r><w:instrText>PAGE \\* MERGEFORMAT</w:instrText></w:r>");
oFile.WriteStringUTF8(L"<w:r><w:fldChar w:fldCharType=\"separate\"/></w:r>");
oFile.WriteStringUTF8(L"<w:r><w:rPr><w:sz w:val=\"28\"/><w:szCs w:val=\"28\"/></w:rPr><w:t>2</w:t></w:r>");
oFile.WriteStringUTF8(L"<w:r><w:fldChar w:fldCharType=\"end\"/></w:r>");
if (!pCtrlPageNumPos->GetPostfix().empty())
oFile.WriteStringUTF8(L"<w:r><w:rPr><w:sz w:val=\"28\"/><w:szCs w:val=\"28\"/></w:rPr><w:t>" + pCtrlPageNumPos->GetPostfix() + L"</w:t></w:r>");
oFile.WriteStringUTF8(L"</w:p></w:sdtContent></w:sdt>");
oFile.WriteStringUTF8(L"</w:" + wsNodeName + L">");
oFile.CloseFile();
return wsFileName;
}

View File

@ -5,7 +5,6 @@
#include "../Paragraph/CtrlNote.h"
#include "../Paragraph/CtrlHeadFoot.h"
#include "../Paragraph/CtrlPageNumPos.h"
namespace HWP
{
@ -25,7 +24,6 @@ public:
std::wstring CreateNote(const CCtrlNote* pNote, CConverter2OOXML& oConverter);
std::wstring CreateHeadOrFoot(const CCtrlHeadFoot* pCtrlHeadFoot, CConverter2OOXML& oConverter);
std::wstring CreatePageNum(const CCtrlPageNumPos* pCtrlPageNumPos, CConverter2OOXML& oConverter);
bool SaveToFile(const std::wstring& wsDirectory);

View File

@ -1,8 +1,6 @@
#include "NumberingConverter.h"
#include "../../../DesktopEditor/common/File.h"
#include "Converter2OOXML.h"
namespace HWP
{
CNumberingConverter::CNumberingConverter()
@ -24,7 +22,7 @@ std::wstring HeadingTypeToWSTR(EHeadingType eHeadingType)
}
}
int CNumberingConverter::CreateNumbering(const CHWPRecordNumbering* pNumbering, EHeadingType eHeadingType, CConverter2OOXML& oConverter)
int CNumberingConverter::CreateNumbering(const CHWPRecordNumbering* pNumbering, EHeadingType eHeadingType)
{
if (nullptr == pNumbering || eHeadingType == EHeadingType::NONE || EHeadingType::OUTLINE == eHeadingType)
return 0;
@ -76,14 +74,6 @@ int CNumberingConverter::CreateNumbering(const CHWPRecordNumbering* pNumbering,
}
m_oNumberXml.WriteString(L"\"/>");
int nCharShape = pNumbering->GetCharShape(shIndex);
if (INT_MAX == nCharShape)
nCharShape = 0;
TConversionState oState;
oConverter.WriteRunnerStyle(nCharShape, m_oNumberXml, oState);
m_oNumberXml.WriteString(L"</w:lvl>");
}
}

View File

@ -8,7 +8,6 @@
namespace HWP
{
class CConverter2OOXML;
class CNumberingConverter
{
NSStringUtils::CStringBuilder m_oNumberXml;
@ -18,7 +17,7 @@ public:
unsigned int GetCountNumbering() const;
int CreateNumbering(const CHWPRecordNumbering* pNumbering, EHeadingType eHeadingType, CConverter2OOXML& oConverter);
int CreateNumbering(const CHWPRecordNumbering* pNumbering, EHeadingType eHeadingType);
bool SaveToFile(const std::wstring& wsDirectory);
};
}

Some files were not shown because too many files have changed in this diff Show More