mirror of
https://github.com/ONLYOFFICE/core.git
synced 2026-04-07 13:55:33 +08:00
254 lines
6.0 KiB
C++
254 lines
6.0 KiB
C++
#include "FontPath.h"
|
|
|
|
//-------------------------------------------------------------------------------------------------------------------------------
|
|
// CPath
|
|
//-------------------------------------------------------------------------------------------------------------------------------
|
|
|
|
// Path может быть в одном из трех следующий состояний:
|
|
//
|
|
// 1. Нет текущей точки -- ни одного или более законченных SubPaths
|
|
// [m_nCurSubpath == m_nPointsCount]
|
|
//
|
|
// 2. Одна точка в SubPaths
|
|
// [m_nCurSubpath == m_nPointsCount - 1]
|
|
//
|
|
// 3. Открытый SubPaths c двумя или более точками
|
|
// [m_nCurSubpath < m_nPointsCount - 1]
|
|
|
|
CFontPath::CFontPath()
|
|
{
|
|
m_pPoints = NULL;
|
|
m_pFlags = NULL;
|
|
m_nPointsCount = m_nSize = 0;
|
|
m_nCurSubpath = 0;
|
|
|
|
m_pHints = NULL;
|
|
m_nHintsCount = m_nHintsSize = 0;
|
|
}
|
|
|
|
CFontPath::CFontPath(CFontPath *pPath)
|
|
{
|
|
m_nPointsCount = pPath->m_nPointsCount;
|
|
m_nSize = pPath->m_nSize;
|
|
m_pPoints = (TPathPoint *)malloc( m_nSize * sizeof(TPathPoint) );
|
|
m_pFlags = (unsigned char *)malloc( m_nSize * sizeof(unsigned char) );
|
|
|
|
memcpy( m_pPoints, pPath->m_pPoints, m_nPointsCount * sizeof(TPathPoint) );
|
|
memcpy( m_pFlags, pPath->m_pFlags, m_nPointsCount * sizeof(unsigned char) );
|
|
|
|
m_nCurSubpath = pPath->m_nCurSubpath;
|
|
|
|
if ( pPath->m_pHints )
|
|
{
|
|
m_nHintsCount = m_nHintsSize = pPath->m_nHintsCount;
|
|
m_pHints = (TPathHint *)malloc( m_nHintsSize * sizeof(TPathHint) );
|
|
memcpy( m_pHints, pPath->m_pHints, m_nHintsCount * sizeof(TPathHint) );
|
|
}
|
|
else
|
|
{
|
|
m_pHints = NULL;
|
|
}
|
|
}
|
|
|
|
CFontPath::~CFontPath()
|
|
{
|
|
free( m_pPoints );
|
|
free( m_pFlags );
|
|
free( m_pHints );
|
|
}
|
|
|
|
void CFontPath::Resize(int nPointsCount)
|
|
{
|
|
if ( m_nPointsCount + nPointsCount > m_nSize )
|
|
{
|
|
if ( m_nSize == 0 )
|
|
{
|
|
m_nSize = 32;
|
|
}
|
|
while ( m_nSize < m_nPointsCount + nPointsCount )
|
|
{
|
|
m_nSize *= 2;
|
|
}
|
|
m_pPoints = (TPathPoint *)realloc( m_pPoints, m_nSize * sizeof(TPathPoint) );
|
|
m_pFlags = (unsigned char *)realloc( m_pFlags, m_nSize * sizeof(unsigned char) );
|
|
}
|
|
}
|
|
|
|
void CFontPath::Append(CFontPath *pPath)
|
|
{
|
|
m_nCurSubpath = m_nPointsCount + pPath->m_nCurSubpath;
|
|
Resize( pPath->m_nPointsCount );
|
|
|
|
for ( int nIndex = 0; nIndex < pPath->m_nPointsCount; ++nIndex )
|
|
{
|
|
m_pPoints[m_nPointsCount] = pPath->m_pPoints[nIndex];
|
|
m_pFlags[m_nPointsCount] = pPath->m_pFlags[nIndex];
|
|
++m_nPointsCount;
|
|
}
|
|
}
|
|
|
|
int CFontPath::MoveTo(double dX, double dY)
|
|
{
|
|
if ( OnePointSubpath() )
|
|
{
|
|
return -1;
|
|
}
|
|
Resize(1);
|
|
m_pPoints[m_nPointsCount].dX = dX;
|
|
m_pPoints[m_nPointsCount].dY = dY;
|
|
m_pFlags[m_nPointsCount] = PathFirst | PathLast;
|
|
m_nCurSubpath = m_nPointsCount++;
|
|
|
|
return 0;
|
|
}
|
|
|
|
int CFontPath::LineTo(double dX, double dY)
|
|
{
|
|
if ( NoCurrentPoint() )
|
|
{
|
|
return -1;
|
|
}
|
|
m_pFlags[m_nPointsCount - 1] &= ~PathLast;
|
|
Resize(1);
|
|
|
|
m_pPoints[m_nPointsCount].dX = dX;
|
|
m_pPoints[m_nPointsCount].dY = dY;
|
|
m_pFlags[m_nPointsCount] = PathLast;
|
|
++m_nPointsCount;
|
|
|
|
return 0;
|
|
}
|
|
|
|
int CFontPath::CurveTo(double dX1, double dY1, double dX2, double dY2, double dX3, double dY3)
|
|
{
|
|
if ( NoCurrentPoint() )
|
|
{
|
|
return -1;
|
|
}
|
|
|
|
m_pFlags[m_nPointsCount-1] &= ~PathLast;
|
|
Resize(3);
|
|
|
|
m_pPoints[m_nPointsCount].dX = dX1;
|
|
m_pPoints[m_nPointsCount].dY = dY1;
|
|
m_pFlags[m_nPointsCount] = PathCurve;
|
|
++m_nPointsCount;
|
|
|
|
m_pPoints[m_nPointsCount].dX = dX2;
|
|
m_pPoints[m_nPointsCount].dY = dY2;
|
|
m_pFlags[m_nPointsCount] = PathCurve;
|
|
++m_nPointsCount;
|
|
|
|
m_pPoints[m_nPointsCount].dX = dX3;
|
|
m_pPoints[m_nPointsCount].dY = dY3;
|
|
m_pFlags[m_nPointsCount] = PathLast;
|
|
++m_nPointsCount;
|
|
|
|
return 0;
|
|
}
|
|
|
|
int CFontPath::Close()
|
|
{
|
|
if ( NoCurrentPoint() )
|
|
{
|
|
return -1;
|
|
}
|
|
if ( m_nCurSubpath == m_nPointsCount - 1 || m_pPoints[m_nPointsCount - 1].dX != m_pPoints[m_nCurSubpath].dX || m_pPoints[m_nPointsCount - 1].dY != m_pPoints[m_nCurSubpath].dY )
|
|
{
|
|
LineTo( m_pPoints[m_nCurSubpath].dX, m_pPoints[m_nCurSubpath].dY );
|
|
}
|
|
|
|
m_pFlags[m_nCurSubpath] |= PathClosed;
|
|
m_pFlags[m_nPointsCount - 1] |= PathClosed;
|
|
m_nCurSubpath = m_nPointsCount;
|
|
|
|
return 0;
|
|
}
|
|
|
|
void CFontPath::AddStrokeAdjustHint(int nFirstControl, int nSecondControl, int nFirstPoint, int nLastPoint)
|
|
{
|
|
if ( m_nHintsCount == m_nHintsSize )
|
|
{
|
|
m_nHintsSize = m_nHintsCount ? 2 * m_nHintsCount : 8;
|
|
m_pHints = (TPathHint *)realloc( m_pHints, m_nHintsSize * sizeof(TPathHint) );
|
|
}
|
|
m_pHints[m_nHintsCount].nFirstControl = nFirstControl;
|
|
m_pHints[m_nHintsCount].nSecondControl = nSecondControl;
|
|
m_pHints[m_nHintsCount].nFirstPoint = nFirstPoint;
|
|
m_pHints[m_nHintsCount].nLastPoint = nLastPoint;
|
|
|
|
++m_nHintsCount;
|
|
}
|
|
|
|
void CFontPath::Offset(double dDx, double dDy)
|
|
{
|
|
for ( int nIndex = 0; nIndex < m_nPointsCount; ++nIndex )
|
|
{
|
|
m_pPoints[nIndex].dX += dDx;
|
|
m_pPoints[nIndex].dY += dDy;
|
|
}
|
|
}
|
|
|
|
void CFontPath::Reverse()
|
|
{
|
|
for ( int nIndex = 0; nIndex < m_nPointsCount; ++nIndex )
|
|
{
|
|
m_pPoints[nIndex].dY = -m_pPoints[nIndex].dY;
|
|
}
|
|
}
|
|
|
|
void CFontPath::ToMM(double dHorDpi, double dVerDpi)
|
|
{
|
|
for ( int nIndex = 0; nIndex < m_nPointsCount; ++nIndex )
|
|
{
|
|
m_pPoints[nIndex].dX *= 25.4 / dHorDpi;
|
|
m_pPoints[nIndex].dY *= 25.4 / dVerDpi;
|
|
}
|
|
}
|
|
|
|
BOOL CFontPath::GetCurPoint(double *pdX, double *pdY)
|
|
{
|
|
if ( NoCurrentPoint() )
|
|
{
|
|
return FALSE;
|
|
}
|
|
*pdX = m_pPoints[m_nPointsCount - 1].dX;
|
|
*pdY = m_pPoints[m_nPointsCount - 1].dY;
|
|
return TRUE;
|
|
}
|
|
|
|
BOOL CFontPath::ToInterface(ISimpleGraphicsPath* pPath)
|
|
{
|
|
if ( !pPath )
|
|
return FALSE;
|
|
|
|
for ( int nIndex = 0; nIndex < m_nPointsCount; )
|
|
{
|
|
TPathPoint oPoint = m_pPoints[nIndex];
|
|
unsigned char nFlag = m_pFlags[nIndex];
|
|
|
|
if ( nFlag & PathFirst )
|
|
{
|
|
pPath->_MoveTo( oPoint.dX, oPoint.dY );
|
|
nIndex++;
|
|
}
|
|
else if ( nFlag & PathCurve )
|
|
{
|
|
pPath->_CurveTo( m_pPoints[nIndex + 0].dX, m_pPoints[nIndex + 0].dY, m_pPoints[nIndex + 1].dX, m_pPoints[nIndex + 1].dY, m_pPoints[nIndex + 2].dX, m_pPoints[nIndex + 2].dY );
|
|
nIndex += 3;
|
|
}
|
|
else
|
|
{
|
|
pPath->_LineTo( oPoint.dX, oPoint.dY );
|
|
nIndex++;
|
|
}
|
|
|
|
if ( nFlag & PathClosed && nFlag & PathLast )
|
|
{
|
|
pPath->_Close();
|
|
}
|
|
|
|
}
|
|
|
|
return TRUE;
|
|
} |