mirror of
https://github.com/ONLYOFFICE/core.git
synced 2026-07-20 00:03:33 +08:00
1059 lines
25 KiB
C++
1059 lines
25 KiB
C++
#pragma once
|
|
#include "..\stdafx.h"
|
|
#include "atlcoll.h"
|
|
#include "TemporaryCS.h"
|
|
|
|
#include "..\Interfaces\ASCMetafile.h"
|
|
#include "DIB.h"
|
|
#include "..\Interfaces\XmlUtils.h"
|
|
|
|
namespace NSDocumentViewer
|
|
{
|
|
// êëàññ Ãèïåðññûëêà
|
|
class CHyperlinkEvent
|
|
{
|
|
public:
|
|
virtual void HyperlinkURL(CString& strUrl) = 0;
|
|
virtual void HyperlinkPlace(LONG& lPageNum, CDoubleRect& oRect) = 0;
|
|
};
|
|
|
|
class CHyperlink
|
|
{
|
|
public:
|
|
CDoubleRect m_oBoundsSrc;
|
|
CDoubleRect m_oBoundsDst;
|
|
|
|
CString m_strURL;
|
|
|
|
LONG m_lSrcPageIndex;
|
|
LONG m_lDstPageIndex;
|
|
|
|
BOOL m_bIsActivate;
|
|
|
|
public:
|
|
CHyperlink() : m_oBoundsSrc(), m_oBoundsDst()
|
|
{
|
|
m_strURL = _T("");
|
|
|
|
m_lSrcPageIndex = -1;
|
|
m_lDstPageIndex = -1;
|
|
|
|
m_bIsActivate = FALSE;
|
|
}
|
|
CHyperlink(const CHyperlink& oSrc)
|
|
{
|
|
*this = oSrc;
|
|
}
|
|
~CHyperlink()
|
|
{
|
|
}
|
|
CHyperlink& operator=(const CHyperlink& oSrc)
|
|
{
|
|
m_oBoundsSrc = oSrc.m_oBoundsSrc;
|
|
m_oBoundsDst = oSrc.m_oBoundsDst;
|
|
|
|
m_strURL = oSrc.m_strURL;
|
|
m_lDstPageIndex = oSrc.m_lDstPageIndex;
|
|
m_lSrcPageIndex = oSrc.m_lSrcPageIndex;
|
|
|
|
m_bIsActivate = oSrc.m_bIsActivate;
|
|
|
|
return *this;
|
|
}
|
|
|
|
public:
|
|
inline void FromXml(CString& strXml)
|
|
{
|
|
XmlUtils::CXmlNode oNode;
|
|
if (oNode.FromXmlString(strXml))
|
|
{
|
|
FromXml(oNode);
|
|
}
|
|
}
|
|
inline void FromXml(XmlUtils::CXmlNode& oNodeLink)
|
|
{
|
|
XmlUtils::CXmlNode oNodeSource;
|
|
if (oNodeLink.GetNode(_T("source"), oNodeSource))
|
|
{
|
|
m_lSrcPageIndex = XmlUtils::GetInteger(oNodeSource.GetAttributeOrValue(_T("page")));
|
|
|
|
m_oBoundsSrc.left = XmlUtils::GetDouble(oNodeSource.GetAttributeOrValue(_T("x")));
|
|
m_oBoundsSrc.top = XmlUtils::GetDouble(oNodeSource.GetAttributeOrValue(_T("y")));
|
|
|
|
m_oBoundsSrc.right = m_oBoundsSrc.left + XmlUtils::GetDouble(oNodeSource.GetAttributeOrValue(_T("width")));
|
|
m_oBoundsSrc.bottom = m_oBoundsSrc.top + XmlUtils::GetDouble(oNodeSource.GetAttributeOrValue(_T("height")));
|
|
}
|
|
XmlUtils::CXmlNode oNodeTarget;
|
|
if (oNodeLink.GetNode(_T("target"), oNodeTarget))
|
|
{
|
|
m_strURL = oNodeTarget.GetAttributeOrValue(_T("url"));
|
|
|
|
if (_T("") == m_strURL)
|
|
{
|
|
m_lDstPageIndex = XmlUtils::GetInteger(oNodeTarget.GetAttributeOrValue(_T("page")));
|
|
|
|
m_oBoundsDst.left = XmlUtils::GetDouble(oNodeTarget.GetAttributeOrValue(_T("x")));
|
|
m_oBoundsDst.top = XmlUtils::GetDouble(oNodeTarget.GetAttributeOrValue(_T("y")));
|
|
|
|
m_oBoundsDst.right = m_oBoundsSrc.left + XmlUtils::GetDouble(oNodeTarget.GetAttributeOrValue(_T("width")));
|
|
m_oBoundsDst.bottom = m_oBoundsSrc.top + XmlUtils::GetDouble(oNodeTarget.GetAttributeOrValue(_T("height")));
|
|
}
|
|
}
|
|
}
|
|
|
|
inline BOOL IsActivate(const double& x, const double& y)
|
|
{
|
|
m_bIsActivate = m_oBoundsSrc.IsPointInside(x, y);
|
|
return m_bIsActivate;
|
|
}
|
|
inline BOOL Activate(const double& x, const double& y, CHyperlinkEvent* pEvent)
|
|
{
|
|
BOOL bOld = m_bIsActivate;
|
|
|
|
m_bIsActivate = IsActivate(x, y);
|
|
|
|
if (bOld && m_bIsActivate && NULL != pEvent)
|
|
{
|
|
if (_T("") == m_strURL)
|
|
{
|
|
pEvent->HyperlinkPlace(m_lDstPageIndex, m_oBoundsDst);
|
|
}
|
|
else
|
|
{
|
|
pEvent->HyperlinkURL(m_strURL);
|
|
}
|
|
return TRUE;
|
|
}
|
|
|
|
return FALSE;
|
|
}
|
|
};
|
|
|
|
class CHyperlinks
|
|
{
|
|
public:
|
|
CAtlArray<CHyperlink> m_arLinks;
|
|
|
|
public:
|
|
CHyperlinks() : m_arLinks()
|
|
{
|
|
}
|
|
CHyperlinks(const CHyperlinks& oSrc)
|
|
{
|
|
*this = oSrc;
|
|
}
|
|
~CHyperlinks()
|
|
{
|
|
}
|
|
CHyperlinks& operator=(const CHyperlinks& oSrc)
|
|
{
|
|
m_arLinks.Copy(oSrc.m_arLinks);
|
|
return *this;
|
|
}
|
|
|
|
BOOL IsActivate(const double& x, const double& y)
|
|
{
|
|
size_t nCount = m_arLinks.GetCount();
|
|
for (size_t i = 0; i < nCount; ++i)
|
|
{
|
|
if (m_arLinks[i].IsActivate(x, y))
|
|
return TRUE;
|
|
}
|
|
return FALSE;
|
|
}
|
|
BOOL Activate(const double& x, const double& y, CHyperlinkEvent* pEvent)
|
|
{
|
|
size_t nCount = m_arLinks.GetCount();
|
|
for (size_t i = 0; i < nCount; ++i)
|
|
{
|
|
if (m_arLinks[i].Activate(x, y, pEvent))
|
|
return TRUE;
|
|
}
|
|
return FALSE;
|
|
}
|
|
};
|
|
|
|
// êëàññ ñòðàíèöû.
|
|
// ñîäåðæèò òîëüêî èíôîðìàöèþ î íåé (ðàçìåðû è êîìàíäû)
|
|
class CPage
|
|
{
|
|
public:
|
|
double m_dWidthMM;
|
|
double m_dHeightMM;
|
|
|
|
LONG m_lPixWidth;
|
|
LONG m_lPixHeight;
|
|
|
|
LONG m_lShadowOffsetHor;
|
|
LONG m_lShadowOffsetVer;
|
|
|
|
// íóæíî äëÿ áûñòðîé è óäîáíîé íàâèãàöèè ïî ñòðàíèöàì
|
|
double m_dPositionVer;
|
|
|
|
// íóæíî äëÿ ïîêàçà âèäèìîé ñòðàíèöû (òàáíåéëû)
|
|
double m_dPositionVer2;
|
|
|
|
CHyperlinks m_oLinks;
|
|
|
|
IAVSMetafile* m_pPage;
|
|
|
|
public:
|
|
CPage() : m_oLinks()
|
|
{
|
|
m_dWidthMM = 210;
|
|
m_dHeightMM = 190;
|
|
|
|
SetDpi(96.0, 96.0);
|
|
|
|
m_lShadowOffsetHor = 3;
|
|
m_lShadowOffsetVer = 3;
|
|
|
|
m_dPositionVer = 0;
|
|
m_dPositionVer2 = 0;
|
|
|
|
m_pPage = NULL;
|
|
}
|
|
~CPage()
|
|
{
|
|
RELEASEINTERFACE(m_pPage);
|
|
}
|
|
|
|
public:
|
|
inline void SetDpi(double dDpiX, double dDpiY)
|
|
{
|
|
m_lPixWidth = (LONG)(dDpiX * m_dWidthMM / c_dInch_to_MM);
|
|
m_lPixHeight = (LONG)(dDpiY * m_dHeightMM / c_dInch_to_MM);
|
|
}
|
|
inline void CalculatePix(const double& dScaleX, const double& dScaleY)
|
|
{
|
|
m_lPixWidth = (LONG)(m_dWidthMM * dScaleX);
|
|
m_lPixHeight = (LONG)(m_dHeightMM * dScaleY);
|
|
}
|
|
|
|
inline LONG Width()
|
|
{
|
|
return m_lPixWidth + m_lShadowOffsetHor;
|
|
}
|
|
inline LONG Height()
|
|
{
|
|
return m_lPixHeight + m_lShadowOffsetVer;
|
|
}
|
|
|
|
void Draw(IUnknown* punkRenderer, BOOL* pBreak)
|
|
{
|
|
if (NULL != m_pPage)
|
|
{
|
|
m_pPage->Draw(punkRenderer, pBreak);
|
|
}
|
|
}
|
|
void Draw2(IUnknown* pRenderer, BOOL* pBreak)
|
|
{
|
|
if (NULL != m_pPage)
|
|
{
|
|
m_pPage->Draw2(pRenderer, -1, -1, pBreak);
|
|
}
|
|
}
|
|
};
|
|
|
|
// êëàññ äëÿ îòðèñîâêè ñòðàíèöû
|
|
// ñîäåðæèò ñòðàíèöó è åå ðåêò äëÿ îòðèñîâêè
|
|
class CDrawingPage
|
|
{
|
|
public:
|
|
CPage* m_pPage;
|
|
|
|
CDoubleRect m_oGlobalBounds;
|
|
CDoubleRect m_oPageBounds;
|
|
|
|
LONG m_lIndexInSource;
|
|
|
|
public:
|
|
|
|
CDrawingPage(CPage* pPage = NULL)
|
|
{
|
|
m_pPage = pPage;
|
|
}
|
|
|
|
~CDrawingPage()
|
|
{
|
|
}
|
|
|
|
double GetPercentVisibleVer(LONG lHeightControl)
|
|
{
|
|
double dH = m_oGlobalBounds.GetHeight();
|
|
if (dH < 0.001)
|
|
return 1.0;
|
|
|
|
double dTop = max(0, m_oGlobalBounds.top);
|
|
double dBottom = min((double)lHeightControl, m_oGlobalBounds.bottom);
|
|
|
|
return (dBottom - dTop) / dH;
|
|
}
|
|
double GetPercentVisibleHor(LONG lWidthControl)
|
|
{
|
|
double dW = m_oGlobalBounds.GetWidth();
|
|
if (dW < 0.001)
|
|
return 1.0;
|
|
|
|
double dLeft = max(0, m_oGlobalBounds.left);
|
|
double dRight = min((double)lWidthControl, m_oGlobalBounds.right);
|
|
|
|
return (dRight - dLeft) / dW;
|
|
}
|
|
|
|
void GetPercentsVisiblePage(double& dLeft, double& dTop, double& dWidth, double& dHeight, const LONG& lWidthControl, const LONG& lHeightControl)
|
|
{
|
|
double dWidthControl = (double)lWidthControl;
|
|
double dHeightControl = (double)lHeightControl;
|
|
|
|
double dWidthPage = max(0.001, m_oGlobalBounds.GetWidth());
|
|
double dHeightPage = max(0.001, m_oGlobalBounds.GetHeight());
|
|
|
|
// left
|
|
dLeft = 0;
|
|
if (m_oGlobalBounds.left < 0)
|
|
dLeft = -m_oGlobalBounds.left;
|
|
|
|
dLeft /= dWidthPage;
|
|
|
|
// top
|
|
dTop = 0;
|
|
if (m_oGlobalBounds.top < 0)
|
|
dTop = -m_oGlobalBounds.top;
|
|
|
|
dTop /= dHeightPage;
|
|
|
|
// width
|
|
double __dLeft = max(0, m_oGlobalBounds.left);
|
|
double __dRight = min(dWidthControl, m_oGlobalBounds.right);
|
|
|
|
dWidth = (__dRight - __dLeft) / dWidthPage;
|
|
|
|
// height
|
|
double __dTop = max(0, m_oGlobalBounds.top);
|
|
double __dBottom = min(dHeightControl, m_oGlobalBounds.bottom);
|
|
|
|
dHeight = (__dBottom - __dTop) / dHeightPage;
|
|
}
|
|
|
|
friend bool operator==(const CDrawingPage& oPage1, const CDrawingPage& oPage2)
|
|
{
|
|
if (oPage1.m_pPage != oPage2.m_pPage)
|
|
return false;
|
|
|
|
if ((oPage1.m_oGlobalBounds.left != oPage2.m_oGlobalBounds.left) ||
|
|
(oPage1.m_oGlobalBounds.top != oPage2.m_oGlobalBounds.top) ||
|
|
(oPage1.m_oGlobalBounds.right != oPage2.m_oGlobalBounds.right) ||
|
|
(oPage1.m_oGlobalBounds.bottom != oPage2.m_oGlobalBounds.bottom))
|
|
return false;
|
|
|
|
return true;
|
|
}
|
|
|
|
friend bool operator!=(const CDrawingPage& oPage1, const CDrawingPage& oPage2)
|
|
{
|
|
return (oPage1 == oPage2) ? false : true;
|
|
}
|
|
|
|
CDrawingPage& operator=(const CDrawingPage& oSrc)
|
|
{
|
|
m_pPage = oSrc.m_pPage;
|
|
m_oGlobalBounds = oSrc.m_oGlobalBounds;
|
|
|
|
m_lIndexInSource = oSrc.m_lIndexInSource;
|
|
|
|
m_oPageBounds = oSrc.m_oPageBounds;
|
|
return *this;
|
|
}
|
|
|
|
CDrawingPage(const CDrawingPage& oSrc)
|
|
{
|
|
*this = oSrc;
|
|
}
|
|
|
|
void Inscribed()
|
|
{
|
|
double dWidth1 = m_oPageBounds.GetWidth();
|
|
double dHeight1 = m_oPageBounds.GetHeight();
|
|
|
|
double dWidth2 = m_pPage->m_dWidthMM;
|
|
double dHeight2 = m_pPage->m_dHeightMM;
|
|
|
|
double dAspect1 = dWidth1 / dHeight1;
|
|
double dAspect2 = dWidth2 / dHeight2;
|
|
|
|
if (dAspect1 >= dAspect2)
|
|
{
|
|
m_oGlobalBounds.top = m_oPageBounds.top;
|
|
m_oGlobalBounds.bottom = m_oPageBounds.bottom;
|
|
|
|
double __dWidth = dWidth2 * dHeight1 / dHeight2;
|
|
|
|
m_oGlobalBounds.left = m_oPageBounds.left + (dWidth1 - __dWidth) / 2.0;
|
|
m_oGlobalBounds.right = m_oGlobalBounds.left + __dWidth;
|
|
}
|
|
else
|
|
{
|
|
m_oGlobalBounds.left = m_oPageBounds.left;
|
|
m_oGlobalBounds.right = m_oPageBounds.right;
|
|
|
|
double __dHeight = dHeight2 * dWidth1 / dWidth2;
|
|
|
|
m_oGlobalBounds.top = m_oPageBounds.top + (dHeight1 - __dHeight) / 2.0;
|
|
m_oGlobalBounds.bottom = m_oGlobalBounds.top + __dHeight;
|
|
}
|
|
}
|
|
};
|
|
|
|
class CDrawingDocument
|
|
{
|
|
public:
|
|
CAtlArray<CDrawingPage> m_arPages;
|
|
|
|
public:
|
|
CDrawingDocument() : m_arPages()
|
|
{
|
|
}
|
|
~CDrawingDocument()
|
|
{
|
|
Clear();
|
|
}
|
|
|
|
public:
|
|
inline void Clear()
|
|
{
|
|
m_arPages.RemoveAll();
|
|
}
|
|
friend bool operator==(const CDrawingDocument& oDoc1, const CDrawingDocument& oDoc2)
|
|
{
|
|
LONG lCount1 = (LONG)oDoc1.m_arPages.GetCount();
|
|
LONG lCount2 = (LONG)oDoc2.m_arPages.GetCount();
|
|
|
|
if (lCount1 != lCount2)
|
|
return false;
|
|
|
|
for (LONG i = 0; i < lCount1; ++i)
|
|
{
|
|
if (oDoc1.m_arPages[i] != oDoc2.m_arPages[i])
|
|
return false;
|
|
}
|
|
|
|
return true;
|
|
}
|
|
|
|
friend bool operator!=(const CDrawingDocument& oDoc1, const CDrawingDocument& oDoc2)
|
|
{
|
|
return (oDoc1 == oDoc2) ? false : true;
|
|
}
|
|
|
|
CDrawingDocument& operator=(const CDrawingDocument& oSrc)
|
|
{
|
|
m_arPages.Copy(oSrc.m_arPages);
|
|
return *this;
|
|
}
|
|
CDrawingDocument(const CDrawingDocument& oSrc)
|
|
{
|
|
*this = oSrc;
|
|
}
|
|
};
|
|
|
|
// ýòî äëÿ òîãî, ÷òîáû áûë îäèí èíòåðôåéñ äëÿ âñåõ ðåæèìîâ
|
|
// (êîë-âî ñòðàíèö ïî ãîðèçîíòàëè)
|
|
// âðîäå êàê èñïîëüçîâàòüñÿ áóäåò òîëüêî 1 èëè 2
|
|
class CBlockPages
|
|
{
|
|
public:
|
|
CAtlArray<CPage*> m_arPages;
|
|
|
|
public:
|
|
CBlockPages() : m_arPages()
|
|
{
|
|
}
|
|
~CBlockPages()
|
|
{
|
|
DeletePages();
|
|
}
|
|
CBlockPages& operator=(const CBlockPages& oSrc)
|
|
{
|
|
m_arPages.Copy(oSrc.m_arPages);
|
|
return *this;
|
|
}
|
|
CBlockPages(const CBlockPages& oSrc)
|
|
{
|
|
*this = oSrc;
|
|
}
|
|
|
|
public:
|
|
inline LONG GetWidth(const LONG& lPageBetween)
|
|
{
|
|
size_t nCount = m_arPages.GetCount();
|
|
if (1 == nCount)
|
|
{
|
|
return m_arPages[0]->m_lPixWidth;
|
|
}
|
|
else if (2 == nCount)
|
|
{
|
|
//return m_arPages[0]->m_lPixWidth + m_arPages[1]->m_lPixWidth + lPageBetween;
|
|
return 2 * max(m_arPages[0]->m_lPixWidth, m_arPages[1]->m_lPixWidth) + lPageBetween;
|
|
}
|
|
return 0;
|
|
}
|
|
|
|
inline double GetWidthMM(double dPlus)
|
|
{
|
|
size_t nCount = m_arPages.GetCount();
|
|
if (1 == nCount)
|
|
{
|
|
return m_arPages[0]->m_dWidthMM;
|
|
}
|
|
else if (2 == nCount)
|
|
{
|
|
//return m_arPages[0]->m_dWidthMM + m_arPages[1]->m_dWidthMM + dPlus;
|
|
return 2 * max(m_arPages[0]->m_dWidthMM, m_arPages[1]->m_dWidthMM) + dPlus;
|
|
}
|
|
return 0;
|
|
}
|
|
|
|
inline LONG GetHeight()
|
|
{
|
|
size_t nCount = m_arPages.GetCount();
|
|
if (1 == nCount)
|
|
{
|
|
return m_arPages[0]->m_lPixHeight;
|
|
}
|
|
else if (2 == nCount)
|
|
{
|
|
return max(m_arPages[0]->m_lPixHeight, m_arPages[1]->m_lPixHeight);
|
|
}
|
|
return 0;
|
|
}
|
|
|
|
inline double GetHeightMM()
|
|
{
|
|
size_t nCount = m_arPages.GetCount();
|
|
if (1 == nCount)
|
|
{
|
|
return m_arPages[0]->m_dHeightMM;
|
|
}
|
|
else if (2 == nCount)
|
|
{
|
|
return max(m_arPages[0]->m_dHeightMM, m_arPages[1]->m_dHeightMM);
|
|
}
|
|
return 0;
|
|
}
|
|
inline void DeletePages()
|
|
{
|
|
size_t nCount = m_arPages.GetCount();
|
|
for (size_t i = 0; i < nCount; ++i)
|
|
{
|
|
CPage* pPage = m_arPages[i];
|
|
RELEASEOBJECT(pPage);
|
|
}
|
|
m_arPages.RemoveAll();
|
|
}
|
|
inline void DeletePagesNoAttack()
|
|
{
|
|
m_arPages.RemoveAll();
|
|
}
|
|
|
|
inline void SetPositionVer(double dPosition)
|
|
{
|
|
for (size_t i = 0; i < m_arPages.GetCount(); ++i)
|
|
{
|
|
m_arPages[i]->m_dPositionVer = dPosition;
|
|
}
|
|
}
|
|
inline void SetPositionVer2(double dPosition)
|
|
{
|
|
for (size_t i = 0; i < m_arPages.GetCount(); ++i)
|
|
{
|
|
m_arPages[i]->m_dPositionVer2 = dPosition;
|
|
}
|
|
}
|
|
|
|
inline void CalculatePix(const double& dScaleX, const double& dScaleY)
|
|
{
|
|
size_t nCount = m_arPages.GetCount();
|
|
for (size_t i = 0; i < nCount; ++i)
|
|
{
|
|
m_arPages[i]->CalculatePix(dScaleX, dScaleY);
|
|
}
|
|
}
|
|
|
|
inline LONG AppendDrawingPages(CAtlArray<CDrawingPage>* pArray, const LONGLONG& lCenterHor, const double& dTop, const double& dBorderTop, LONG lBetween)
|
|
{
|
|
size_t nCount = m_arPages.GetCount();
|
|
|
|
// à âîò òóò íåïîíÿòíî êàê äåëàòü. äîáàâÿò âîçìîæíîñòü ñìîòðåòü
|
|
// ïðîèçâîëüíîå êîëè÷åñòâî ñòðàíèö - ñäåëàþ
|
|
if (1 == nCount)
|
|
{
|
|
CPage* pPage = m_arPages[0];
|
|
CDrawingPage oPage(pPage);
|
|
oPage.m_oGlobalBounds.left = lCenterHor - (double)(pPage->m_lPixWidth) / 2.0;
|
|
oPage.m_oGlobalBounds.right = lCenterHor + (double)(pPage->m_lPixWidth) / 2.0;
|
|
|
|
oPage.m_oGlobalBounds.top = dTop;
|
|
oPage.m_oGlobalBounds.bottom = (double)(oPage.m_oGlobalBounds.top + pPage->m_lPixHeight);
|
|
|
|
if (oPage.m_oGlobalBounds.bottom > -dBorderTop)
|
|
{
|
|
pArray->Add(oPage);
|
|
}
|
|
|
|
return (LONG)(oPage.m_oGlobalBounds.bottom + lBetween);
|
|
}
|
|
else if (2 == nCount)
|
|
{
|
|
CPage* pPage1 = m_arPages[0];
|
|
CPage* pPage2 = m_arPages[1];
|
|
|
|
LONG lHeight1 = pPage1->m_lPixHeight;
|
|
LONG lHeight2 = pPage2->m_lPixHeight;
|
|
|
|
LONG lHeightMax = max(lHeight1, lHeight2);
|
|
|
|
double dCentreV = dTop + ((double)lHeightMax) / 2;
|
|
|
|
LONGLONG lRight1 = lCenterHor - lBetween / 2;
|
|
|
|
CDrawingPage oPage1(pPage1);
|
|
oPage1.m_oGlobalBounds.left = (double)(lRight1 - pPage1->m_lPixWidth);
|
|
oPage1.m_oGlobalBounds.right = (double)lRight1;
|
|
|
|
oPage1.m_oGlobalBounds.top = dCentreV - (double)pPage1->m_lPixHeight / 2;
|
|
oPage1.m_oGlobalBounds.bottom = dCentreV + (double)pPage1->m_lPixHeight / 2;
|
|
|
|
LONGLONG lLeft2 = lCenterHor + lBetween / 2;
|
|
|
|
CDrawingPage oPage2(pPage2);
|
|
oPage2.m_oGlobalBounds.left = (double)(lLeft2);
|
|
oPage2.m_oGlobalBounds.right = (double)(lLeft2 + pPage2->m_lPixWidth);
|
|
|
|
oPage2.m_oGlobalBounds.top = dCentreV - (double)pPage2->m_lPixHeight / 2;
|
|
oPage2.m_oGlobalBounds.bottom = dCentreV + (double)pPage2->m_lPixHeight / 2;
|
|
|
|
if (oPage1.m_oGlobalBounds.bottom > -dBorderTop)
|
|
{
|
|
pArray->Add(oPage1);
|
|
}
|
|
if (oPage2.m_oGlobalBounds.bottom > -dBorderTop)
|
|
{
|
|
pArray->Add(oPage2);
|
|
}
|
|
|
|
return (LONG)(dCentreV + (double)lHeightMax / 2 + lBetween);
|
|
}
|
|
|
|
return 0;
|
|
}
|
|
|
|
inline LONG AppendDrawingPages2(CAtlArray<CDrawingPage>* pArray, const LONGLONG& lCenterHor, const double& dTop, const double& dBorderTop, LONG lBetween)
|
|
{
|
|
size_t nCount = m_arPages.GetCount();
|
|
|
|
// à âîò òóò íåïîíÿòíî êàê äåëàòü. äîáàâÿò âîçìîæíîñòü ñìîòðåòü
|
|
// ïðîèçâîëüíîå êîëè÷åñòâî ñòðàíèö - ñäåëàþ
|
|
if (1 == nCount)
|
|
{
|
|
CPage* pPage = m_arPages[0];
|
|
CDrawingPage oPage(pPage);
|
|
oPage.m_oGlobalBounds.left = lCenterHor - (double)(pPage->m_lPixWidth) / 2.0;
|
|
oPage.m_oGlobalBounds.right = lCenterHor + (double)(pPage->m_lPixWidth) / 2.0;
|
|
|
|
oPage.m_oGlobalBounds.top = dTop;
|
|
oPage.m_oGlobalBounds.bottom = (double)(oPage.m_oGlobalBounds.top + pPage->m_lPixHeight);
|
|
|
|
return (LONG)(oPage.m_oGlobalBounds.bottom + lBetween);
|
|
}
|
|
else if (2 == nCount)
|
|
{
|
|
CPage* pPage1 = m_arPages[0];
|
|
CPage* pPage2 = m_arPages[1];
|
|
|
|
LONG lHeight1 = pPage1->m_lPixHeight;
|
|
LONG lHeight2 = pPage2->m_lPixHeight;
|
|
|
|
LONG lHeightMax = max(lHeight1, lHeight2);
|
|
|
|
double dCentreV = dTop + ((double)lHeightMax) / 2;
|
|
|
|
LONGLONG lRight1 = lCenterHor - lBetween / 2;
|
|
|
|
CDrawingPage oPage1(pPage1);
|
|
oPage1.m_oGlobalBounds.left = (double)(lRight1 - pPage1->m_lPixWidth);
|
|
oPage1.m_oGlobalBounds.right = (double)lRight1;
|
|
|
|
oPage1.m_oGlobalBounds.top = dCentreV - (double)pPage1->m_lPixHeight / 2;
|
|
oPage1.m_oGlobalBounds.bottom = dCentreV + (double)pPage1->m_lPixHeight / 2;
|
|
|
|
LONGLONG lLeft2 = lCenterHor + lBetween / 2;
|
|
|
|
CDrawingPage oPage2(pPage2);
|
|
oPage2.m_oGlobalBounds.left = (double)(lLeft2);
|
|
oPage2.m_oGlobalBounds.right = (double)(lLeft2 + pPage2->m_lPixWidth);
|
|
|
|
oPage2.m_oGlobalBounds.top = dCentreV - (double)pPage2->m_lPixHeight / 2;
|
|
oPage2.m_oGlobalBounds.bottom = dCentreV + (double)pPage2->m_lPixHeight / 2;
|
|
|
|
pArray->Add(oPage1);
|
|
pArray->Add(oPage2);
|
|
|
|
return (LONG)(dCentreV + (double)lHeightMax / 2 + lBetween);
|
|
}
|
|
|
|
return 0;
|
|
}
|
|
};
|
|
|
|
// ñàìûé âåðõíèé êëàññ â èåðàðõèè
|
|
// ïðîñòî ìàññèâ áëîêîâ.
|
|
// âàæíàÿ ôóíêöèÿ - îòäàòü ÷àñòü áëîêîâ îòäåëüíûì äîêóìåíòîì.
|
|
// è íàäî ðåàëèçîâàòü çäåñü ñèíõðîíèçàöèþ ïîòîêîâ
|
|
class CDocument
|
|
{
|
|
public:
|
|
CAtlArray<CBlockPages> m_arBlocks;
|
|
LONG m_lCountPagesInBlock;
|
|
|
|
CRITICAL_SECTION m_oCS;
|
|
|
|
// òîëüêî îäèí ðàç ìîæíî âûñòàâèòü ãèïåðññûëêè
|
|
BOOL m_bIsSetupHyperlinks;
|
|
|
|
public:
|
|
CDocument() : m_arBlocks()
|
|
{
|
|
m_lCountPagesInBlock = 1;
|
|
|
|
InitializeCriticalSection(&m_oCS);
|
|
}
|
|
~CDocument()
|
|
{
|
|
DeleteCriticalSection(&m_oCS);
|
|
}
|
|
|
|
public:
|
|
|
|
inline ULONGLONG GetWidth(const LONG& lBetween)
|
|
{
|
|
CTemporaryCS oCS(&m_oCS);
|
|
|
|
ULONGLONG lWidth = 0;
|
|
size_t nCount = m_arBlocks.GetCount();
|
|
|
|
for (size_t nIndex = 0; nIndex < nCount; ++nIndex)
|
|
{
|
|
ULONGLONG lNew = (ULONGLONG)m_arBlocks[nIndex].GetWidth(lBetween);
|
|
if (lWidth < lNew)
|
|
{
|
|
lWidth = lNew;
|
|
}
|
|
}
|
|
return lWidth;
|
|
}
|
|
inline ULONGLONG GetHeightMax()
|
|
{
|
|
CTemporaryCS oCS(&m_oCS);
|
|
|
|
ULONGLONG lHeight = 0;
|
|
size_t nCount = m_arBlocks.GetCount();
|
|
|
|
for (size_t nIndex = 0; nIndex < nCount; ++nIndex)
|
|
{
|
|
ULONGLONG lNew = (ULONGLONG)m_arBlocks[nIndex].GetHeight();
|
|
if (lHeight < lNew)
|
|
{
|
|
lHeight = lNew;
|
|
}
|
|
}
|
|
return lHeight;
|
|
}
|
|
|
|
inline double GetWidthMM(double dPlus)
|
|
{
|
|
CTemporaryCS oCS(&m_oCS);
|
|
|
|
double max = 0;
|
|
size_t nCount = m_arBlocks.GetCount();
|
|
|
|
for (size_t nIndex = 0; nIndex < nCount; ++nIndex)
|
|
{
|
|
double lNew = m_arBlocks[nIndex].GetWidthMM(dPlus);
|
|
if (max < lNew)
|
|
{
|
|
max = lNew;
|
|
}
|
|
}
|
|
return max;
|
|
}
|
|
inline double GetHeightMM()
|
|
{
|
|
CTemporaryCS oCS(&m_oCS);
|
|
|
|
double max = 0;
|
|
size_t nCount = m_arBlocks.GetCount();
|
|
|
|
for (size_t nIndex = 0; nIndex < nCount; ++nIndex)
|
|
{
|
|
double lNew = m_arBlocks[nIndex].GetHeightMM();
|
|
if (max < lNew)
|
|
{
|
|
max = lNew;
|
|
}
|
|
}
|
|
return max;
|
|
}
|
|
|
|
inline ULONGLONG GetHeight()
|
|
{
|
|
CTemporaryCS oCS(&m_oCS);
|
|
|
|
ULONGLONG lHeight = 0;
|
|
size_t nCount = m_arBlocks.GetCount();
|
|
|
|
for (size_t nIndex = 0; nIndex < nCount; ++nIndex)
|
|
{
|
|
//lHeight += m_arPages[nIndex]->Height();
|
|
lHeight += m_arBlocks[nIndex].GetHeight();
|
|
}
|
|
return lHeight;
|
|
}
|
|
|
|
inline void CalculatePix(const double& dScaleX, const double& dScaleY)
|
|
{
|
|
CTemporaryCS oCS(&m_oCS);
|
|
|
|
size_t nCount = m_arBlocks.GetCount();
|
|
for (size_t i = 0; i < nCount; ++i)
|
|
{
|
|
m_arBlocks[i].CalculatePix(dScaleX, dScaleY);
|
|
}
|
|
}
|
|
|
|
inline void CloseFile()
|
|
{
|
|
CTemporaryCS oCS(&m_oCS);
|
|
|
|
size_t nCount = m_arBlocks.GetCount();
|
|
for (size_t i = 0; i < nCount; ++i)
|
|
{
|
|
m_arBlocks[i].DeletePages();
|
|
}
|
|
|
|
m_arBlocks.RemoveAll();
|
|
}
|
|
|
|
inline void Clear(bool bIsAttack = true)
|
|
{
|
|
CTemporaryCS oCS(&m_oCS);
|
|
|
|
if (!bIsAttack)
|
|
{
|
|
size_t nCountB = m_arBlocks.GetCount();
|
|
for (size_t i = 0; i < nCountB; ++i)
|
|
{
|
|
m_arBlocks[i].DeletePagesNoAttack();
|
|
}
|
|
}
|
|
|
|
m_arBlocks.RemoveAll();
|
|
}
|
|
inline void Remove(LONG lStartPage)
|
|
{
|
|
LONG lBlock = lStartPage / m_lCountPagesInBlock;
|
|
LONG lPage = lStartPage % m_lCountPagesInBlock;
|
|
|
|
LONG lBlocks = (LONG)m_arBlocks.GetCount();
|
|
if ((0 > lBlock) || (lBlock >= lBlocks))
|
|
return;
|
|
|
|
LONG lPages = (LONG)m_arBlocks[lBlock].m_arPages.GetCount();
|
|
if ((0 > lPage) || (lPage >= lPages))
|
|
return;
|
|
|
|
|
|
m_arBlocks[lBlock].m_arPages.RemoveAt(lPage, lPages - lPage);
|
|
|
|
if (0 == lPage)
|
|
{
|
|
m_arBlocks.RemoveAt(lBlock, lBlocks - lBlock);
|
|
}
|
|
else
|
|
{
|
|
m_arBlocks.RemoveAt(lBlock + 1, lBlocks - lBlock - 1);
|
|
}
|
|
}
|
|
|
|
inline LONG GetPixelsBetween(LONG lOne)
|
|
{
|
|
return (m_lCountPagesInBlock - 1) * lOne;
|
|
}
|
|
|
|
inline void GetCurrentDocument(CDocument* pDocument, LONG lStartBlock, LONG lCountBlocks)
|
|
{
|
|
CTemporaryCS oCS(&m_oCS);
|
|
|
|
pDocument->m_arBlocks.RemoveAll();
|
|
|
|
pDocument->m_lCountPagesInBlock = m_lCountPagesInBlock;
|
|
pDocument->Clear();
|
|
|
|
if (0 > lStartBlock)
|
|
lStartBlock = 0;
|
|
|
|
LONG lCount = (LONG)m_arBlocks.GetCount();
|
|
|
|
LONG lCountMax = lCount - lStartBlock;
|
|
if (lCountBlocks > lCountMax)
|
|
lCountBlocks = lCountMax;
|
|
|
|
for (LONG i = 0; i < lCountBlocks; ++i)
|
|
{
|
|
pDocument->m_arBlocks.Add(m_arBlocks[lStartBlock + i]);
|
|
}
|
|
}
|
|
|
|
inline void AddPage(CPage* pPage)
|
|
{
|
|
CTemporaryCS oCS(&m_oCS);
|
|
|
|
size_t nCount = m_arBlocks.GetCount();
|
|
if (0 == nCount)
|
|
{
|
|
m_arBlocks.Add();
|
|
m_arBlocks[nCount].m_arPages.Add(pPage);
|
|
|
|
BSTR bsLinks = NULL;
|
|
if (S_OK == pPage->m_pPage->get_Hypelinks(&bsLinks))
|
|
{
|
|
CString strXml = (CString)bsLinks;
|
|
HyperlinkSetup(strXml);
|
|
SysFreeString(bsLinks);
|
|
}
|
|
|
|
return;
|
|
}
|
|
|
|
if (m_arBlocks[nCount - 1].m_arPages.GetCount() < (size_t)m_lCountPagesInBlock)
|
|
{
|
|
m_arBlocks[nCount - 1].m_arPages.Add(pPage);
|
|
|
|
BSTR bsLinks = NULL;
|
|
if (S_OK == pPage->m_pPage->get_Hypelinks(&bsLinks))
|
|
{
|
|
CString strXml = (CString)bsLinks;
|
|
HyperlinkSetup(strXml);
|
|
SysFreeString(bsLinks);
|
|
}
|
|
|
|
return;
|
|
}
|
|
|
|
m_arBlocks.Add();
|
|
m_arBlocks[nCount].m_arPages.Add(pPage);
|
|
|
|
BSTR bsLinks = NULL;
|
|
if (S_OK == pPage->m_pPage->get_Hypelinks(&bsLinks))
|
|
{
|
|
CString strXml = (CString)bsLinks;
|
|
HyperlinkSetup(strXml);
|
|
SysFreeString(bsLinks);
|
|
}
|
|
}
|
|
|
|
inline CBlockPages GetBlock(size_t nIndex)
|
|
{
|
|
CTemporaryCS oCS(&m_oCS);
|
|
return m_arBlocks[nIndex];
|
|
}
|
|
|
|
inline size_t GetPagesCount()
|
|
{
|
|
CTemporaryCS oCS(&m_oCS);
|
|
|
|
LONG lCount = (LONG)m_arBlocks.GetCount();
|
|
if (0 == lCount)
|
|
return 0;
|
|
|
|
size_t nResult = m_lCountPagesInBlock * (lCount - 1);
|
|
nResult += m_arBlocks[lCount - 1].m_arPages.GetCount();
|
|
return nResult;
|
|
}
|
|
|
|
CPage* GetPage(LONG lIndexPage)
|
|
{
|
|
LONG lBlock = lIndexPage / m_lCountPagesInBlock;
|
|
LONG lPage = lIndexPage % m_lCountPagesInBlock;
|
|
|
|
if ((0 > lBlock) || (lBlock >= (LONG)m_arBlocks.GetCount()))
|
|
return NULL;
|
|
|
|
if ((0 > lPage) || (lPage >= (LONG)m_arBlocks[lBlock].m_arPages.GetCount()))
|
|
return NULL;
|
|
|
|
return m_arBlocks[lBlock].m_arPages[lPage];
|
|
}
|
|
|
|
bool SetCountPagesInBlock(LONG lCountPages)
|
|
{
|
|
if (m_lCountPagesInBlock == lCountPages)
|
|
return false;
|
|
|
|
CAtlArray<CPage*> arPages;
|
|
size_t nPages = GetPagesCount();
|
|
|
|
for (size_t i = 0; i < nPages; ++i)
|
|
{
|
|
CPage* pPage = GetPage((LONG)i);
|
|
arPages.Add(pPage);
|
|
}
|
|
|
|
Clear(false);
|
|
m_lCountPagesInBlock = lCountPages;
|
|
|
|
for (size_t i = 0; i < nPages; ++i)
|
|
{
|
|
AddPage(arPages[i]);
|
|
}
|
|
|
|
return true;
|
|
}
|
|
|
|
void HyperlinkSetup(CString& strXmlLinks)
|
|
{
|
|
if (m_bIsSetupHyperlinks && _T("") == strXmlLinks)
|
|
return;
|
|
|
|
m_bIsSetupHyperlinks = TRUE;
|
|
|
|
XmlUtils::CXmlNode oNodeLinker;
|
|
if (oNodeLinker.FromXmlString(strXmlLinks))
|
|
{
|
|
XmlUtils::CXmlNodes oNodeLinks;
|
|
if (oNodeLinker.GetNodes(_T("link"), oNodeLinks))
|
|
{
|
|
LONG lCount = oNodeLinks.GetCount();
|
|
LONG lCountPages = (LONG)GetPagesCount();
|
|
|
|
for (LONG i = 0; i < lCount; ++i)
|
|
{
|
|
XmlUtils::CXmlNode oLink;
|
|
oNodeLinks.GetAt(i, oLink);
|
|
|
|
CHyperlink oHL;
|
|
oHL.FromXml(oLink);
|
|
|
|
CPage* pPage = GetPage(oHL.m_lSrcPageIndex);
|
|
|
|
if (NULL != pPage)
|
|
{
|
|
pPage->m_oLinks.m_arLinks.Add(oHL);
|
|
}
|
|
}
|
|
}
|
|
}
|
|
}
|
|
};
|
|
|
|
} |