Commit 86885c37 authored by Elen.Subbotina's avatar Elen.Subbotina Committed by Alexander Trofimov

.....

git-svn-id: svn://fileserver/activex/AVS/Sources/TeamlabOffice/trunk/ServerComponents@61943 954022d7-b5bf-4e40-9824-e11837661b57
parent 62f42732
//
//
//////////////////////////////////////////////////////////////////////
#ifndef _AGGPLUSENUMS_H
#define _AGGPLUSENUMS_H
#include "aggplustypes.h"
namespace Aggplus
{
#define PixelFormatIndexed 0x00010000 // Indexes into a palette
#define PixelFormatGDI 0x00020000 // Is a GDI-supported format
#define PixelFormatAlpha 0x00040000 // Has an alpha component
#define PixelFormatPAlpha 0x00080000 // Pre-multiplied alpha
#define PixelFormatExtended 0x00100000 // Extended color 16 bits/channel
#define PixelFormatCanonical 0x00200000
#define PixelFormatUndefined 0
#define PixelFormatDontCare 0
#define PixelFormat1bppIndexed (1 | ( 1 << 8) | PixelFormatIndexed | PixelFormatGDI)
#define PixelFormat4bppIndexed (2 | ( 4 << 8) | PixelFormatIndexed | PixelFormatGDI)
#define PixelFormat8bppIndexed (3 | ( 8 << 8) | PixelFormatIndexed | PixelFormatGDI)
#define PixelFormat16bppGrayScale (4 | (16 << 8) | PixelFormatExtended)
#define PixelFormat16bppRGB555 (5 | (16 << 8) | PixelFormatGDI)
#define PixelFormat16bppRGB565 (6 | (16 << 8) | PixelFormatGDI)
#define PixelFormat16bppARGB1555 (7 | (16 << 8) | PixelFormatAlpha | PixelFormatGDI)
#define PixelFormat24bppRGB (8 | (24 << 8) | PixelFormatGDI)
#define PixelFormat32bppRGB (9 | (32 << 8) | PixelFormatGDI)
#define PixelFormat32bppARGB (10 | (32 << 8) | PixelFormatAlpha | PixelFormatGDI | PixelFormatCanonical)
#define PixelFormat32bppPARGB (11 | (32 << 8) | PixelFormatAlpha | PixelFormatPAlpha | PixelFormatGDI)
#define PixelFormat48bppRGB (12 | (48 << 8) | PixelFormatExtended)
#define PixelFormat64bppARGB (13 | (64 << 8) | PixelFormatAlpha | PixelFormatCanonical | PixelFormatExtended)
#define PixelFormat64bppPARGB (14 | (64 << 8) | PixelFormatAlpha | PixelFormatPAlpha | PixelFormatExtended)
#ifndef PixelFormatMax
#define PixelFormatMax 15
#endif
//--------------------------------------------------------------------------
// Matrix Order
//--------------------------------------------------------------------------
enum MatrixOrder
{
MatrixOrderPrepend = 0,
MatrixOrderAppend = 1
};
//--------------------------------------------------------------------------
// Dash style constants
//--------------------------------------------------------------------------
enum DashStyle
{
DashStyleSolid, // 0
DashStyleDash, // 1
DashStyleDot, // 2
DashStyleDashDot, // 3
DashStyleDashDotDot, // 4
DashStyleCustom // 5
};
//--------------------------------------------------------------------------
// Line join constants
//--------------------------------------------------------------------------
enum LineJoin
{
LineJoinMiter = 0,
LineJoinBevel = 1,
LineJoinRound = 2,
LineJoinMiterClipped = 3
};
//--------------------------------------------------------------------------
// Line cap constants
//--------------------------------------------------------------------------
enum LineCap
{
LineCapFlat = 0,
LineCapSquare = 1,
LineCapRound = 2,
LineCapTriangle = 3,
LineCapNoAnchor = 0x10, // corresponds to flat cap
LineCapSquareAnchor = 0x11, // corresponds to square cap
LineCapRoundAnchor = 0x12, // corresponds to round cap
LineCapDiamondAnchor = 0x13, // corresponds to triangle cap
LineCapArrowAnchor = 0x14, // no correspondence
LineCapCustom = 0xff, // custom cap
LineCapAnchorMask = 0xf0 // mask to check for anchor or not.
};
//--------------------------------------------------------------------------
// Brush types
//--------------------------------------------------------------------------
enum BrushType
{
BrushTypeSolidColor = 0,
BrushTypeHatchFill = 1,
BrushTypeTextureFill = 2,
BrushTypePathGradient = 3,
BrushTypeLinearGradient = 4
};
//--------------------------------------------------------------------------
// Various wrap modes for brushes
//--------------------------------------------------------------------------
enum WrapMode
{
WrapModeTile, // 0
WrapModeTileFlipX, // 1
WrapModeTileFlipY, // 2
WrapModeTileFlipXY, // 3
WrapModeClamp // 4
};
//--------------------------------------------------------------------------
// LineGradient Mode
//--------------------------------------------------------------------------
enum LinearGradientMode
{
LinearGradientModeHorizontal, // 0
LinearGradientModeVertical, // 1
LinearGradientModeForwardDiagonal, // 2
LinearGradientModeBackwardDiagonal // 3
};
//--------------------------------------------------------------------------
// FontStyle: face types and common styles
//--------------------------------------------------------------------------
enum FontStyle
{
FontStyleRegular = 0,
FontStyleBold = 1,
FontStyleItalic = 2,
FontStyleBoldItalic = 3,
FontStyleUnderline = 4,
FontStyleStrikeout = 8
};
//---------------------------------------------------------------------------
// String alignment flags
//---------------------------------------------------------------------------
enum StringAlignment
{
// Left edge for left-to-right text,
// right for right-to-left text,
// and top for vertical
StringAlignmentNear = 0,
StringAlignmentCenter = 1,
StringAlignmentFar = 2
};
//############## Not implemented-Used
//--------------------------------------------------------------------------
// Unit constants
//--------------------------------------------------------------------------
enum Unit
{
UnitWorld, // 0 -- World coordinate (non-physical unit)
UnitDisplay, // 1 -- Variable -- for PageTransform only
UnitPixel, // 2 -- Each unit is one device pixel.
UnitPoint, // 3 -- Each unit is a printer's point, or 1/72 inch.
UnitInch, // 4 -- Each unit is 1 inch.
UnitDocument, // 5 -- Each unit is 1/300 inch.
UnitMillimeter // 6 -- Each unit is 1 millimeter.
};
//---------------------------------------------------------------------------
// Text Rendering Hint
//---------------------------------------------------------------------------
enum TextRenderingHint
{
TextRenderingHintSystemDefault = 0, // Glyph with system default rendering hint
TextRenderingHintSingleBitPerPixelGridFit, // Glyph bitmap with hinting
TextRenderingHintSingleBitPerPixel, // Glyph bitmap without hinting
TextRenderingHintAntiAliasGridFit, // Glyph anti-alias bitmap with hinting
TextRenderingHintAntiAlias, // Glyph anti-alias bitmap without hinting
TextRenderingHintClearTypeGridFit // Glyph CT bitmap with hinting
};
//--------------------------------------------------------------------------
// Quality mode constants
//--------------------------------------------------------------------------
enum QualityMode
{
QualityModeInvalid = -1,
QualityModeDefault = 0,
QualityModeLow = 1, // Best performance
QualityModeHigh = 2 // Best rendering quality
};
//--------------------------------------------------------------------------
// Alpha Compositing mode constants
//--------------------------------------------------------------------------
enum CompositingMode
{
CompositingModeSourceOver, // 0
CompositingModeSourceCopy // 1
};
//--------------------------------------------------------------------------
// Alpha Compositing quality constants
//--------------------------------------------------------------------------
enum CompositingQuality
{
CompositingQualityInvalid = QualityModeInvalid,
CompositingQualityDefault = QualityModeDefault,
CompositingQualityHighSpeed = QualityModeLow,
CompositingQualityHighQuality = QualityModeHigh,
CompositingQualityGammaCorrected,
CompositingQualityAssumeLinear
};
//---------------------------------------------------------------------------
// Smoothing Mode
//---------------------------------------------------------------------------
enum SmoothingMode
{
SmoothingModeInvalid = QualityModeInvalid,
SmoothingModeDefault = QualityModeDefault,
SmoothingModeHighSpeed = QualityModeLow,
SmoothingModeHighQuality = QualityModeHigh,
SmoothingModeNone,
SmoothingModeAntiAlias
};
//--------------------------------------------------------------------------
// Interpolation modes
//--------------------------------------------------------------------------
enum InterpolationMode
{
InterpolationModeInvalid = QualityModeInvalid,
InterpolationModeDefault = QualityModeDefault,
InterpolationModeLowQuality = QualityModeLow,
InterpolationModeHighQuality = QualityModeHigh,
InterpolationModeBilinear,
InterpolationModeBicubic,
InterpolationModeNearestNeighbor,
InterpolationModeHighQualityBilinear,
InterpolationModeHighQualityBicubic
};
enum StringFormatFlags
{
//not supp StringFormatFlagsDirectionRightToLeft = 0x00000001,
//not supp StringFormatFlagsDirectionVertical = 0x00000002,
//not supp StringFormatFlagsNoFitBlackBox = 0x00000004,
//not supp StringFormatFlagsDisplayFormatControl = 0x00000020,
//not supp StringFormatFlagsNoFontFallback = 0x00000400,
//not supp StringFormatFlagsMeasureTrailingSpaces = 0x00000800,
//not supp StringFormatFlagsNoWrap = 0x00001000,
StringFormatFlagsLineLimit = 0x00002000
//not supp StringFormatFlagsNoClip = 0x00004000
};
} //namespace Aggplus
#endif // !defined(_AGGPLUSENUMS_H)
\ No newline at end of file
#include "ArrowHead.h"
namespace Aggplus
{
CArrowHead::CArrowHead()
{
m_lType = 0;
m_bIsMoveTo = false;
m_dX1 = 0;
m_dY1 = 0;
m_dX2 = 1;
m_dY2 = 1;
}
CArrowHead::~CArrowHead()
{
}
void CArrowHead::SetType(LONG lType)
{
m_lType = lType;
switch (m_lType)
{
case Aggplus::LineCapSquareAnchor:
case Aggplus::LineCapRoundAnchor:
case Aggplus::LineCapDiamondAnchor:
case Aggplus::LineCapArrowAnchor:
break;
default:
m_lType = 0;
break;
}
}
bool CArrowHead::IsNeed()
{
return (0 != m_lType);
}
void CArrowHead::PathCommandMoveTo(double fX, double fY)
{
if (!IsNeed())
return;
m_bIsMoveTo = true;
m_oPath.MoveTo(fX, fY);
m_oPath.LineTo(fX, fY);
}
void CArrowHead::PathCommandLineTo(double fX, double fY)
{
if (!IsNeed())
return;
m_oPath.LineTo(fX, fY);
}
void CArrowHead::PathCommandLinesTo(double* pPoints, LONG lCount)
{
if (!IsNeed())
return;
if (!m_bIsMoveTo && (lCount >= 2))
{
PathCommandMoveTo(pPoints[0], pPoints[1]);
}
m_oPath.AddLines(pPoints, lCount);
}
void CArrowHead::PathCommandCurveTo(double fX1, double fY1, double fX2, double fY2, double fX3, double fY3)
{
if (!IsNeed())
return;
m_oPath.CurveTo(fX1, fY1, fX2, fY2, fX3, fY3);
}
void CArrowHead::PathCommandCurvesTo(double* pPoints, LONG lCount)
{
if (!IsNeed())
return;
if (!m_bIsMoveTo && (lCount >= 2))
{
PathCommandMoveTo(pPoints[0], pPoints[1]);
}
m_oPath.AddBeziers(pPoints, lCount);
}
void CArrowHead::PathCommandArcTo(double fX, double fY, double fWidth, double fHeight, double fStartAngle, double fSweepAngle)
{
if (!IsNeed())
return;
m_oPath.AddArc2(fX, fY, fWidth, fHeight, -fStartAngle, -fSweepAngle);
}
void CArrowHead::PathCommandClose()
{
if (!IsNeed())
return;
m_oPath.Reset();
}
void CArrowHead::PathCommandEnd()
{
if (!IsNeed())
return;
m_oPath.Reset();
m_bIsMoveTo = false;
}
void CArrowHead::PathCommandStart()
{
if (!IsNeed())
return;
m_oPath.StartFigure();
}
bool CArrowHead::DrawPath(LONG lType)
{
if (!IsNeed())
return false;
if (lType & 0x01)
{
m_oPath.Transform(&m_oTransform);
LONG lCount = (LONG)m_oPath.GetPointCount();
if (2 > lCount)
return false;
double* pPoints = new double[2 * lCount];
m_oPath.GetPathPoints(pPoints, lCount);
m_dX1 = pPoints[2 * lCount - 4];
m_dY1 = pPoints[2 * lCount - 3];
m_dX2 = pPoints[2 * lCount - 2];
m_dY2 = pPoints[2 * lCount - 1];
RELEASEARRAYOBJECTS(pPoints);
return true;
}
return false;
}
}
\ No newline at end of file
#ifndef _BUILD_ARROW_HEAD_H_
#define _BUILD_ARROW_HEAD_H_
#include "GraphicsPath.h"
namespace Aggplus
{
class CArrowHead
{
private:
LONG m_lType;
CMatrix m_oTransform;
bool m_bIsMoveTo;
CGraphicsPath m_oPath;
public:
double m_dX1;
double m_dY1;
double m_dX2;
double m_dY2;
public:
CArrowHead();
~CArrowHead();
public:
void SetType(LONG lType);
bool IsNeed();
void PathCommandMoveTo(double fX, double fY);
void PathCommandLineTo(double fX, double fY);
void PathCommandLinesTo(double* pPoints, LONG lCount);
void PathCommandCurveTo(double fX1, double fY1, double fX2, double fY2, double fX3, double fY3);
void PathCommandCurvesTo(double* pPoints, LONG lCount);
void PathCommandArcTo(double fX, double fY, double fWidth, double fHeight, double fStartAngle, double fSweepAngle);
void PathCommandClose();
void PathCommandEnd();
void PathCommandStart();
bool DrawPath(LONG lType);
};
}
#endif // _BUILD_ARROW_HEAD_H_
\ No newline at end of file
#ifndef _BUILD_BASETHREAD_H_
#define _BUILD_BASETHREAD_H_
#include "../common/Types.h"
#if defined(_WIN32) || defined(_WIN64) ||defined(_WIN32_WCE)
#include "windows.h"
#include "winbase.h"
#else
#include <pthread.h>
#include <signal.h>
#include "time.h"
#endif
namespace NSThreads
{
class CThreadDescriptor
{
public:
CThreadDescriptor(){}
virtual ~CThreadDescriptor(){}
};
static void Sleep(int nMilliseconds)
{
#if defined(_WIN32) || defined(_WIN64) || defined(_WIN32_WCE)
::Sleep((DWORD)nMilliseconds);
#else
struct timespec tim, tim2;
tim.tv_sec = nMilliseconds / 1000;
tim.tv_nsec = (nMilliseconds % 1000) * 1000000;
::nanosleep(&tim , &tim2);
#endif
}
class CBaseThread
{
protected:
CThreadDescriptor* m_hThread;
INT m_bRunThread;
INT m_bSuspend;
int m_lError;
int m_lThreadPriority;
public:
CBaseThread()
{
m_hThread = NULL;
m_bRunThread = FALSE;
m_bSuspend = FALSE;
m_lError = 0;
m_lThreadPriority = 0;
}
virtual ~CBaseThread()
{
Stop();
}
public:
virtual void Start(int lPriority)
{
if (m_bRunThread)
return;
m_lError = 0;
m_bSuspend = FALSE;
m_hThread = new __native_thread();
m_bRunThread = TRUE;
#if defined(_WIN32) || defined(_WIN64) || defined(_WIN32_WCE)
DWORD dwTemp;
((__native_thread*)m_hThread)->m_thread = CreateThread(NULL, 0, &__ThreadProc, (void*)this, 0, &dwTemp);
SetThreadPriority(((__native_thread*)m_hThread)->m_thread, lPriority);
#else
pthread_create(&((__native_thread*)m_hThread)->m_thread, 0, &__ThreadProc, (void*)this);
#endif
m_lThreadPriority = lPriority;
}
virtual void Suspend()
{
m_bSuspend = TRUE;
}
virtual void Resume()
{
m_bSuspend = FALSE;
}
virtual void Stop()
{
if (!m_bRunThread)
return;
m_bRunThread = FALSE;
Join();
RELEASEOBJECT(m_hThread);
}
inline INT IsSuspended() { return m_bSuspend; }
inline INT IsRunned() { return m_bRunThread; }
inline int GetError() { return m_lError; }
inline CThreadDescriptor* GetDescriptor() { return m_hThread; }
inline int GetPriority() { return m_lThreadPriority; }
virtual void CheckSuspend()
{
while (m_bSuspend && m_bRunThread)
NSThreads::Sleep(10);
}
protected:
virtual void Join()
{
if (NULL == m_hThread)
return;
#if defined(_WIN32) || defined(_WIN64) || defined(_WIN32_WCE)
WaitForSingleObject(((__native_thread*)m_hThread)->m_thread, INFINITE);
#else
pthread_join(((__native_thread*)m_hThread)->m_thread, 0);
#endif
}
virtual DWORD ThreadProc() = 0;
private:
#if defined(_WIN32) || defined(_WIN64) || defined(_WIN32_WCE)
static DWORD WINAPI __ThreadProc(void* pv)
{
CBaseThread* pThis = (CBaseThread*)pv;
return pThis->ThreadProc();
}
class __native_thread : public NSThreads::CThreadDescriptor
{
friend class CBaseThread;
private:
HANDLE m_thread;
public:
__native_thread() : CThreadDescriptor()
{
m_thread = NULL;
}
virtual ~__native_thread()
{
if (m_thread != NULL)
{
CloseHandle(m_thread);
m_thread = NULL;
}
}
};
#else
static void* __ThreadProc(void* pv)
{
int old_thread_type;
pthread_setcanceltype(PTHREAD_CANCEL_ASYNCHRONOUS, &old_thread_type);
CBaseThread* pThis = (CBaseThread*)pv;
pThis->ThreadProc();
return NULL;
}
class __native_thread : public NSThreads::CThreadDescriptor
{
friend class CBaseThread;
private:
pthread_t m_thread;
public:
__native_thread() : CThreadDescriptor()
{
m_thread = NULL;
}
virtual ~__native_thread()
{
}
};
#endif
};
}
#endif // _BUILD_BASETHREAD_H_
#include "Brush.h"
namespace Aggplus
{
////////////////////////////////////////////////////////////////////////////////
CBrush::CBrush(BrushType bType) : m_bType(bType)
{
}
CBrush::~CBrush()
{
}
BrushType CBrush::GetType() const
{
return m_bType;
}
////////////////////////////////////////////////////////////////////////////////
CBrushSolid::CBrushSolid(CColor dwColor) : CBrush(BrushTypeSolidColor), m_dwColor(dwColor)
{
}
CBrushSolid::~CBrushSolid()
{
}
CBrush* CBrushSolid::Clone() const
{
return new CBrushSolid(m_dwColor);
}
void CBrushSolid::GetColor(CColor* color) const { *color = m_dwColor; }
void CBrushSolid::SetColor(const CColor &color) { m_dwColor = color; }
////////////////////////////////////////////////////////////////////////////////
CBrushHatch::CBrushHatch() : CBrush(BrushTypeHatchFill)
{
}
CBrushHatch::~CBrushHatch()
{
}
CBrush* CBrushHatch::Clone() const
{
CBrushHatch* clone = new CBrushHatch();
clone->m_name = m_name;
clone->m_dwColor1 = m_dwColor1;
clone->m_dwColor2 = m_dwColor2;
return clone;
}
////////////////////////////////////////////////////////////////////////////////
CBrushLinearGradient::CBrushLinearGradient( const PointF& p1, const PointF& p2, const CColor& c1, const CColor& c2 )
: CBrush(BrushTypeLinearGradient)
{
m_points[0] = p1;
m_points[1] = p2;
m_colors[0] = c1;
m_colors[1] = c2;
m_angle = 0;
m_wrap = Aggplus::WrapModeTile;
m_bAngleScalable = FALSE;
m_bRectable = FALSE;
m_bRelativeCoords = FALSE;
}
CBrushLinearGradient::CBrushLinearGradient( const Point& p1, const Point& p2, const CColor& c1, const CColor& c2 )
: CBrush(BrushTypeLinearGradient)
{
m_points[0].X = (float)p1.X;
m_points[0].Y = (float)p1.Y;
m_points[1].X = (float)p2.X;
m_points[1].Y = (float)p2.Y;
m_colors[0] = c1;
m_colors[1] = c2;
m_angle = 0;
m_wrap = Aggplus::WrapModeTile;
m_bAngleScalable = FALSE;
m_bRectable = FALSE;
m_bRelativeCoords = FALSE;
}
CBrushLinearGradient::CBrushLinearGradient( const RectF& rect, const CColor& c1, const CColor& c2, float angle, INT isAngleScalable )
: CBrush(BrushTypeLinearGradient)
{
m_points[0].X = rect.GetLeft();
m_points[0].Y = rect.GetTop();
m_points[1].X = rect.GetRight();
m_points[1].Y = rect.GetBottom();
m_colors[0] = c1;
m_colors[1] = c2;
m_angle = angle;
m_wrap = Aggplus::WrapModeTile;
m_bAngleScalable = isAngleScalable;
m_bRectable = TRUE;
m_bRelativeCoords = FALSE;
}
CBrushLinearGradient::CBrushLinearGradient( const Rect& rect, const CColor& c1, const CColor& c2, float angle, INT isAngleScalable )
: CBrush(BrushTypeLinearGradient)
{
m_points[0].X = (float)rect.GetLeft();
m_points[0].Y = (float)rect.GetTop();
m_points[1].X = (float)rect.GetRight();
m_points[1].Y = (float)rect.GetBottom();
m_colors[0] = c1;
m_colors[1] = c2;
m_angle = angle;
m_wrap = Aggplus::WrapModeTile;
m_bAngleScalable = isAngleScalable;
m_bRectable = TRUE;
m_bRelativeCoords = FALSE;
}
CBrushLinearGradient::CBrushLinearGradient( const RectF& rect, const CColor& c1, const CColor& c2, Aggplus::LinearGradientMode mode )
: CBrush(BrushTypeLinearGradient)
{
m_points[0].X = rect.GetLeft();
m_points[0].Y = rect.GetTop();
m_points[1].X = rect.GetRight();
m_points[1].Y = rect.GetBottom();
switch( mode )
{
case LinearGradientModeHorizontal:
m_angle = 0;
break;
case LinearGradientModeVertical:
m_angle = 90;
break;
case LinearGradientModeForwardDiagonal:
m_angle = 45;
break;
default:
m_angle = 315;
}
m_colors[0] = c1;
m_colors[1] = c2;
m_wrap = Aggplus::WrapModeTile;
m_bAngleScalable = TRUE;
m_bRectable = TRUE;
m_bRelativeCoords = FALSE;
}
CBrushLinearGradient::CBrushLinearGradient( const Rect& rect, const CColor& c1, const CColor& c2, Aggplus::LinearGradientMode mode )
: CBrush(BrushTypeLinearGradient)
{
m_points[0].X = (REAL)rect.GetLeft();
m_points[0].Y = (REAL)rect.GetTop();
m_points[1].X = (REAL)rect.GetRight();
m_points[1].Y = (REAL)rect.GetBottom();
switch( mode )
{
case LinearGradientModeHorizontal:
m_angle = 0;
break;
case LinearGradientModeVertical:
m_angle = 90;
break;
case LinearGradientModeForwardDiagonal:
m_angle = 45;
break;
default:
m_angle = 315;
}
m_colors[0] = c1;
m_colors[1] = c2;
m_wrap = Aggplus::WrapModeTile;
m_bAngleScalable = TRUE;
m_bRectable = TRUE;
m_bRelativeCoords = FALSE;
}
CBrushLinearGradient::CBrushLinearGradient( const CBrushLinearGradient& out )
: CBrush(out.m_bType)
{
m_colors[0] = out.m_colors[0];
m_colors[1] = out.m_colors[1];
m_points[0] = out.m_points[0];
m_points[1] = out.m_points[1];
m_subcolors = out.m_subcolors;
m_matrix = out.m_matrix;
m_angle = out.m_angle;
m_wrap = out.m_wrap;
m_bAngleScalable = out.m_bAngleScalable;
m_bRectable = out.m_bRectable;
m_bRelativeCoords = out.m_bRelativeCoords;
}
Status CBrushLinearGradient::GetLinearColors( CColor* colors ) const
{
if( !colors )
return InvalidParameter;
colors[0] = m_colors[0];
colors[1] = m_colors[1];
return Ok;
}
Status CBrushLinearGradient::GetRectangle( Rect *rect ) const
{
if( !rect )
return InvalidParameter;
rect->X = (int)( m_points[0].X );
rect->Y = (int)( m_points[0].Y );
rect->Width = (int)( m_points[1].X ) - rect->X;
rect->Height = (int)( m_points[1].Y ) - rect->Y;
return Ok;
}
Status CBrushLinearGradient::GetRectangle( RectF *rect ) const
{
if( !rect )
return InvalidParameter;
rect->X = m_points[0].X;
rect->Y = m_points[0].Y;
rect->Width = m_points[1].X - rect->X;
rect->Height = m_points[1].Y - rect->Y;
return Ok;
}
Status CBrushLinearGradient::GetTransform( CMatrix* matrix ) const
{
if( !matrix )
return InvalidParameter;
*matrix = m_matrix;
return Ok;
}
Status CBrushLinearGradient::MultiplyTransform( const CMatrix *matrix, MatrixOrder order)
{
if( !matrix )
return InvalidParameter;
m_matrix.Multiply( matrix, order );
return Ok;
}
Status CBrushLinearGradient::ResetTransform()
{
m_matrix.Reset();
return Ok;
}
Status CBrushLinearGradient::RotateTransform( REAL angle, MatrixOrder order )
{
m_matrix.Rotate( angle, order );
return Ok;
}
Status CBrushLinearGradient::ScaleTransform( REAL sx, REAL sy, MatrixOrder order )
{
m_matrix.Scale( sx, sy, order );
return Ok;
}
void CBrushLinearGradient::SetWrapMode( WrapMode mode )
{
m_wrap = mode;
}
WrapMode CBrushLinearGradient::GetWrapMode() const
{
return m_wrap;
}
CBrush* CBrushLinearGradient::Clone() const
{
return new CBrushLinearGradient( *this );
}
Status CBrushLinearGradient::SetInterpolationColors( const CColor *presetColors, const REAL *blendPositions, INT count )
{
m_subcolors.RemoveAll();
if( count > 0 && presetColors && blendPositions )
{
m_subcolors.SetCount( count );
for( int i = 0; i < count; i++ )
{
m_subcolors[i].color = presetColors[i];
m_subcolors[i].position = blendPositions[i];
}
}
return Ok;
}
Status CBrushLinearGradient::GetInterpolationColors( CColor *presetColors, REAL *blendPositions, INT count ) const
{
if( count > 0 && count <= (INT)m_subcolors.GetCount() && presetColors && blendPositions )
{
for( int i = 0; i < count; i++ )
{
presetColors[i] = m_subcolors[i].color;
blendPositions[i] = m_subcolors[i].position;
}
}
return Ok;
}
INT CBrushLinearGradient::GetInterpolationColorsCount() const
{
return (INT)m_subcolors.GetCount();
}
// additional methods
void CBrushLinearGradient::GetSubColor( int nIndex, CColor* pColor, float* pPosition ) const
{
*pColor = m_subcolors[nIndex].color;
*pPosition = m_subcolors[nIndex].position;
}
void CBrushLinearGradient::SetRelativeCoords( INT bRelative )
{
m_bRelativeCoords = bRelative;
}
INT CBrushLinearGradient::IsRelativeCoords() const
{
return m_bRelativeCoords;
}
INT CBrushLinearGradient::IsAngleScalable() const
{
return m_bAngleScalable;
}
INT CBrushLinearGradient::IsRectable() const
{
return m_bRectable;
}
float CBrushLinearGradient::GetAngle() const
{
return m_angle;
}
////////////////////////////////////////////////////////////////////////////////
CBrushTexture::CBrushTexture() : CBrush(BrushTypeTextureFill)
{
m_pImage = NULL;
m_bReleaseImage = FALSE;
m_bUsePattern = FALSE;
Alpha = 255;
}
CBrushTexture::CBrushTexture(const std::wstring& strName, WrapMode wrapMode) : CBrush(BrushTypeTextureFill), m_wrapMode(wrapMode)
{
m_pImage = new CImage(strName);
m_bReleaseImage = TRUE;
m_bUsePattern = FALSE;
Alpha = 255;
}
CBrushTexture::CBrushTexture(CImage *pImage, WrapMode wrapMode) : CBrush(BrushTypeTextureFill), m_wrapMode(wrapMode)
{
m_pImage = pImage;
m_bReleaseImage = FALSE;
m_bUsePattern = FALSE;
Alpha = 255;
}
CBrushTexture::~CBrushTexture()
{
if (m_bReleaseImage)
{
RELEASEOBJECT(m_pImage);
}
}
CBrush* CBrushTexture::Clone() const
{
CBrushTexture *pRet = new CBrushTexture(m_pImage, m_wrapMode);
if( pRet )
{
pRet->m_mtx = m_mtx;
pRet->m_bUsePattern = m_bUsePattern;
}
return pRet;
}
void CBrushTexture::TranslateTransform(double dX, double dY, MatrixOrder order)
{
m_mtx.Translate(dX, dY, order);
}
void CBrushTexture::ScaleTransform(double dX, double dY, MatrixOrder order)
{
m_mtx.Scale(dX, dY, order);
}
void CBrushTexture::RotateTransform(double angle, MatrixOrder order)
{
m_mtx.Rotate(angle, order);
}
void CBrushTexture::GetTransform(CMatrix* matrix) const
{
*matrix = m_mtx;
}
void CBrushTexture::SetTransform(const CMatrix* matrix)
{
m_mtx = *matrix;
}
void CBrushTexture::SetWrapMode(WrapMode wMode)
{
m_wrapMode = wMode;
}
WrapMode CBrushTexture::GetWrapMode() const
{
return(m_wrapMode);
}
void* CBrushTexture::PatternFinalize()
{
if (m_pImage->m_nStride < 0)
return m_pImage->m_pImgData - ((m_pImage->m_dwHeight - 1) * m_pImage->m_nStride);
return m_pImage->m_pImgData;
}
DWORD CBrushTexture::PatternGetWidth()
{
return m_pImage->m_dwWidth;
}
DWORD CBrushTexture::PatternGetHeight()
{
return m_pImage->m_dwHeight;
}
int CBrushTexture::PatternGetStride()
{
return m_pImage->m_nStride;
}
}
#ifndef _BUILD_BRUSH_H_
#define _BUILD_BRUSH_H_
#include "AggPlusEnums.h"
#include "Color.h"
#include "Matrix.h"
#include "Image.h"
#include "structures.h"
#include "../common/Array.h"
namespace Aggplus
{
class CBrush
{
friend class CGraphics;
protected:
CBrush(BrushType bType);
public:
virtual ~CBrush();
virtual CBrush* Clone() const = 0;
BrushType GetType() const;
public:
BrushType m_bType;
};
class CBrushSolid : public CBrush
{
public:
CBrushSolid(CColor dwColor);
virtual ~CBrushSolid();
virtual CBrush *Clone() const;
void GetColor(CColor* color) const;
void SetColor(const CColor &color);
protected:
CColor m_dwColor;
};
class CBrushHatch : public CBrush
{
public:
CBrushHatch();
virtual ~CBrushHatch();
virtual CBrush *Clone() const;
inline CDoubleRect& GetBounds() { return Bounds; }
public:
std::wstring m_name;
CColor m_dwColor1;
CColor m_dwColor2;
CDoubleRect Bounds;
};
class CBrushLinearGradient : public CBrush
{
friend class CGraphics;
public:
CBrushLinearGradient( const PointF& p1, const PointF& p2, const CColor& c1, const CColor& c2 );
CBrushLinearGradient( const Point& p1, const Point& p2, const CColor& c1, const CColor& c2 );
CBrushLinearGradient( const RectF& rect, const CColor& c1, const CColor& c2, float angle, INT isAngleScalable );
CBrushLinearGradient( const Rect& rect, const CColor& c1, const CColor& c2, float angle, INT isAngleScalable );
CBrushLinearGradient( const RectF& rect, const CColor& c1, const CColor& c2, Aggplus::LinearGradientMode mode );
CBrushLinearGradient( const Rect& rect, const CColor& c1, const CColor& c2, Aggplus::LinearGradientMode mode );
CBrushLinearGradient( const CBrushLinearGradient& out );
Status GetLinearColors( CColor* colors ) const;
Status GetRectangle( Rect *rect ) const;
Status GetRectangle( RectF *rect ) const;
Status GetTransform( CMatrix* matrix ) const;
Status MultiplyTransform( const CMatrix *matrix, MatrixOrder order = MatrixOrderPrepend);
Status ResetTransform();
Status RotateTransform( REAL angle, MatrixOrder order = MatrixOrderPrepend );
Status ScaleTransform( REAL sx, REAL sy, MatrixOrder order = MatrixOrderPrepend );
void SetWrapMode( WrapMode mode );
WrapMode GetWrapMode() const;
virtual CBrush *Clone() const;
Status SetInterpolationColors( const CColor *presetColors, const REAL *blendPositions, INT count );
Status GetInterpolationColors( CColor *presetColors, REAL *blendPositions, INT count ) const;
INT GetInterpolationColorsCount() const;
// additional methods
void GetSubColor( int nIndex, CColor* pColor, float* pPosition ) const;
void SetRelativeCoords( INT bRelative );
INT IsRelativeCoords() const;
INT IsAngleScalable() const;
INT IsRectable() const;
float GetAngle() const;
inline void SetBounds(const CDoubleRect& oRect) { Bounds = oRect; }
inline CDoubleRect& GetBounds() { return Bounds; }
protected:
CColor m_colors[2];
PointF m_points[2];
struct TSubColor
{
CColor color;
float position;
};
CArray<TSubColor> m_subcolors;
CMatrix m_matrix;
float m_angle; // угол поворота в градусах базовой линии p1 -> p2
CDoubleRect Bounds;
Aggplus::WrapMode m_wrap;
INT m_bAngleScalable; // масштабировать угол поворота относительно заданных точек b = arctan( width / height * tan(angle) );
INT m_bRectable; // в качестве направляющей используется диагональ прямоугольника
INT m_bRelativeCoords; // координаты точек считаются относительно рисуемого примитива
};
class CBrushTexture : public CBrush
{
friend class CGraphics;
protected:
CBrushTexture();
public:
CBrushTexture(const std::wstring& strName, WrapMode wrapMode = WrapModeTile);
CBrushTexture(CImage *pImage, WrapMode wrapMode = WrapModeTile);
virtual ~CBrushTexture();
virtual CBrush* Clone() const;
void TranslateTransform(double dX, double dY, MatrixOrder order = MatrixOrderPrepend);
void ScaleTransform(double dX, double dY, MatrixOrder order = MatrixOrderPrepend);
void RotateTransform(double angle, MatrixOrder order = MatrixOrderPrepend);
void GetTransform(CMatrix* matrix) const;
void SetTransform(const CMatrix* matrix);
void SetWrapMode(WrapMode wMode);
WrapMode GetWrapMode() const;
public:
void* PatternFinalize();
DWORD PatternGetWidth();
DWORD PatternGetHeight();
int PatternGetStride();
public:
CImage* m_pImage;
INT m_bReleaseImage;
WrapMode m_wrapMode;
CMatrix m_mtx;
INT m_bUsePattern;
CColor m_colors[2];
BYTE Alpha;
};
}
#endif // _BUILD_BRUSH_H_
\ No newline at end of file
// !!! :
// 1. MFC :
// CString str1("qwerty");
// CString str2;
// str2.Format(TEXT("str1 = %s"), str1);
// CStringT :
// CStringT str1("qwerty");
// CStringT str2;
// str2.Format(TEXT("str1 = %s"), (LPCTSTR)str1);
#ifndef __FILE__CSTRINGT__
#define __FILE__CSTRINGT__
#include <string>
namespace NSStrings
{
template <typename _T, typename _TCHAR>
class CStringT
{
protected:
_T m_str;
public:
CStringT() {}
CStringT(const CStringT& src) { m_str = src.m_str; }
CStringT(const char& ch) { _TCHAR c = (_TCHAR)ch; m_src = c; }
CStringT(const wchar_t& ch) { _TCHAR c = (_TCHAR)ch; m_src = c; }
// get data length
int GetLength() const {return m_str.length();}
// TRUE if zero length
BOOL IsEmpty() const {return m_str.empty();}
// clear contents to empty
void Empty() {m_str.erase();}
// return single character at zero-based index
_TCHAR GetAt(int nIndex) const {return m_str[nIndex];}
// return single character at zero-based index
_TCHAR operator[](int nIndex) const {return m_str[nIndex];}
// set a single character at zero-based index
void SetAt(int nIndex, _TCHAR ch) {m_str[nIndex] = ch;}
// return pointer to const string
operator _TCHAR*() const {return m_str.c_str();}
// ref-counted copy from another CStringT
const CStringT& operator=(const CStringT& stringSrc) { if (&stringSrc != this) {m_str = (_TCHAR*)stringSrc;} return *this;}
// set string content to single character
const CStringT& operator=(wchar_t ch) {_TCHAR c = (_TCHAR)ch; m_str = c; return *this;}
const CStringT& operator=(char ch) {_TCHAR c = (_TCHAR)ch; m_str = c; return *this;}
// concatenate from another CStringT
const CStringT& operator+=(const CStringT& string) {m_str += string.m_str; return *this;}
// concatenate a single character
const CStringT& operator+=(char ch) {m_str += (_TCHAR)ch; return *this;}
const CStringT& operator+=(wchar_t ch) {m_str += (_TCHAR)ch; return *this;}
friend CStringT operator+(const CStringT& string1, const CStringT& string2) {CStringT str(string1); return (str += string2);}
friend CStringT operator+(const CStringT& string, char ch) {CStringT str(string); return (str += ch);}
friend CStringT operator+(char ch, const CStringT& string) {CStringT str(ch); return (str += string);}
friend CStringT operator+(const CStringT& string, wchar_t ch) {CStringT str(string); return (str += ch);}
friend CStringT operator+(wchar_t ch, const CStringT& string) {CStringT str(ch); return (str += string);}
// string comparison
// straight character comparison
int Compare (LPCTSTR lpsz) const {return _tcscmp (this->operator LPCTSTR(), lpsz);}
// compare ignoring case
int CompareNoCase(LPCTSTR lpsz) const {return _tcsicmp (this->operator LPCTSTR(), lpsz);}
// NLS aware comparison, case sensitive
int Collate (LPCTSTR lpsz) const {return _tcscoll (this->operator LPCTSTR(), lpsz);}
// NLS aware comparison, case insensitive
int CollateNoCase(LPCTSTR lpsz) const {return _tcsicoll(this->operator LPCTSTR(), lpsz);}
// simple sub-string extraction
// return nCount characters starting at zero-based nFirst
CStringT Mid(int nFirst, int nCount) const { CStringT s; s.m_str = m_str.substr(); }
// return all characters starting at zero-based nFirst
CStringT Mid(int nFirst) const {return CStringKS(this->operator LPCTSTR()+max(0,nFirst));}
// return first nCount characters in string
CStringKS Left(int nCount) const {CStringKS str; for (int i=0; i<nCount; i++) str += GetAt(i); return str;}
// return nCount characters from end of string
CStringKS Right(int nCount) const {return Mid(GetLength()-max(0,nCount));}
// characters from beginning that are also in passed string
CStringKS SpanIncluding(LPCTSTR lpszCharSet) const {CStringKS str; for (int i=0; i<GetLength(); i++) if(_tcschr(lpszCharSet, GetAt(i)) != NULL) str += GetAt(i); else break; return str;}
// characters from beginning that are not also in passed string
CStringKS SpanExcluding(LPCTSTR lpszCharSet) const {CStringKS str; for (int i=0; i<GetLength(); i++) if(_tcschr(lpszCharSet, GetAt(i)) == NULL) str += GetAt(i); else break; return str;}
// upper/lower/reverse conversion
// NLS aware conversion to uppercase
void MakeUpper() {
//TCHAR *szStr = new TCHAR[1+GetLength()];
//_tcscpy(szStr, this->operator LPCTSTR());
::CharUpper((LPTSTR)this->operator LPCTSTR());//::CharUpper(szStr);
//m_str = szStr;
//delete szStr;
}
// NLS aware conversion to lowercase
void MakeLower() {
//TCHAR *szStr = new TCHAR[1+GetLength()];
//_tcscpy(szStr, this->operator LPCTSTR());
::CharLower((LPTSTR)this->operator LPCTSTR());//::CharLower(szStr);
//m_str = szStr;
//delete szStr;
}
// reverse string right-to-left
void MakeReverse() {
int len = GetLength();
for (int i=0; i<len/2; i++) {
TCHAR ch = GetAt(i);
SetAt(i, GetAt(len-i-1));
SetAt(len-i-1, ch);
}
}
// trimming whitespace (either side)
// remove whitespace starting from right edge
void TrimRight() {TrimRight(TEXT(' '));}
// remove whitespace starting from left side
void TrimLeft () {TrimLeft (TEXT(' '));}
// trimming anything (either side)
// remove continuous occurrences of chTarget starting from right
void TrimRight(TCHAR chTarget) {
for (int i=GetLength()-1; i>=0; i--) {
if (GetAt(i) != chTarget) {
operator =(Left(i+1));
break;
}
}
}
// remove continuous occcurrences of characters in passed string,
// starting from right
void TrimRight(LPCTSTR lpszTargets) {
int pos = -1;
CStringKS strTargets(lpszTargets);
for (int i=GetLength()-1; i>=0; i--) {
if (strTargets.Find(GetAt(i)) != -1) {
pos = i;
} else {
break;
}
}
if (pos >= 0) {
operator =(Left(pos));
}
}
// remove continuous occurrences of chTarget starting from left
void TrimLeft(TCHAR chTarget) {
for (int i=0; i<GetLength(); i++) {
if (GetAt(i) != chTarget) {
operator =(Mid(i));
break;
}
}
}
// remove continuous occcurrences of characters in
// passed string, starting from left
void TrimLeft(LPCTSTR lpszTargets) {
int pos = -1;
CStringKS strTargets(lpszTargets);
for (int i=0; i<GetLength(); i++) {
if (strTargets.Find(GetAt(i)) != -1) {
pos = i;
} else {
break;
}
}
if (pos >= 0) {
operator =(Mid(i));
}
}
// advanced manipulation
// replace occurrences of chOld with chNew
int Replace(TCHAR chOld, TCHAR chNew) {
int count = 0;
for (int i=0; i<GetLength(); i++) {
if (GetAt(i) == chOld) {
SetAt(i, chNew);
count++;
}
}
return count;
}
// replace occurrences of substring lpszOld with lpszNew;
// empty lpszNew removes instances of lpszOld
int Replace(LPCTSTR lpszOld, LPCTSTR lpszNew) {
int count = 0;
if (lpszOld) {
int pos = 0;
size_t len = _tcslen(lpszOld);
do {
pos = Find(lpszOld, pos);
if (pos == -1) break;
count++;
if (lpszNew) {
m_str.replace(pos, len, lpszNew);
} else {
m_str.erase(pos, len);
}
} while (true);
}
return count;
}
// remove occurrences of chRemove
int Remove(TCHAR chRemove) {
int count = 0;
int i=0;
while (i<GetLength()) {
if (GetAt(i) == chRemove) {
Delete(i);
count++;
} else {
i++;
}
}
return count;
}
// insert character at zero-based index; concatenates
// if index is past end of string
int Insert(int nIndex, TCHAR ch) {
m_str.insert(max(0, min(nIndex, GetLength())), 1, ch);
return GetLength();
}
// insert substring at zero-based index; concatenates
// if index is past end of string
int Insert(int nIndex, LPCTSTR pstr) {
if (pstr) {
m_str.insert(max(0, min(nIndex, GetLength())), pstr);
}
return GetLength();
}
// delete nCount characters starting at zero-based index
int Delete(int nIndex, int nCount = 1) {
const int iRes = GetLength();
if (nCount > 0) {
nIndex = max(0, nIndex);
nCount = min(nCount, GetLength()-nIndex);
m_str.erase(nIndex, nCount);
}
return iRes;
}
// searching
// find character starting at left, -1 if not found
int Find(TCHAR ch) const {return m_str.find(ch);}
// find character starting at right
int ReverseFind(TCHAR ch) const {return m_str.rfind(ch);}
// find character starting at zero-based index and going right
int Find(TCHAR ch, int nStart) const {return m_str.find(ch, nStart);}
// find first instance of any character in passed string
int FindOneOf(LPCTSTR lpszCharSet) const {return m_str.find_first_of(lpszCharSet);}
// find first instance of substring
int Find(LPCTSTR lpszSub) const {return m_str.find(lpszSub);}
// find first instance of substring starting at zero-based index
int Find(LPCTSTR lpszSub, int nStart) const {return m_str.find(lpszSub, nStart);}
// simple formatting
// printf-like formatting using passed string
void Format(LPCTSTR lpszFormat, ...) {
va_list arglist;
va_start(arglist, lpszFormat);
FormatV(lpszFormat, arglist);
va_end(arglist);
}
// printf-like formatting using referenced string resource
void Format(UINT nFormatID, ...) {
va_list arglist;
va_start(arglist, nFormatID);
CStringKS strLoad;
BOOL bRes = strLoad.LoadString(nFormatID);
if (bRes) {
FormatV(strLoad, arglist);
} else {
Empty();
}
va_end(arglist);
}
// printf-like formatting using variable arguments parameter
void FormatV(LPCTSTR lpszFormat, va_list argList) {
size_t sizeBuff = 512;
TCHAR *szFormat = NULL;
int write = -1;
do {
szFormat = new TCHAR[sizeBuff*=2];
write = _vsntprintf(szFormat, sizeBuff-1, lpszFormat, argList);
if (write >= 0) {
m_str = szFormat;
}
delete [] szFormat;
} while (write < 0);
}
// formatting for localization (uses FormatMessage API)
// format using FormatMessage API on passed string
void FormatMessage(LPCTSTR lpszFormat, ...) {
va_list argList;
va_start(argList, lpszFormat);
LPTSTR lpszTemp;
if ((::FormatMessage(FORMAT_MESSAGE_FROM_STRING|FORMAT_MESSAGE_ALLOCATE_BUFFER,lpszFormat, 0, 0, (LPTSTR)&lpszTemp, 0, &argList) == 0) &&
(lpszTemp == NULL))
{
*this = lpszTemp;
LocalFree(lpszTemp);
}
va_end(argList);
}
// format using FormatMessage API on referenced string resource
void FormatMessage(UINT nFormatID, ...) {
CStringKS strFormat;
if (strFormat.LoadString(nFormatID)) {
va_list argList;
va_start(argList, nFormatID);
LPTSTR lpszTemp;
if ((::FormatMessage(FORMAT_MESSAGE_FROM_STRING|FORMAT_MESSAGE_ALLOCATE_BUFFER, strFormat, 0, 0, (LPTSTR)&lpszTemp, 0, &argList) == 0) &&
(lpszTemp == NULL))
{
*this = lpszTemp;
LocalFree(lpszTemp);
}
va_end(argList);
}
}
// input and output
//friend CArchive& operator<<(CArchive& ar, const CStringKS& string);
//friend CArchive& operator>>(CArchive& ar, CStringKS& string);
// load from string resource
BOOL LoadString(UINT nID) {
size_t sizeBuff = 512;
bool bRepeat;
int iRes = 0;
TCHAR *szFormat = NULL;
do {
szFormat = new TCHAR[sizeBuff*=2];
iRes = ::LoadString(::GetModuleHandle(NULL), nID, szFormat, sizeBuff);
bRepeat = (iRes+1 >= sizeBuff);
if (!bRepeat)
m_str = szFormat;
delete [] szFormat;
} while (bRepeat);
return (iRes > 0);
}
#ifndef _UNICODE
// ANSI <-> OEM support (convert string in place)
// convert string from ANSI to OEM in-place
void AnsiToOem() {::CharToOem((LPCTSTR)this->operator LPCTSTR(), (LPSTR) this->operator LPCTSTR());}
// convert string from OEM to ANSI in-place
void OemToAnsi() {::OemToChar((LPCSTR) this->operator LPCTSTR(), (LPTSTR)this->operator LPCTSTR());}
#endif
#ifndef _AFX_NO_BSTR_SUPPORT
// OLE BSTR support (use for OLE automation)
// return a BSTR initialized with this CStringKS's data
BSTR AllocSysString() const {USES_CONVERSION; return SysAllocString(T2COLE(m_str.c_str()));}
// reallocates the passed BSTR, copies content of this CStringKS to it
BSTR SetSysString(BSTR* pbstr) const {BSTR szRes = AllocSysString(); if (pbstr) {::SysFreeString(*pbstr); *pbstr=szRes;} return szRes;}
#endif
// Access to string implementation buffer as "C" character array
// get pointer to modifiable buffer at least as long as nMinBufLength
LPTSTR GetBuffer(int nMinBufLength) {
if (GetLength() < nMinBufLength) {
m_str.resize(nMinBufLength);
}
return (LPTSTR)this->operator LPCTSTR();
}
// release buffer, setting length to nNewLength (or to first nul if -1)
void ReleaseBuffer(int nNewLength = -1) {
if (nNewLength != -1) {
nNewLength = max(0, nNewLength);
m_str.resize(nNewLength);
}
FreeExtra();
}
// get pointer to modifiable buffer exactly as long as nNewLength
LPTSTR GetBufferSetLength(int nNewLength) { return GetBuffer(nNewLength);}
// release memory allocated to but unused by string
void FreeExtra() {
int pos = Find(TEXT('\0'));
if (pos != -1) {
m_str.resize(pos);
}
}
};
class CStringA
{
};
class CStringKS {
private:
#ifdef UNICODE
typedef std::wstring tstring;
#else
typedef std:: string tstring;
#endif // UNICODE
tstring m_str;
public:
// Constructors
// constructs empty CStringKS
CStringKS() {}
// copy constructor
CStringKS(const CStringKS& stringSrc) : m_str((LPCTSTR)stringSrc) {}
// from a single character
CStringKS(TCHAR ch, int nRepeat = 1) : m_str(tstring(nRepeat, ch)) {}
// from an ANSI string (converts to TCHAR)
CStringKS(LPCSTR lpsz) {if (lpsz!=NULL) {USES_CONVERSION; m_str = A2CT(lpsz);}}
// from a UNICODE string (converts to TCHAR)
CStringKS(LPCWSTR lpsz) {if (lpsz!=NULL) {USES_CONVERSION; m_str = W2CT(lpsz);}}
// subset of characters from an ANSI string (converts to TCHAR)
CStringKS(LPCSTR lpch, int nLength) : m_str((LPCTSTR)(CStringKS(lpch).Left(nLength))) {}
// subset of characters from a UNICODE string (converts to TCHAR)
CStringKS(LPCWSTR lpch, int nLength) : m_str((LPCTSTR)(CStringKS(lpch).Left(nLength))) {}
// from unsigned characters
CStringKS(const unsigned char* psz) {this->operator=(psz);}
// Attributes & Operations
// get data length
int GetLength() const {return m_str.length();}
// TRUE if zero length
BOOL IsEmpty() const {return m_str.empty();}
// clear contents to empty
void Empty() {m_str.erase();}
// return single character at zero-based index
TCHAR GetAt(int nIndex) const {return m_str[nIndex];}
// return single character at zero-based index
TCHAR operator[](int nIndex) const {return m_str[nIndex];}
// set a single character at zero-based index
void SetAt(int nIndex, TCHAR ch) {m_str[nIndex] = ch;}
// return pointer to const string
operator LPCTSTR() const {return m_str.c_str();}
// overloaded assignment
// ref-counted copy from another CStringKS
const CStringKS& operator=(const CStringKS& stringSrc) { if (&stringSrc != this) {m_str = (LPCTSTR)stringSrc;} return *this;}
// set string content to single character
const CStringKS& operator=(TCHAR ch) {m_str = ch; return *this;}
#ifdef _UNICODE
const CStringKS& operator=(char ch) {TCHAR tCh = ch; m_str = tCh; return *this;}
#endif
// copy string content from ANSI string (converts to TCHAR)
const CStringKS& operator=(LPCSTR lpsz) {m_str = (LPCTSTR)CStringKS(lpsz); return *this;}
// copy string content from UNICODE string (converts to TCHAR)
const CStringKS& operator=(LPCWSTR lpsz) {m_str = (LPCTSTR)CStringKS(lpsz); return *this;}
// copy string content from unsigned chars
const CStringKS& operator=(const unsigned char* psz) {USES_CONVERSION; m_str = A2CT((const char*)psz); return *this;}
// string concatenation
// concatenate from another CStringKS
const CStringKS& operator+=(const CStringKS& string) {m_str += (LPCTSTR)string; return *this;}
// concatenate a single character
const CStringKS& operator+=(TCHAR ch) {m_str += ch; return *this;}
#ifdef _UNICODE
// concatenate an ANSI character after converting it to TCHAR
const CStringKS& operator+=(char ch) {TCHAR tCh = ch; m_str += tCh; return *this;}
#endif
// concatenate a UNICODE character after converting it to TCHAR
const CStringKS& operator+=(LPCTSTR lpsz) {m_str += lpsz; return *this;}
friend CStringKS operator+(const CStringKS& string1, const CStringKS& string2) {CStringKS str(string1); return (str += string2);}
friend CStringKS operator+(const CStringKS& string, TCHAR ch) {CStringKS str(string); return (str += ch );}
friend CStringKS operator+(TCHAR ch, const CStringKS& string) {CStringKS str(ch ); return (str += string);}
#ifdef _UNICODE
friend CStringKS operator+(const CStringKS& string, char ch) {CStringKS str(string); TCHAR tCh = ch; return (str += tCh);}
friend CStringKS operator+(char ch, const CStringKS& string) {TCHAR tCh = ch; CStringKS str(tCh); return (str += string);}
#endif
friend CStringKS operator+(const CStringKS& string, LPCTSTR lpsz) {CStringKS str(string); return (str += lpsz );}
friend CStringKS operator+(LPCTSTR lpsz, const CStringKS& string) {CStringKS str(lpsz ); return (str += string);}
// string comparison
// straight character comparison
int Compare (LPCTSTR lpsz) const {return _tcscmp (this->operator LPCTSTR(), lpsz);}
// compare ignoring case
int CompareNoCase(LPCTSTR lpsz) const {return _tcsicmp (this->operator LPCTSTR(), lpsz);}
// NLS aware comparison, case sensitive
int Collate (LPCTSTR lpsz) const {return _tcscoll (this->operator LPCTSTR(), lpsz);}
// NLS aware comparison, case insensitive
int CollateNoCase(LPCTSTR lpsz) const {return _tcsicoll(this->operator LPCTSTR(), lpsz);}
// simple sub-string extraction
// return nCount characters starting at zero-based nFirst
CStringKS Mid(int nFirst, int nCount) const {return Mid(nFirst).Left(nCount);}
// return all characters starting at zero-based nFirst
CStringKS Mid(int nFirst) const {return CStringKS(this->operator LPCTSTR()+max(0,nFirst));}
// return first nCount characters in string
CStringKS Left(int nCount) const {CStringKS str; for (int i=0; i<nCount; i++) str += GetAt(i); return str;}
// return nCount characters from end of string
CStringKS Right(int nCount) const {return Mid(GetLength()-max(0,nCount));}
// characters from beginning that are also in passed string
CStringKS SpanIncluding(LPCTSTR lpszCharSet) const {CStringKS str; for (int i=0; i<GetLength(); i++) if(_tcschr(lpszCharSet, GetAt(i)) != NULL) str += GetAt(i); else break; return str;}
// characters from beginning that are not also in passed string
CStringKS SpanExcluding(LPCTSTR lpszCharSet) const {CStringKS str; for (int i=0; i<GetLength(); i++) if(_tcschr(lpszCharSet, GetAt(i)) == NULL) str += GetAt(i); else break; return str;}
// upper/lower/reverse conversion
// NLS aware conversion to uppercase
void MakeUpper() {
//TCHAR *szStr = new TCHAR[1+GetLength()];
//_tcscpy(szStr, this->operator LPCTSTR());
::CharUpper((LPTSTR)this->operator LPCTSTR());//::CharUpper(szStr);
//m_str = szStr;
//delete szStr;
}
// NLS aware conversion to lowercase
void MakeLower() {
//TCHAR *szStr = new TCHAR[1+GetLength()];
//_tcscpy(szStr, this->operator LPCTSTR());
::CharLower((LPTSTR)this->operator LPCTSTR());//::CharLower(szStr);
//m_str = szStr;
//delete szStr;
}
// reverse string right-to-left
void MakeReverse() {
int len = GetLength();
for (int i=0; i<len/2; i++) {
TCHAR ch = GetAt(i);
SetAt(i, GetAt(len-i-1));
SetAt(len-i-1, ch);
}
}
// trimming whitespace (either side)
// remove whitespace starting from right edge
void TrimRight() {TrimRight(TEXT(' '));}
// remove whitespace starting from left side
void TrimLeft () {TrimLeft (TEXT(' '));}
// trimming anything (either side)
// remove continuous occurrences of chTarget starting from right
void TrimRight(TCHAR chTarget) {
for (int i=GetLength()-1; i>=0; i--) {
if (GetAt(i) != chTarget) {
operator =(Left(i+1));
break;
}
}
}
// remove continuous occcurrences of characters in passed string,
// starting from right
void TrimRight(LPCTSTR lpszTargets) {
int pos = -1;
CStringKS strTargets(lpszTargets);
for (int i=GetLength()-1; i>=0; i--) {
if (strTargets.Find(GetAt(i)) != -1) {
pos = i;
} else {
break;
}
}
if (pos >= 0) {
operator =(Left(pos));
}
}
// remove continuous occurrences of chTarget starting from left
void TrimLeft(TCHAR chTarget) {
for (int i=0; i<GetLength(); i++) {
if (GetAt(i) != chTarget) {
operator =(Mid(i));
break;
}
}
}
// remove continuous occcurrences of characters in
// passed string, starting from left
void TrimLeft(LPCTSTR lpszTargets) {
int pos = -1;
CStringKS strTargets(lpszTargets);
for (int i=0; i<GetLength(); i++) {
if (strTargets.Find(GetAt(i)) != -1) {
pos = i;
} else {
break;
}
}
if (pos >= 0) {
operator =(Mid(i));
}
}
// advanced manipulation
// replace occurrences of chOld with chNew
int Replace(TCHAR chOld, TCHAR chNew) {
int count = 0;
for (int i=0; i<GetLength(); i++) {
if (GetAt(i) == chOld) {
SetAt(i, chNew);
count++;
}
}
return count;
}
// replace occurrences of substring lpszOld with lpszNew;
// empty lpszNew removes instances of lpszOld
int Replace(LPCTSTR lpszOld, LPCTSTR lpszNew) {
int count = 0;
if (lpszOld) {
int pos = 0;
size_t len = _tcslen(lpszOld);
do {
pos = Find(lpszOld, pos);
if (pos == -1) break;
count++;
if (lpszNew) {
m_str.replace(pos, len, lpszNew);
} else {
m_str.erase(pos, len);
}
} while (true);
}
return count;
}
// remove occurrences of chRemove
int Remove(TCHAR chRemove) {
int count = 0;
int i=0;
while (i<GetLength()) {
if (GetAt(i) == chRemove) {
Delete(i);
count++;
} else {
i++;
}
}
return count;
}
// insert character at zero-based index; concatenates
// if index is past end of string
int Insert(int nIndex, TCHAR ch) {
m_str.insert(max(0, min(nIndex, GetLength())), 1, ch);
return GetLength();
}
// insert substring at zero-based index; concatenates
// if index is past end of string
int Insert(int nIndex, LPCTSTR pstr) {
if (pstr) {
m_str.insert(max(0, min(nIndex, GetLength())), pstr);
}
return GetLength();
}
// delete nCount characters starting at zero-based index
int Delete(int nIndex, int nCount = 1) {
const int iRes = GetLength();
if (nCount > 0) {
nIndex = max(0, nIndex);
nCount = min(nCount, GetLength()-nIndex);
m_str.erase(nIndex, nCount);
}
return iRes;
}
// searching
// find character starting at left, -1 if not found
int Find(TCHAR ch) const {return m_str.find(ch);}
// find character starting at right
int ReverseFind(TCHAR ch) const {return m_str.rfind(ch);}
// find character starting at zero-based index and going right
int Find(TCHAR ch, int nStart) const {return m_str.find(ch, nStart);}
// find first instance of any character in passed string
int FindOneOf(LPCTSTR lpszCharSet) const {return m_str.find_first_of(lpszCharSet);}
// find first instance of substring
int Find(LPCTSTR lpszSub) const {return m_str.find(lpszSub);}
// find first instance of substring starting at zero-based index
int Find(LPCTSTR lpszSub, int nStart) const {return m_str.find(lpszSub, nStart);}
// simple formatting
// printf-like formatting using passed string
void Format(LPCTSTR lpszFormat, ...) {
va_list arglist;
va_start(arglist, lpszFormat);
FormatV(lpszFormat, arglist);
va_end(arglist);
}
// printf-like formatting using referenced string resource
void Format(UINT nFormatID, ...) {
va_list arglist;
va_start(arglist, nFormatID);
CStringKS strLoad;
BOOL bRes = strLoad.LoadString(nFormatID);
if (bRes) {
FormatV(strLoad, arglist);
} else {
Empty();
}
va_end(arglist);
}
// printf-like formatting using variable arguments parameter
void FormatV(LPCTSTR lpszFormat, va_list argList) {
size_t sizeBuff = 512;
TCHAR *szFormat = NULL;
int write = -1;
do {
szFormat = new TCHAR[sizeBuff*=2];
write = _vsntprintf(szFormat, sizeBuff-1, lpszFormat, argList);
if (write >= 0) {
m_str = szFormat;
}
delete [] szFormat;
} while (write < 0);
}
// formatting for localization (uses FormatMessage API)
// format using FormatMessage API on passed string
void FormatMessage(LPCTSTR lpszFormat, ...) {
va_list argList;
va_start(argList, lpszFormat);
LPTSTR lpszTemp;
if ((::FormatMessage(FORMAT_MESSAGE_FROM_STRING|FORMAT_MESSAGE_ALLOCATE_BUFFER,lpszFormat, 0, 0, (LPTSTR)&lpszTemp, 0, &argList) == 0) &&
(lpszTemp == NULL))
{
*this = lpszTemp;
LocalFree(lpszTemp);
}
va_end(argList);
}
// format using FormatMessage API on referenced string resource
void FormatMessage(UINT nFormatID, ...) {
CStringKS strFormat;
if (strFormat.LoadString(nFormatID)) {
va_list argList;
va_start(argList, nFormatID);
LPTSTR lpszTemp;
if ((::FormatMessage(FORMAT_MESSAGE_FROM_STRING|FORMAT_MESSAGE_ALLOCATE_BUFFER, strFormat, 0, 0, (LPTSTR)&lpszTemp, 0, &argList) == 0) &&
(lpszTemp == NULL))
{
*this = lpszTemp;
LocalFree(lpszTemp);
}
va_end(argList);
}
}
// input and output
//friend CArchive& operator<<(CArchive& ar, const CStringKS& string);
//friend CArchive& operator>>(CArchive& ar, CStringKS& string);
// load from string resource
BOOL LoadString(UINT nID) {
size_t sizeBuff = 512;
bool bRepeat;
int iRes = 0;
TCHAR *szFormat = NULL;
do {
szFormat = new TCHAR[sizeBuff*=2];
iRes = ::LoadString(::GetModuleHandle(NULL), nID, szFormat, sizeBuff);
bRepeat = (iRes+1 >= sizeBuff);
if (!bRepeat)
m_str = szFormat;
delete [] szFormat;
} while (bRepeat);
return (iRes > 0);
}
#ifndef _UNICODE
// ANSI <-> OEM support (convert string in place)
// convert string from ANSI to OEM in-place
void AnsiToOem() {::CharToOem((LPCTSTR)this->operator LPCTSTR(), (LPSTR) this->operator LPCTSTR());}
// convert string from OEM to ANSI in-place
void OemToAnsi() {::OemToChar((LPCSTR) this->operator LPCTSTR(), (LPTSTR)this->operator LPCTSTR());}
#endif
#ifndef _AFX_NO_BSTR_SUPPORT
// OLE BSTR support (use for OLE automation)
// return a BSTR initialized with this CStringKS's data
BSTR AllocSysString() const {USES_CONVERSION; return SysAllocString(T2COLE(m_str.c_str()));}
// reallocates the passed BSTR, copies content of this CStringKS to it
BSTR SetSysString(BSTR* pbstr) const {BSTR szRes = AllocSysString(); if (pbstr) {::SysFreeString(*pbstr); *pbstr=szRes;} return szRes;}
#endif
// Access to string implementation buffer as "C" character array
// get pointer to modifiable buffer at least as long as nMinBufLength
LPTSTR GetBuffer(int nMinBufLength) {
if (GetLength() < nMinBufLength) {
m_str.resize(nMinBufLength);
}
return (LPTSTR)this->operator LPCTSTR();
}
// release buffer, setting length to nNewLength (or to first nul if -1)
void ReleaseBuffer(int nNewLength = -1) {
if (nNewLength != -1) {
nNewLength = max(0, nNewLength);
m_str.resize(nNewLength);
}
FreeExtra();
}
// get pointer to modifiable buffer exactly as long as nNewLength
LPTSTR GetBufferSetLength(int nNewLength) { return GetBuffer(nNewLength);}
// release memory allocated to but unused by string
void FreeExtra() {
int pos = Find(TEXT('\0'));
if (pos != -1) {
m_str.resize(pos);
}
}
// Use LockBuffer/UnlockBuffer to turn refcounting off
// turn refcounting back on
LPTSTR LockBuffer();
// turn refcounting off
void UnlockBuffer();
// Implementation
public:
~CStringKS() {}
int GetAllocLength() const {return GetLength();};
};
} // NSStrings
#endif // __FILE__CSTRINGKS__
\ No newline at end of file
#include "Clip.h"
namespace Aggplus
{
/////////////////////////////////////////////////////////////////////////////////////
CClipMask::CClipMask() : m_pixf(m_alpha_rbuf)
{
m_pMask = NULL;
m_bIsClip = false;
m_lWidth = 0;
m_lHeight = 0;
}
CClipMask::~CClipMask()
{
Destroy();
}
void CClipMask::Destroy()
{
if (NULL != m_pMask)
delete [] m_pMask;
}
void CClipMask::Reset()
{
m_bIsClip = false;
}
void CClipMask::Create(LONG width, LONG height)
{
Destroy();
m_pMask = new BYTE[width * height];
m_alpha_rbuf.attach(m_pMask, width, height, width);
m_lWidth = width;
m_lHeight = height;
m_pixf.attach(m_alpha_rbuf);
m_base_renderer.attach(m_pixf);
m_renderer.attach(m_base_renderer);
m_renderer.color(agg::gray8(0xFF, 0xFF));
}
void CClipMask::ResetClip()
{
}
void CClipMask::GenerateClip(CGraphicsPath* pPath, CMatrix* pMatrix)
{
if (NULL == pPath)
return;
memset(m_pMask, 0, m_lWidth * m_lHeight);
m_rasterizer.reset();
typedef agg::conv_transform<agg::path_storage> trans_type;
trans_type trans(pPath->m_agg_ps, pMatrix->m_agg_mtx);
typedef agg::conv_curve<trans_type> conv_crv_type;
conv_crv_type c_c_path(trans);
m_rasterizer.add_path(c_c_path);
agg::render_scanlines(m_rasterizer, m_sl, m_renderer);
m_bIsClip = true;
}
agg::rendering_buffer CClipMask::GetRenderingBuffer()
{
return m_alpha_rbuf;
}
BYTE* CClipMask::GetMask()
{
return m_pMask;
}
bool CClipMask::IsClip()
{
return m_bIsClip;
}
/////////////////////////////////////////////////////////////////////////////////////
CClip::CClip() : m_pixf(m_alpha_rbuf)
{
m_pMask = NULL;
m_bIsClip = false;
m_lWidth = 0;
m_lHeight = 0;
}
CClip::~CClip()
{
Destroy();
}
void CClip::Destroy()
{
if (NULL != m_pMask)
delete [] m_pMask;
}
void CClip::Reset()
{
m_bIsClip = false;
}
void CClip::Create(LONG width, LONG height)
{
}
void CClip::ResetClip()
{
}
void CClip::GenerateClip(CGraphicsPath* pPath, CMatrix* pMatrix)
{
if (NULL == pPath)
return;
m_rasterizer.reset();
typedef agg::conv_transform<agg::path_storage> trans_type;
trans_type trans(pPath->m_agg_ps, pMatrix->m_agg_mtx);
typedef agg::conv_curve<trans_type> conv_crv_type;
conv_crv_type c_c_path(trans);
m_rasterizer.add_path(c_c_path);
m_bIsClip = true;
}
agg::rendering_buffer CClip::GetRenderingBuffer()
{
return m_alpha_rbuf;
}
BYTE* CClip::GetMask()
{
return m_pMask;
}
bool CClip::IsClip()
{
return m_bIsClip;
}
/////////////////////////////////////////////////////////////////////////////////////
CClipMulti::CClipMulti()
{
m_bIsClip = false;
m_bIsClip2 = false;
}
CClipMulti::~CClipMulti()
{
}
void CClipMulti::Create(LONG width, LONG height)
{
m_rasterizer.clip_box(0, 0, width, height);
m_bIsClip = false;
m_bIsClip2 = false;
}
void CClipMulti::GenerateClip(CGraphicsPath* pPath, CMatrix* pMatrix)
{
if (NULL == pPath)
return;
m_rasterizer.reset();
typedef agg::conv_transform<agg::path_storage> trans_type;
trans_type trans(pPath->m_agg_ps, pMatrix->m_agg_mtx);
typedef agg::conv_curve<trans_type> conv_crv_type;
conv_crv_type c_c_path(trans);
m_rasterizer.add_path(c_c_path);
m_bIsClip = true;
m_bIsClip2 = false;
}
void CClipMulti::Combine(CGraphicsPath* pPath, CMatrix* pMatrix, agg::sbool_op_e op)
{
if (!m_bIsClip)
return GenerateClip(pPath, pMatrix);
if (!m_bIsClip2)
{
// смешивать надо с растерайзером
agg::rasterizer_scanline_aa<> rasterizer;
typedef agg::conv_transform<agg::path_storage> trans_type;
trans_type trans(pPath->m_agg_ps, pMatrix->m_agg_mtx);
typedef agg::conv_curve<trans_type> conv_crv_type;
conv_crv_type c_c_path(trans);
rasterizer.add_path(c_c_path);
rasterizer.filling_rule(pPath->m_bEvenOdd ? agg::fill_even_odd : agg::fill_non_zero);
scanline_type sl1;
scanline_type sl2;
scanline_type sl;
agg::sbool_combine_shapes_aa(op, m_rasterizer, rasterizer, sl1, sl2, sl, m_storage1);
m_lCurStorage = 1;
}
else
{
// надо смешивать со стораджем
agg::rasterizer_scanline_aa<> rasterizer;
typedef agg::conv_transform<agg::path_storage> trans_type;
trans_type trans(pPath->m_agg_ps, pMatrix->m_agg_mtx);
typedef agg::conv_curve<trans_type> conv_crv_type;
conv_crv_type c_c_path(trans);
rasterizer.add_path(c_c_path);
rasterizer.filling_rule(pPath->m_bEvenOdd ? agg::fill_even_odd : agg::fill_non_zero);
scanline_type sl1;
scanline_type sl2;
scanline_type sl;
agg::sbool_combine_shapes_aa(op, rasterizer, (m_lCurStorage == 1) ? m_storage1 : m_storage2, sl1, sl2, sl,
(m_lCurStorage == 1) ? m_storage2 : m_storage1);
if (1 == m_lCurStorage)
{
//m_storage1.prepare();
m_lCurStorage = 2;
}
else
{
//m_storage2.prepare();
m_lCurStorage = 1;
}
}
m_bIsClip2 = true;
}
bool CClipMulti::IsClip()
{
return m_bIsClip;
}
bool CClipMulti::IsClip2()
{
return m_bIsClip2;
}
void CClipMulti::Reset()
{
m_rasterizer.reset();
//m_storage1.prepare();
//m_storage2.prepare();
m_bIsClip = false;
m_bIsClip2 = false;
}
}
\ No newline at end of file
#ifndef _BUILD_CLIP_H_
#define _BUILD_CLIP_H_
#include "GraphicsPath.h"
#include "../agg-2.4/include/agg_basics.h"
#include "../agg-2.4/include/agg_rendering_buffer.h"
#include "../agg-2.4/include/agg_rasterizer_scanline_aa.h"
#include "../agg-2.4/include/agg_scanline_storage_aa.h"
#include "../agg-2.4/include/agg_scanline_storage_bin.h"
#include "../agg-2.4/include/agg_pixfmt_rgb.h"
#include "../agg-2.4/include/agg_pixfmt_gray.h"
#include "../agg-2.4/include/agg_alpha_mask_u8.h"
#include "../agg-2.4/include/agg_scanline_u.h"
#include "../agg-2.4/include/agg_scanline_p.h"
#include "../agg-2.4/include/agg_scanline_bin.h"
#include "../agg-2.4/include/agg_scanline_boolean_algebra.h"
#include <string>
namespace Aggplus
{
class CClipMask
{
typedef agg::renderer_base<agg::pixfmt_gray8> ren_base;
typedef agg::renderer_scanline_aa_solid<ren_base> renderer;
friend class CGraphicsPath;
public:
BYTE* m_pMask;
LONG m_lWidth;
LONG m_lHeight;
agg::rendering_buffer m_alpha_rbuf;
agg::rasterizer_scanline_aa<> m_rasterizer;
agg::pixfmt_gray8 m_pixf;
ren_base m_base_renderer;
renderer m_renderer;
agg::scanline_p8 m_sl;
bool m_bIsClip;
public:
CClipMask();
~CClipMask();
void Destroy();
void Reset();
public:
void Create(LONG width, LONG height);
void ResetClip();
void GenerateClip(CGraphicsPath* pPath, CMatrix* pMatrix);
agg::rendering_buffer GetRenderingBuffer();
BYTE* GetMask();
bool IsClip();
};
class CClip
{
typedef agg::renderer_base<agg::pixfmt_gray8> ren_base;
typedef agg::renderer_scanline_aa_solid<ren_base> renderer;
friend class CGraphicsPath;
public:
BYTE* m_pMask;
LONG m_lWidth;
LONG m_lHeight;
agg::rendering_buffer m_alpha_rbuf;
agg::rasterizer_scanline_aa<> m_rasterizer;
agg::pixfmt_gray8 m_pixf;
ren_base m_base_renderer;
renderer m_renderer;
agg::scanline_p8 m_sl;
bool m_bIsClip;
public:
CClip();
~CClip();
void Destroy();
void Reset();
public:
void Create(LONG width, LONG height);
void ResetClip();
void GenerateClip(CGraphicsPath* pPath, CMatrix* pMatrix);
agg::rendering_buffer GetRenderingBuffer();
BYTE* GetMask();
bool IsClip();
};
class CClipMulti
{
typedef agg::scanline_p8 scanline_type;
public:
agg::rasterizer_scanline_aa<> m_rasterizer;
agg::scanline_storage_aa8 m_storage1;
agg::scanline_storage_aa8 m_storage2;
long m_lCurStorage;
bool m_bIsClip;
bool m_bIsClip2;
public:
CClipMulti();
~CClipMulti();
void Create(LONG width, LONG height);
void GenerateClip(CGraphicsPath* pPath, CMatrix* pMatrix);
void Combine(CGraphicsPath* pPath, CMatrix* pMatrix, agg::sbool_op_e op);
bool IsClip();
bool IsClip2();
void Reset();
};
}
#endif // _BUILD_CLIP_H_
\ No newline at end of file
#ifndef _BUILD_COLOR_H_
#define _BUILD_COLOR_H_
#include "AggPlusEnums.h"
#include "../agg-2.4/include/agg_color_rgba.h"
/*
#define GetRValue(rgb) (unsigned char(rgb))
#define GetGValue(rgb) (unsigned char(rgb) >> 8))
#define GetBValue(rgb) (unsigned char(rgb) >> 16))
*/
namespace Aggplus
{
class CColor
{
public:
CColor() { Argb = 0xFF000000; } //Black;
//Color values are not premultiplied.
CColor(BYTE r, BYTE g, BYTE b) { Argb = MakeARGB(255, r, g, b); }
CColor(BYTE a, LONG lColor, bool bSwapRGB = false)
{
if (!bSwapRGB)
Argb = ((a << AlphaShift) | lColor);
else
{
Argb = MakeARGB(a, (BYTE)(lColor >> BlueShift), (BYTE)(lColor >> GreenShift), (BYTE)(lColor >> RedShift));
}
}
CColor(BYTE a, BYTE r, BYTE g, BYTE b) { Argb = MakeARGB(a, r, g, b); }
CColor(ARGB argb) { Argb = argb; }
BYTE GetAlpha() const { return (BYTE) (Argb >> AlphaShift); }
BYTE GetA() const { return GetAlpha(); }
BYTE GetRed() const { return (BYTE) (Argb >> RedShift); }
BYTE GetR() const { return GetRed(); }
BYTE GetGreen() const { return (BYTE) (Argb >> GreenShift); }
BYTE GetG() const { return GetGreen(); }
BYTE GetBlue() const { return (BYTE) (Argb >> BlueShift); }
BYTE GetB() const { return GetBlue(); }
ARGB GetValue() const { return Argb; }
void SetValue(ARGB argb) { Argb = argb; }
public:
// Shift count and bit mask for A, R, G, B components
enum
{
AlphaShift = 24,
RedShift = 16,
GreenShift = 8,
BlueShift = 0
};
enum
{
AlphaMask = 0xff000000,
RedMask = 0x00ff0000,
GreenMask = 0x0000ff00,
BlueMask = 0x000000ff
};
// Assemble A, R, G, B values into a 32-bit integer
static ARGB MakeARGB(BYTE a, BYTE r, BYTE g, BYTE b)
{
return (((ARGB) (b) << BlueShift) |
((ARGB) (g) << GreenShift) |
((ARGB) (r) << RedShift) |
((ARGB) (a) << AlphaShift));
}
//AGG converter
inline agg::rgba8 GetAggColor() const { return(agg::rgba8(GetBlue(), GetGreen(), GetRed(), GetAlpha())); }
protected:
ARGB Argb;
};
}
#endif // _BUILD_COLOR_H_
#pragma once
typedef float REAL;
typedef int INT;
typedef unsigned int UINT, *PUINT;
typedef unsigned long ARGB;
typedef unsigned char BYTE;
typedef int INT;
typedef unsigned long DWORD;
typedef long LONG;
#define ADDREFINTERFACE(pinterface)\
{\
if (pinterface!=NULL)\
{\
pinterface->AddRef();\
}\
}
#define RELEASEINTERFACE(pinterface)\
{\
if (pinterface!=NULL)\
{\
pinterface->Release();\
pinterface=NULL;\
}\
}
#define QUERYINTERFACE(pinterface, pinterface_res, iid)\
{\
if (pinterface!=NULL)\
pinterface->QueryInterface(iid, (void**)&pinterface_res);\
else\
pinterface_res=NULL;\
}
#define RELEASEMEM(pobject)\
{\
if (pobject!=NULL)\
{\
free(pobject);\
pobject=NULL;\
}\
}
#define RELEASEOBJECT(pobject)\
{\
if (pobject!=NULL)\
{\
delete pobject;\
pobject=NULL;\
}\
}
#define RELEASEARRAYOBJECTS(pobject)\
{\
if (pobject!=NULL)\
{\
delete []pobject;\
pobject=NULL;\
}\
}
#define RELEASEHEAP(pmem)\
{\
if (pmem!=NULL)\
{\
HeapFree(GetProcessHeap(), 0, pmem);\
pmem=NULL;\
}\
}
#define RELEASEARRAY(parray)\
{\
if (parray!=NULL)\
{\
SafeArrayDestroy(parray);\
parray=NULL;\
}\
}
#define RELEASESYSSTRING(pstring)\
{\
if (pstring!=NULL)\
{\
SysFreeString(pstring);\
pstring=NULL;\
}\
}
#define RELEASEHANDLE(phandle)\
{\
if (phandle!=NULL)\
{\
CloseHandle(phandle);\
phandle=NULL;\
}\
}
\ No newline at end of file
#include "Graphics.h"
#ifndef max
#define max(a,b) (((a) > (b)) ? (a) : (b))
#endif
#ifndef min
#define min(a,b) (((a) < (b)) ? (a) : (b))
#endif
namespace Aggplus
{
CGraphics::CGraphics()
{
m_pPixels = NULL;
m_pDib = NULL;
m_dWidthPix = 0;
m_dHeightPix = 0;
m_dDpiX = 72.0;
m_dDpiY = 72.0;
m_ePageUnits = UnitPixel;
m_bIntegerGrid = false;
#ifdef _WINDOWS_GDIPLUS_USE_
m_pBitmap = NULL;
m_pGraphics = NULL;
m_oInitGdiplus.Init();
#endif
m_dGlobalAlpha = 1.0;
m_bSwapRGB = false;
#if defined (_LINUX) || defined (_QT)
m_bSwapRGB = true;
#endif
}
CGraphics::CGraphics(int dwWidth, int dwHeight, int stride, BYTE* pBuffer) : m_dwConfigFlags(0)
{
m_dWidthPix = 0;
m_dHeightPix = 0;
m_dDpiX = 72.0;
m_dDpiY = 72.0;
m_ePageUnits = UnitPixel;
m_pPixels = NULL;
m_bIntegerGrid = false;
Create(pBuffer, dwWidth, dwHeight, stride, 0);
m_dGlobalAlpha = 1.0;
#ifdef _WINDOW_GDIPLUS_USE_
m_pBitmap = NULL;
m_pGraphics = NULL;
#endif
m_bSwapRGB = false;
#if defined (_LINUX) || defined (_QT)
m_bSwapRGB = true;
#endif
}
CGraphics::CGraphics(CImage* pImage) : m_dwConfigFlags(0)
{
m_dGlobalAlpha = 1.0;
if (!pImage)
{
return;
}
m_dWidthPix = 0;
m_dHeightPix = 0;
m_dDpiX = 72.0;
m_dDpiY = 72.0;
m_ePageUnits = UnitPixel;
m_pPixels = NULL;
m_bIntegerGrid = false;
Create(pImage->m_pImgData, pImage->GetWidth(), pImage->GetHeight(), pImage->m_nStride, 0);
#ifdef _WINDOW_GDIPLUS_USE_
m_pBitmap = NULL;
m_pGraphics = NULL;
#endif
m_bSwapRGB = false;
#if defined (_LINUX) || defined (_QT)
m_bSwapRGB = true;
#endif
}
CGraphics::~CGraphics()
{
#ifdef _WINDOW_GDIPLUS_USE_
RELEASEOBJECT(m_pGraphics);
RELEASEOBJECT(m_pBitmap);
#endif
}
INT CGraphics::IsDib()
{
return (NULL != m_pDib);
}
Status CGraphics::Create(BYTE* pPixels, int lWidth, int lHeight, int lStride, LONG lPitch)
{
if (lStride < 0)
{
//BYTE* pBuffer = pPixels + (lHeight - 1) * lStride;
//m_frame_buffer.create(lWidth, lHeight, false, lStride, pBuffer);
m_frame_buffer.create(lWidth, lHeight, false, lStride, pPixels);
}
else
{
m_frame_buffer.create(lWidth, lHeight, false, lStride, pPixels);
}
m_dWidthPix = (double)lWidth;
m_dHeightPix = (double)lHeight;
m_rasterizer.get_rasterizer().clip_box(0, 0, m_dWidthPix, m_dHeightPix);
m_rasterizer.get_rasterizer().gamma(agg::gamma_none());
m_dClipLeft = 0;
m_dClipTop = 0;
m_dClipWidth = m_dWidthPix;
m_dClipHeight = m_dHeightPix;
m_oClip.Create(lWidth, lHeight);
UpdateUnits();
return Ok;
}
Status CGraphics::Create2(BYTE* pPixels, int lWidth, int lHeight, int lStride, LONG lPitch, LONG x, LONG y, LONG w, LONG h, double dW, double dH, CDIB* pDib)
{
if (lStride < 0)
{
m_frame_buffer.create(lWidth, lHeight, false, lStride, pPixels);
}
else
{
m_frame_buffer.create(lWidth, lHeight, false, lStride, pPixels);
}
m_dWidthPix = (double)dW;
m_dHeightPix = (double)dH;
m_rasterizer.get_rasterizer().clip_box(x, y, w + x, h + y);
m_rasterizer.get_rasterizer().gamma(agg::gamma_none());
m_dClipLeft = x;
m_dClipTop = y;
m_dClipWidth = w;
m_dClipHeight = h;
m_oClip.Create(lWidth, lHeight);
UpdateUnits();
#ifdef _WINDOW_GDIPLUS_USE_
RELEASEOBJECT(m_pGraphics);
RELEASEOBJECT(m_pBitmap);
#endif
BYTE* pBuffer = pPixels;
if (0 > lStride)
{
// переворачиваем изображение для GDI+
pBuffer += 4 * lWidth * (lHeight - 1);
}
#ifdef _WINDOW_GDIPLUS_USE_
m_pBitmap = new Gdiplus::Bitmap(lWidth, lHeight, lStride, PixelFormat32bppARGB, pBuffer);
m_pGraphics = new Gdiplus::Graphics(m_pBitmap);
m_pGraphics->SetTextRenderingHint(Gdiplus::TextRenderingHintAntiAlias);
m_pGraphics->SetSmoothingMode(Gdiplus::SmoothingModeAntiAlias);
#endif
m_pPixels = pPixels;
m_pDib = pDib;
return Ok;
}
Status CGraphics::CreatePart(LONG lLeft, LONG lTop, LONG lWidth, LONG lHeight, CGraphics** ppPart)
{
// здесь минимум кода. Просто сделать дубликат - и выставить ему правильные границы.
// а потом уже и dpi и все настройки.
return Ok;
}
double CGraphics::GetDpiX()
{
return m_dDpiX;
}
double CGraphics::GetDpiY()
{
return m_dDpiY;
}
Status CGraphics::SetDpiX(double dDpiX)
{
if (dDpiX != m_dDpiX)
{
m_dDpiX = dDpiX;
}
return Ok;
}
Status CGraphics::SetDpiY(double dDpiY)
{
if (dDpiY != m_dDpiY)
{
m_dDpiY = dDpiY;
}
return Ok;
}
Status CGraphics::SetPageWidth(double lWidth, LONG lUnit)
{
// вычисилить dpi и выставить его
switch (lUnit)
{
case UnitPoint:
{
lWidth /= c_ag_Inch_to_Point;
SetDpiX(m_dWidthPix / lWidth);
break;
}
case UnitMillimeter:
{
lWidth /= c_ag_Inch_to_MM;
SetDpiX(m_dWidthPix / lWidth);
break;
}
case UnitInch:
{
SetDpiX(m_dWidthPix / lWidth);
break;
}
default:
break;
};
return Ok;
}
Status CGraphics::SetPageHeight(double lHeight, LONG lUnit)
{
// вычисилить dpi и выставить его
switch (lUnit)
{
case UnitPoint:
{
lHeight /= c_ag_Inch_to_Point;
SetDpiY(m_dHeightPix / lHeight);
break;
}
case UnitMillimeter:
{
lHeight /= c_ag_Inch_to_MM;
SetDpiY(m_dHeightPix / lHeight);
break;
}
case UnitInch:
{
SetDpiY(m_dHeightPix / lHeight);
break;
}
default:
break;
};
return Ok;
}
Unit CGraphics::GetPageUnit()
{
return m_ePageUnits;
}
Status CGraphics::SetPageUnit(Unit lUnits)
{
m_ePageUnits = lUnits;
UpdateUnits();
return Ok;
}
CMatrix* CGraphics::GetTransform()
{
return &m_oTransform;
}
Status CGraphics::SetTransform(CMatrix* pTransform)
{
m_oTransform = *pTransform;
return Ok;
}
CMatrix* CGraphics::GetBaseTransform()
{
return &m_oBaseTransform;
}
Status CGraphics::SetBaseTransform(CMatrix* pTransform)
{
m_oBaseTransform = *pTransform;
return Ok;
}
Status CGraphics::TranslateTransform(double x, double y, MatrixOrder order)
{
m_oTransform.Translate(x, y, order);
return Ok;
}
Status CGraphics::RotateTransform(double dAngle, MatrixOrder order)
{
m_oTransform.Rotate(dAngle, order);
return Ok;
}
Status CGraphics::ScaleTransform(double dScaleX, double dScaleY, MatrixOrder order)
{
m_oTransform.Scale(dScaleX, dScaleY, order);
return Ok;
}
Status CGraphics::ShearTransform(double shearX, double shearY, MatrixOrder order)
{
m_oTransform.Shear(shearX, shearY, order);
return Ok;
}
Status CGraphics::MultiplyTransform(CMatrix* pMatrix, MatrixOrder order)
{
m_oTransform.Multiply(pMatrix, order);
return Ok;
}
// функции отсечения
Status CGraphics::SetClipRect(double dLeft, double dTop, double dWidth, double dHeight)
{
double dx1 = dLeft;
double dy1 = dTop;
double dx2 = dLeft + dWidth;
double dy2 = dTop + dHeight;
m_oFullTransform.TransformPoint(dx1, dy1);
m_oFullTransform.TransformPoint(dx2, dy2);
m_dClipLeft = max(0, dx1);
m_dClipTop = max(0, dy1);
m_dClipWidth = min(dx2, m_dWidthPix - 1) - m_dClipLeft;
m_dClipHeight = min(dy2, m_dHeightPix - 1) - m_dClipTop;
m_oClip.Reset();
return Ok;
}
Status CGraphics::SetClipRect2(double dLeft, double dTop, double dWidth, double dHeight)
{
m_dClipLeft = max(0, dLeft);
m_dClipTop = max(0, dTop);
m_dClipWidth = min(dWidth, m_dWidthPix - 1 - m_dClipLeft);
m_dClipHeight = min(dHeight, m_dHeightPix - 1 - m_dClipTop);
m_rasterizer.get_rasterizer().clip_box(m_dClipLeft, m_dClipTop, m_dClipWidth + m_dClipLeft, m_dClipHeight + m_dClipTop);
m_oClip.Reset();
return Ok;
}
Status CGraphics::SetClipRect3(double dLeft, double dTop, double dWidth, double dHeight)
{
double dRight = dLeft + dWidth;
double dBottom = dTop + dHeight;
m_oFullTransform.TransformPoint(dLeft, dTop);
m_oFullTransform.TransformPoint(dRight, dBottom);
dWidth = dRight - dLeft;
dHeight = dBottom - dTop;
m_dClipLeft = dLeft;
m_dClipTop = dTop;
m_dClipWidth = dWidth;
m_dClipHeight = dHeight;
m_rasterizer.get_rasterizer().reset_clipping();
m_rasterizer.get_rasterizer().clip_box(m_dClipLeft, m_dClipTop, m_dClipWidth + m_dClipLeft, m_dClipHeight + m_dClipTop);
m_frame_buffer.ren_base().clip_box((int)m_dClipLeft, (int)m_dClipTop, (int)(m_dClipWidth + m_dClipLeft), (int)(m_dClipHeight + m_dClipTop));
m_oClip.Reset();
return Ok;
}
Status CGraphics::SetClip(CGraphicsPath* pPath)
{
if (NULL == pPath)
return InvalidParameter;
m_oClip.GenerateClip(pPath, &m_oFullTransform);
return Ok;
}
Status CGraphics::ResetClip()
{
m_oClip.Reset();
return Ok;
}
Status CGraphics::ExclugeClip(CGraphicsPath* pPath)
{
if (NULL == pPath)
return InvalidParameter;
CGraphicsPath oMemory;
oMemory.AddRectangle(0, 0, m_dWidthPix, m_dHeightPix);
oMemory.AddPath(*pPath);
m_oClip.GenerateClip(&oMemory, &m_oFullTransform);
return Ok;
}
Status CGraphics::CombineClip(CGraphicsPath* pPath, agg::sbool_op_e op)
{
if (NULL == pPath)
return InvalidParameter;
if (!m_bIntegerGrid)
m_oClip.Combine(pPath, &m_oFullTransform, op);
else
{
CMatrix transform;
m_oClip.Combine(pPath, &transform, op);
}
return Ok;
}
INT CGraphics::MeasureString(const std::wstring& strText, CFontManager* pManager, double* lWidth, double* lHeight)
{
if (NULL == pManager || NULL == lWidth || NULL == lHeight)
return FALSE;
pManager->LoadString1(strText, 0, 0);
TBBox oBox = pManager->MeasureString();
*lWidth = (double)oBox.fMaxX - oBox.fMinX;
*lHeight = (double)oBox.fMaxY - oBox.fMinY;
return TRUE;
}
Status CGraphics::Clear(CColor oColor)
{
CBrushSolid oBrush(oColor);
return FillRectangle(&oBrush, 0, 0, m_dWidthPix, m_dHeightPix);
}
Status CGraphics::DrawArc(NSStructures::CPen* pPen, double x, double y, double width, double height, double startAngle, double sweepAngle)
{
CGraphicsPath oPath;
oPath.AddArc(x, y, width, height, startAngle, sweepAngle);
return DrawPath(pPen, &oPath);
}
Status CGraphics::DrawBezier(NSStructures::CPen* pPen, double x1, double y1, double x2, double y2, double x3, double y3, double x4, double y4)
{
CGraphicsPath oPath;
oPath.AddBezier(x1, y1, x2, y2, x3, y3, x4, y4);
return DrawPath(pPen, &oPath);
}
Status CGraphics::DrawBeziers(NSStructures::CPen* pPen, double* pPoints, LONG lCount)
{
CGraphicsPath oPath;
oPath.AddBeziers(pPoints, lCount);
return DrawPath(pPen, &oPath);
}
Status CGraphics::DrawCurve(NSStructures::CPen* pPen, double* pPoints, LONG lCount)
{
CGraphicsPath oPath;
oPath.AddBeziers(pPoints, lCount);
return DrawPath(pPen, &oPath);
}
Status CGraphics::DrawLine(NSStructures::CPen* pPen, double x1, double y1, double x2, double y2)
{
CGraphicsPath oPath;
oPath.AddLine(x1, y1, x2, y2);
return DrawPath(pPen, &oPath);
}
Status CGraphics::DrawLines(NSStructures::CPen* pPen, double* pPoints, LONG lCount)
{
CGraphicsPath oPath;
oPath.AddLines(pPoints, lCount);
return DrawPath(pPen, &oPath);
}
Status CGraphics::DrawRectangle(NSStructures::CPen* pPen, double x, double y, double width, double height)
{
CGraphicsPath oPath;
oPath.AddRectangle(x, y, width, height);
return DrawPath(pPen, &oPath);
}
Status CGraphics::DrawEllipse(NSStructures::CPen* pPen, double x, double y, double width, double height)
{
CGraphicsPath oPath;
oPath.AddEllipse(x, y, width, height);
return DrawPath(pPen, &oPath);
}
Status CGraphics::DrawPath(NSStructures::CPen* pPen, CGraphicsPath* pPath)
{
if (NULL == pPen || NULL == pPath)
return InvalidParameter;
m_rasterizer.get_rasterizer().reset();
agg::line_join_e LineJoin = agg::round_join;
switch(pPen->LineJoin)
{
case LineJoinMiter : LineJoin = agg::miter_join_revert; break;
case LineJoinBevel : LineJoin = agg::bevel_join; break;
case LineJoinRound : LineJoin = agg::round_join; break;
case LineJoinMiterClipped : LineJoin = agg::miter_join_revert; break;
default: break;
}
agg::line_cap_e LineCap = agg::round_cap;
switch(pPen->LineStartCap)
{
case LineCapFlat : LineCap = agg::butt_cap; break;
case LineCapRound : LineCap = agg::round_cap; break;
case LineCapSquare : LineCap = agg::square_cap; break;
default: break;
}
double dWidth = pPen->Size;
if (0 == dWidth && !m_bIntegerGrid)
{
dWidth = 1.0 / sqrt(m_oCoordTransform.m_agg_mtx.determinant());
}
double dblMiterLimit = pPen->MiterLimit;
agg::path_storage path_copy(pPath->m_agg_ps);
typedef agg::conv_curve<agg::path_storage> conv_crv_type;
conv_crv_type c_c_path(path_copy);
c_c_path.approximation_scale(25.0);
c_c_path.approximation_method(agg::curve_inc);
DashStyle eStyle = (DashStyle)pPen->DashStyle;
agg::trans_affine* pAffine = &m_oFullTransform.m_agg_mtx;
if (m_bIntegerGrid)
pAffine = new agg::trans_affine();
if (DashStyleSolid == eStyle)
{
typedef agg::conv_stroke<conv_crv_type> Path_Conv_StrokeN;
Path_Conv_StrokeN pgN(c_c_path);
//pgN.line_join(agg::miter_join_revert);
pgN.line_cap(LineCap);
pgN.line_join(LineJoin);
pgN.inner_join(agg::inner_round);
pgN.miter_limit(dblMiterLimit);
pgN.width(dWidth);
pgN.approximation_scale(25.0);
typedef agg::conv_transform<Path_Conv_StrokeN> transStroke;
transStroke trans(pgN, *pAffine);
m_rasterizer.get_rasterizer().add_path(trans);
}
else
{
typedef agg::conv_dash<conv_crv_type> Path_Conv_Dash;
Path_Conv_Dash poly2_dash(c_c_path);
typedef agg::conv_stroke<Path_Conv_Dash> Path_Conv_StrokeD;
Path_Conv_StrokeD pgD(poly2_dash);
switch (eStyle)
{
case DashStyleDash:
poly2_dash.add_dash(3.00*dWidth, dWidth);
break;
case DashStyleDot:
poly2_dash.add_dash(dWidth, dWidth);
break;
case DashStyleDashDot:
poly2_dash.add_dash(3.00*dWidth, dWidth);
poly2_dash.add_dash(dWidth, dWidth);
break;
case DashStyleDashDotDot:
poly2_dash.add_dash(3.00*dWidth, dWidth);
poly2_dash.add_dash(dWidth, dWidth);
poly2_dash.add_dash(dWidth, dWidth);
break;
default:
case DashStyleCustom:
{
double offset = pPen->DashOffset;
double* params = pPen->DashPattern;
LONG lCount = pPen->Count;
LONG lCount2 = lCount / 2;
double dKoef = 0.352777778;
if (m_dDpiX > 1)
dKoef = 25.4 / m_dDpiX;
if (m_bIntegerGrid)
dKoef = 1.0;
for (LONG i = 0; i < lCount2; ++i)
{
if (0 == i)
{
poly2_dash.add_dash((params[i * 2]) * dKoef, params[i * 2 + 1] * dKoef);
}
else
{
poly2_dash.add_dash(params[i * 2] * dKoef, params[i * 2 + 1] * dKoef);
}
}
if (1 == (lCount % 2))
{
poly2_dash.add_dash(params[lCount - 1] * dKoef, 0);
}
poly2_dash.dash_start(offset * dKoef);
break;
}
}
pgD.line_cap(LineCap);
pgD.line_join(LineJoin);
pgD.miter_limit(dblMiterLimit);
pgD.width(dWidth);
agg::conv_transform<Path_Conv_StrokeD> trans(pgD, *pAffine);
m_rasterizer.get_rasterizer().add_path(trans);
}
CColor oColor((BYTE)(pPen->Alpha * m_dGlobalAlpha), pPen->Color, m_bSwapRGB);
CBrushSolid oBrush(oColor);
m_rasterizer.get_rasterizer().filling_rule(agg::fill_non_zero);
DoFillPath(&oBrush);
if (m_bIntegerGrid)
RELEASEOBJECT(pAffine);
return Ok;
}
Status CGraphics::DrawPathNoTransform(NSStructures::CPen* pPen, CGraphicsPath* pPath)
{
if (NULL == pPen || NULL == pPath)
return InvalidParameter;
m_rasterizer.get_rasterizer().reset();
//butt_cap, square_cap, round_cap
//pg.line_cap(agg::vcgen_stroke::round_cap);
agg::line_join_e LineJoin;
switch(pPen->LineJoin)
{
case LineJoinMiter : LineJoin = agg::miter_join; break;
case LineJoinBevel : LineJoin = agg::bevel_join; break;
default:
case LineJoinRound : LineJoin = agg::round_join; break;
case LineJoinMiterClipped: LineJoin = agg::miter_join_revert; break;
}
double dWidth = pPen->Size;
double dblMiterLimit = 0.5;
agg::path_storage path_copy(pPath->m_agg_ps);
typedef agg::conv_curve<agg::path_storage> conv_crv_type;
conv_crv_type c_c_path(path_copy);
c_c_path.approximation_scale(25.0);
c_c_path.approximation_method(agg::curve_inc);
DashStyle eStyle = (DashStyle)pPen->DashStyle;
if (DashStyleSolid == eStyle || DashStyleCustom == eStyle)
{
typedef agg::conv_stroke<conv_crv_type> Path_Conv_StrokeN;
Path_Conv_StrokeN pgN(c_c_path);
//typedef agg::conv_stroke<agg::path_storage> Path_Conv_StrokeN;
//Path_Conv_StrokeN pgN(pPath->m_agg_ps);
pgN.line_join(agg::round_join);
pgN.miter_limit(dblMiterLimit);
//pgN.approximation_scale(25.0);
pgN.width(dWidth);
typedef agg::conv_transform<Path_Conv_StrokeN> transStroke;
CMatrix oM;
transStroke trans(pgN, oM.m_agg_mtx);
m_rasterizer.get_rasterizer().add_path(trans);
}
else
{
typedef agg::conv_dash<conv_crv_type> Path_Conv_Dash;
Path_Conv_Dash poly2_dash(c_c_path);
typedef agg::conv_stroke<Path_Conv_Dash> Path_Conv_StrokeD;
Path_Conv_StrokeD pgD(poly2_dash);
switch (eStyle)
{
case DashStyleDash:
poly2_dash.add_dash(3.00*dWidth, dWidth);
break;
case DashStyleDot:
poly2_dash.add_dash(dWidth, dWidth);
break;
case DashStyleDashDot:
poly2_dash.add_dash(3.00*dWidth, dWidth);
poly2_dash.add_dash(dWidth, dWidth);
break;
case DashStyleDashDotDot:
poly2_dash.add_dash(3.00*dWidth, dWidth);
poly2_dash.add_dash(dWidth, dWidth);
poly2_dash.add_dash(dWidth, dWidth);
break;
default:
case DashStyleCustom:break;
}
pgD.line_join(LineJoin);
pgD.miter_limit(dblMiterLimit);
pgD.width(dWidth);
agg::conv_transform<Path_Conv_StrokeD> trans(pgD, m_oFullTransform.m_agg_mtx);
m_rasterizer.get_rasterizer().add_path(trans);
}
CColor oColor((BYTE)pPen->Alpha, pPen->Color, m_bSwapRGB);
CBrushSolid oBrush(oColor);
m_rasterizer.get_rasterizer().filling_rule(agg::fill_non_zero);
DoFillPath(&oBrush);
return Ok;
}
Status CGraphics::FillEllipse(CBrush* pBrush, double x, double y, double width, double height)
{
CGraphicsPath oPath;
oPath.AddEllipse(x, y, width, height);
return FillPath(pBrush, &oPath);
}
Status CGraphics::FillRectangle(CBrush* pBrush, double x, double y, double width, double height)
{
CGraphicsPath oPath;
oPath.AddRectangle(x, y, width, height);
return FillPath(pBrush, &oPath);
}
Status CGraphics::FillPolygon(CBrush* pBrush, double* pPoints, LONG lCount)
{
CGraphicsPath oPath;
oPath.AddPolygon(pPoints, lCount);
return FillPath(pBrush, &oPath);
}
Status CGraphics::FillPath(CBrush* pBrush, CGraphicsPath* pPath)
{
if (NULL == pBrush)
return InvalidParameter;
m_rasterizer.get_rasterizer().reset();
agg::path_storage p2(pPath->m_agg_ps);
typedef agg::conv_transform<agg::path_storage> trans_type;
trans_type* ptrans = NULL;
agg::trans_affine* paffine = NULL;
if (!m_bIntegerGrid)
ptrans = new trans_type(p2, m_oFullTransform.m_agg_mtx);
else
{
paffine = new agg::trans_affine();
ptrans = new trans_type(p2, *paffine);
}
typedef agg::conv_curve<trans_type> conv_crv_type;
conv_crv_type c_c_path(*ptrans);
m_rasterizer.get_rasterizer().add_path(c_c_path);
m_rasterizer.get_rasterizer().filling_rule(pPath->m_bEvenOdd ? agg::fill_even_odd : agg::fill_non_zero);
if (pBrush->GetType() == Aggplus::BrushTypeTextureFill)
{
CBrushTexture *ptxBrush= (CBrushTexture *)pBrush;
DWORD dwPatternWidth = ptxBrush->PatternGetWidth();
DWORD dwPatternHeight = ptxBrush->PatternGetHeight();
if( !dwPatternWidth || !dwPatternHeight )
return Ok;
double x = 0;
double y = 0;
double r = 0;
double b = 0;
pPath->GetBounds(x, y, r, b);
r += x;
b += y;
CMatrix brushMatrix;
if (ptxBrush->GetWrapMode() == Aggplus::WrapModeClamp)
{
double dScaleX = (r - x) / dwPatternWidth;
double dScaleY = (b - y) / dwPatternHeight;
brushMatrix.Scale(dScaleX, dScaleY, Aggplus::MatrixOrderAppend);
}
brushMatrix.Translate(x, y, Aggplus::MatrixOrderAppend);
brushMatrix.Multiply(&m_oFullTransform, MatrixOrderAppend);
ptxBrush->SetTransform(&brushMatrix);
}
DoFillPath(pBrush);
RELEASEOBJECT(ptrans);
RELEASEOBJECT(paffine);
return Ok;
}
// отрисовка картинки
Status CGraphics::DrawImage(CImage* pImage, double x, double y, double width, double height)
{
if (!pImage || pImage->GetLastStatus() != Ok)
return UnknownImageFormat;
if(width == 0.00 || height == 0.00)
return InvalidParameter;
CGraphicsPath oPath;
oPath.MoveTo(x, y);
oPath.LineTo(x+width, y);
oPath.LineTo(x+width, y+height);
oPath.LineTo(x, y+height);
oPath.CloseFigure();
CBrushTexture oBrush(pImage, Aggplus::WrapModeClamp);
FillPath(&oBrush, &oPath);
return Ok;
}
Status CGraphics::DrawMeta(const std::wstring& strFile, double x, double y, double width, double height)
{
return Ok;
}
#ifdef _WINDOW_GDIPLUS_USE_
Status CGraphics::DrawGdiplusImage(Gdiplus::Bitmap* pImage, double x, double y, double width, double height)
{
if (!pImage || pImage->GetLastStatus() != Gdiplus::Ok)
return UnknownImageFormat;
if(width == 0.00 || height == 0.00)
return InvalidParameter;
m_pGraphics->SetPageUnit(Gdiplus::UnitPixel);
double x1 = x;
double y1 = y;
m_oFullTransform.TransformPoint(x1, y1);
double x2 = x + width;
double y2 = y;
m_oFullTransform.TransformPoint(x2, y2);
double x3 = x;
double y3 = y + height;
m_oFullTransform.TransformPoint(x3, y3);
Gdiplus::PointF points[3];
points[0].X = (float)(x1 - 1.0);
points[0].Y = (float)(y1 - 1.0);
points[1].X = (float)(x2 + 1.0);
points[1].Y = (float)(y2 - 1.0);
points[2].X = (float)(x3 - 1.0);
points[2].Y = (float)(y3 + 1.0);
m_pGraphics->DrawImage(pImage, points, 3);
return Ok;
}
#endif
INT CGraphics::DrawImageUnscaled(CImage* pImage, double x, double y)
{
return TRUE;
}
INT CGraphics::DrawString(const std::wstring& strText, CFontManager* pFont, CBrush* pBrush, double x, double y)
{
if (pBrush->GetType() != BrushTypeSolidColor)
return TRUE;
CMatrix oMatrix = m_oBaseTransform;
oMatrix.Multiply(&m_oTransform, MatrixOrderPrepend);
double mass[6];
oMatrix.GetElements(mass);
double _x = x;
double _y = y;
CMatrix oM1 = oMatrix;
oM1.Invert();
oM1.Multiply(&m_oFullTransform, MatrixOrderPrepend);
oM1.TransformPoint(_x, _y);
pFont->SetTextMatrix((float)mass[0], (float)mass[1], (float)mass[2], (float)mass[3], (float)mass[4], (float)mass[5]);
pFont->LoadString2(strText, (float)_x, (float)_y);
float fX = 0;
float fY = 0;
INT bRes = FALSE;
while (TRUE)
{
TGlyph* pGlyph = NULL;
float fX = 0, fY = 0;
bRes = pFont->GetNextChar2(pGlyph, fX, fY);
if (FALSE == bRes)
break;
if (NULL != pGlyph)
{
FillGlyph2((int)fX, (int)fY, pGlyph, pBrush);
}
}
return TRUE;
}
INT CGraphics::DrawStringC(const LONG& lText, CFontManager* pFont, CBrush* pBrush, double x, double y)
{
if (pBrush->GetType() != BrushTypeSolidColor)
return TRUE;
CMatrix oMatrix = m_oBaseTransform;
oMatrix.Multiply(&m_oTransform, MatrixOrderPrepend);
double mass[6];
oMatrix.GetElements(mass);
double _x = x;
double _y = y;
CMatrix oM1 = oMatrix;
oM1.Invert();
oM1.Multiply(&m_oFullTransform, MatrixOrderPrepend);
oM1.TransformPoint(_x, _y);
pFont->SetTextMatrix((float)mass[0], (float)mass[1], (float)mass[2], (float)mass[3], (float)mass[4], (float)mass[5]);
pFont->LoadString2C(lText, (float)_x, (float)_y);
float fX = 0;
float fY = 0;
INT bRes = FALSE;
while (TRUE)
{
TGlyph* pGlyph = NULL;
float fX = 0, fY = 0;
bRes = pFont->GetNextChar2(pGlyph, fX, fY);
if (FALSE == bRes)
break;
if (NULL != pGlyph)
{
FillGlyph2((int)fX, (int)fY, pGlyph, pBrush);
}
}
return TRUE;
}
INT CGraphics::DrawStringPath(const std::wstring& strText, CFontManager* pFont, CBrush* pBrush, double x, double y)
{
if (pBrush->GetType() != BrushTypeSolidColor)
return TRUE;
double mass[6];
m_oTransform.GetElements(mass);
double _x = x;
double _y = y;
Aggplus::CGraphicsPath oPath;
oPath.AddString(strText, pFont, x, y);
FillPath(pBrush, &oPath);
return TRUE;
}
INT CGraphics::DrawStringPathC(const LONG& lText, CFontManager* pFont, CBrush* pBrush, double x, double y)
{
if (pBrush->GetType() != BrushTypeSolidColor)
return TRUE;
double mass[6];
m_oTransform.GetElements(mass);
double _x = x;
double _y = y;
Aggplus::CGraphicsPath oPath;
oPath.AddStringC(lText, pFont, x, y);
FillPath(pBrush, &oPath);
return TRUE;
}
void CGraphics::CalculateFullTransform()
{
m_oFullTransform = m_oCoordTransform;
m_oFullTransform.Multiply(&m_oBaseTransform, MatrixOrderAppend);
m_oFullTransform.Multiply(&m_oTransform, MatrixOrderPrepend);
}
bool CGraphics::IsClip()
{
return m_oClip.IsClip();
}
template<class Renderer>
void CGraphics::render_scanlines(Renderer& ren)
{
if (!m_oClip.IsClip())
{
return agg::render_scanlines(m_rasterizer.get_rasterizer(), m_rasterizer.get_scanline(), ren);
}
else
{
if (!m_oClip.IsClip2())
{
typedef agg::scanline_p8 sbool_scanline_type;
sbool_scanline_type sl_result;
sbool_scanline_type sl1;
sbool_scanline_type sl2;
agg::sbool_combine_shapes_aa(agg::sbool_and, m_rasterizer.get_rasterizer(), m_oClip.m_rasterizer,
sl1, sl2, sl_result, ren);
}
else
{
typedef agg::scanline_p8 sbool_scanline_type;
sbool_scanline_type sl_result;
sbool_scanline_type sl1;
sbool_scanline_type sl2;
sbool_scanline_type sl;
agg::sbool_combine_shapes_aa(agg::sbool_and, m_rasterizer.get_rasterizer(),
(1 == m_oClip.m_lCurStorage) ? m_oClip.m_storage1 : m_oClip.m_storage2, sl1, sl2, sl_result, ren);
}
}
}
template<class Rasterizer, class Renderer>
void CGraphics::render_scanlines(Rasterizer& ras, Renderer& ren)
{
if (!m_oClip.IsClip())
{
return agg::render_scanlines(ras, m_rasterizer.get_scanline(), ren);
}
else
{
if (!m_oClip.IsClip2())
{
typedef agg::scanline_p8 sbool_scanline_type;
sbool_scanline_type sl_result;
sbool_scanline_type sl1;
sbool_scanline_type sl2;
agg::sbool_combine_shapes_aa(agg::sbool_and, ras, m_oClip.m_rasterizer,
sl1, sl2, sl_result, ren);
}
else
{
typedef agg::scanline_p8 sbool_scanline_type;
sbool_scanline_type sl_result;
sbool_scanline_type sl1;
sbool_scanline_type sl2;
sbool_scanline_type sl;
agg::sbool_combine_shapes_aa(agg::sbool_and, ras,
(1 == m_oClip.m_lCurStorage) ? m_oClip.m_storage1 : m_oClip.m_storage2, sl1, sl2, sl_result, ren);
}
}
}
void CGraphics::DoFillPathSolid(CColor dwColor)
{
typedef agg::renderer_scanline_aa_solid<base_renderer_type> solid_renderer_type;
solid_renderer_type ren_fine(m_frame_buffer.ren_base());
ren_fine.color(dwColor.GetAggColor());
render_scanlines(ren_fine);
}
void CGraphics::DoFillPathGradient(CBrushLinearGradient *pBrush)
{
CDoubleRect& oBounds = pBrush->GetBounds();
CMatrix oMatrix;
agg::rect_d rect;
if (oBounds.GetWidth() > FLT_EPSILON || oBounds.GetHeight() > FLT_EPSILON)
{
rect.x1 = oBounds.left;
rect.y1 = oBounds.top;
rect.x2 = oBounds.right;
rect.y2 = oBounds.bottom;
oMatrix = m_oFullTransform;
oMatrix.Invert();
}
else
{
int x = m_rasterizer.get_rasterizer().min_x();
int y = m_rasterizer.get_rasterizer().min_y();
int width = m_rasterizer.get_rasterizer().max_x() - m_rasterizer.get_rasterizer().min_x();
int height = m_rasterizer.get_rasterizer().max_y() - m_rasterizer.get_rasterizer().min_y();
rect.x1 = x;
rect.x2 = x + width;
rect.y1 = y;
rect.y2 = y + height;
}
typedef agg::my_span_gradient<agg::rgba8> gradient_span_gen;
gradient_span_gen span_gen;
span_gen.SetDirection(rect, (double)pBrush->GetAngle(), oMatrix.m_agg_mtx);
agg::rgba8* pSubColors = NULL;
float* pSubBlends = NULL;
int nCountSubColors = pBrush->GetInterpolationColorsCount();
if( nCountSubColors > 0 )
{
pSubColors = new agg::rgba8[nCountSubColors];
pSubBlends = new float[nCountSubColors];
if( pSubColors && pSubBlends )
{
for( int i = 0; i < nCountSubColors; i++ )
{
CColor c;
pBrush->GetSubColor( i, &c, &pSubBlends[i] );
pSubColors[i] = agg::rgba8(c.GetB(), c.GetG(), c.GetR(), c.GetA());
}
span_gen.SetSubColors( pSubColors, pSubBlends, nCountSubColors );
}
}
typedef agg::span_allocator<gradient_span_gen::color_type> gradient_span_alloc;
gradient_span_alloc span_alloc;
typedef agg::renderer_scanline_aa<base_renderer_type, gradient_span_alloc, gradient_span_gen> renderer_gradient_type;
renderer_gradient_type ren_gradient( m_frame_buffer.ren_base(), span_alloc, span_gen );
if (fabs(m_dGlobalAlpha - 1.0) < FLT_EPSILON)
{
render_scanlines(ren_gradient);
}
else
{
m_rasterizer.gamma_multi(m_dGlobalAlpha);
render_scanlines(ren_gradient);
m_rasterizer.gamma(1.0);
}
if( pSubColors ) delete [] pSubColors;
if( pSubBlends ) delete [] pSubBlends;
}
void CGraphics::DoFillPathGradient2(CBrushLinearGradient *pBrush)
{
CDoubleRect& oBounds = pBrush->GetBounds();
CMatrix oMatrix;
agg::rect_d rect;
if (oBounds.GetWidth() > FLT_EPSILON || oBounds.GetHeight() > FLT_EPSILON)
{
rect.x1 = oBounds.left;
rect.y1 = oBounds.top;
rect.x2 = oBounds.right;
rect.y2 = oBounds.bottom;
oMatrix = m_oFullTransform;
oMatrix.Invert();
}
else
{
int x = m_rasterizer.get_rasterizer().min_x();
int y = m_rasterizer.get_rasterizer().min_y();
int width = m_rasterizer.get_rasterizer().max_x() - m_rasterizer.get_rasterizer().min_x();
int height = m_rasterizer.get_rasterizer().max_y() - m_rasterizer.get_rasterizer().min_y();
rect.x1 = x;
rect.x2 = x + width;
rect.y1 = y;
rect.y2 = y + height;
}
typedef agg::my_span_path_gradient<agg::rgba8> gradient_span_gen;
gradient_span_gen span_gen;
span_gen.SetDirection(rect, oMatrix.m_agg_mtx);
agg::rgba8* pSubColors = NULL;
float* pSubBlends = NULL;
int nCountSubColors = pBrush->GetInterpolationColorsCount();
if( nCountSubColors > 0 )
{
pSubColors = new agg::rgba8[nCountSubColors];
pSubBlends = new float[nCountSubColors];
if( pSubColors && pSubBlends )
{
for( int i = 0; i < nCountSubColors; i++ )
{
CColor c;
pBrush->GetSubColor( i, &c, &pSubBlends[i] );
pSubColors[i] = agg::rgba8(c.GetB(), c.GetG(), c.GetR(), c.GetA());
}
span_gen.SetSubColors( pSubColors, pSubBlends, nCountSubColors );
}
}
typedef agg::span_allocator<gradient_span_gen::color_type> gradient_span_alloc;
gradient_span_alloc span_alloc;
typedef agg::renderer_scanline_aa<base_renderer_type, gradient_span_alloc, gradient_span_gen> renderer_gradient_type;
renderer_gradient_type ren_gradient( m_frame_buffer.ren_base(), span_alloc, span_gen );
if (fabs(m_dGlobalAlpha - 1.0) < FLT_EPSILON)
{
render_scanlines(ren_gradient);
}
else
{
m_rasterizer.gamma_multi(m_dGlobalAlpha);
render_scanlines(ren_gradient);
m_rasterizer.gamma(1.0);
}
if( pSubColors ) delete [] pSubColors;
if( pSubBlends ) delete [] pSubBlends;
}
void CGraphics::DoFillPathHatch(CBrushHatch *pBrush)
{
#if 0
CDoubleRect& oBounds = pBrush->GetBounds();
CMatrix oMatrix;
agg::rect_d rect;
if (oBounds.GetWidth() > FLT_EPSILON || oBounds.GetHeight() > FLT_EPSILON)
{
rect.x1 = oBounds.left;
rect.y1 = oBounds.top;
rect.x2 = oBounds.right;
rect.y2 = oBounds.bottom;
oMatrix = m_oFullTransform;
}
else
{
int x = m_rasterizer.get_rasterizer().min_x();
int y = m_rasterizer.get_rasterizer().min_y();
int width = m_rasterizer.get_rasterizer().max_x() - m_rasterizer.get_rasterizer().min_x();
int height = m_rasterizer.get_rasterizer().max_y() - m_rasterizer.get_rasterizer().min_y();
rect.x1 = x;
rect.x2 = x + width;
rect.y1 = y;
rect.y2 = y + height;
}
typedef agg::agg_span_hatch<agg::rgba8> hatch_span_gen;
hatch_span_gen span_gen;
agg::rgba8 c1 = agg::rgba8(pBrush->m_dwColor1.GetB(), pBrush->m_dwColor1.GetG(), pBrush->m_dwColor1.GetR(), pBrush->m_dwColor1.GetA());
agg::rgba8 c2 = agg::rgba8(pBrush->m_dwColor2.GetB(), pBrush->m_dwColor2.GetG(), pBrush->m_dwColor2.GetR(), pBrush->m_dwColor2.GetA());
span_gen.SetDirection(pBrush->m_name, rect, oMatrix.m_agg_mtx, c1, c2);
typedef agg::span_allocator<hatch_span_gen::color_type> hatch_span_alloc;
hatch_span_alloc span_alloc;
typedef agg::renderer_scanline_aa<base_renderer_type, hatch_span_alloc, hatch_span_gen> renderer_hatch_type;
renderer_hatch_type ren_hatch( m_frame_buffer.ren_base(), span_alloc, span_gen );
if (fabs(m_dGlobalAlpha - 1.0) < FLT_EPSILON)
{
render_scanlines(ren_hatch);
}
else
{
m_rasterizer.gamma_multi(m_dGlobalAlpha);
render_scanlines(ren_hatch);
m_rasterizer.gamma(1.0);
}
#else
agg::rgba8 c1 = agg::rgba8(pBrush->m_dwColor1.GetB(), pBrush->m_dwColor1.GetG(), pBrush->m_dwColor1.GetR(), pBrush->m_dwColor1.GetA());
agg::rgba8 c2 = agg::rgba8(pBrush->m_dwColor2.GetB(), pBrush->m_dwColor2.GetG(), pBrush->m_dwColor2.GetR(), pBrush->m_dwColor2.GetA());
BYTE* pPattern = new BYTE[HATCH_TX_SIZE * HATCH_TX_SIZE * 4];
agg::GetHatchPattern(pBrush->m_name, (agg::rgba8*)pPattern, c1, c2);
agg::trans_affine mtx_Work(m_oTransform.m_agg_mtx);
mtx_Work.invert();
span_alloc_type span_allocator;
interpolator_type_linear interpolator(mtx_Work);
agg::rendering_buffer PatRendBuff;
PatRendBuff.attach(pPattern, HATCH_TX_SIZE, HATCH_TX_SIZE, HATCH_TX_SIZE << 2);
typedef agg::pixfmt_bgra32 pixfmt;
//image_accessor_wrap
typedef agg::wrap_mode_repeat wrap_x_type;
typedef agg::wrap_mode_repeat wrap_y_type;
typedef agg::image_accessor_wrap<pixfmt, wrap_x_type, wrap_y_type> img_source_type;
typedef agg::span_image_filter_rgba_bilinear<img_source_type, interpolator_type_linear> span_gen_type;
typedef agg::renderer_scanline_aa<base_renderer_type, span_alloc_type, span_gen_type> renderer_type;
pixfmt img_pixf(PatRendBuff);
img_source_type img_src(img_pixf);
span_gen_type sg(img_src, interpolator);
renderer_type ri(m_frame_buffer.ren_base(), span_allocator, sg);
if (fabs(m_dGlobalAlpha - 1.0) < FLT_EPSILON)
{
render_scanlines(ri);
}
else
{
m_rasterizer.gamma_multi(m_dGlobalAlpha);
render_scanlines(ri);
m_rasterizer.gamma(1.0);
}
RELEASEARRAYOBJECTS(pPattern);
#endif
}
void CGraphics::DoFillPathTextureClampSz(const CMatrix &mImgMtx, const void *pImgBuff, DWORD dwImgWidth, DWORD dwImgHeight, int nImgStride)
{
span_alloc_type span_allocator; // Span Allocator
typedef agg::pixfmt_rgba32 pixfmt;
typedef agg::image_accessor_clip<pixfmt> img_source_type;
typedef agg::span_image_filter_rgba_bilinear<img_source_type, interpolator_type_linear> span_gen_type;
typedef agg::renderer_scanline_aa<base_renderer_type, span_alloc_type, span_gen_type> renderer_type;
agg::trans_affine mtx_Work(mImgMtx.m_agg_mtx);
mtx_Work.multiply(m_oFullTransform.m_agg_mtx);
mtx_Work.invert();
interpolator_type_linear interpolator(mtx_Work);
{
//agg::rendering_buffer PatRendBuff((BYTE *)pImgBuff, dwImgWidth, dwImgHeight, nImgStride);
agg::rendering_buffer PatRendBuff;
if (nImgStride < 0)
{
BYTE* pBuffer = (BYTE*)pImgBuff + (dwImgHeight - 1) * nImgStride;
PatRendBuff.attach(pBuffer, dwImgWidth, dwImgHeight, nImgStride);
}
else
{
PatRendBuff.attach((BYTE*)pImgBuff, dwImgWidth, dwImgHeight, nImgStride);
}
pixfmt img_pixf(PatRendBuff);
img_source_type img_src(img_pixf, agg::rgba(0, 0, 0, 0));
span_gen_type sg(img_src, interpolator);
renderer_type ri(m_frame_buffer.ren_base(), span_allocator, sg);
//agg::render_scanlines(m_rasterizer.get_rasterizer(), m_rasterizer.get_scanline(), ri);
render_scanlines(ri);
}
}
void CGraphics::DoFillPathTextureClampSz2(const CMatrix &mImgMtx, const void *pImgBuff, DWORD dwImgWidth, DWORD dwImgHeight, int nImgStride, BYTE Alpha)
{
if (!m_bSwapRGB)
{
span_alloc_type span_allocator; // Span Allocator
typedef agg::pixfmt_bgra32 pixfmt;
typedef agg::image_accessor_clip<pixfmt> img_source_type;
typedef agg::span_image_filter_rgba_nn<img_source_type, interpolator_type_linear> span_gen_type;
typedef agg::renderer_scanline_aa<base_renderer_type, span_alloc_type, span_gen_type> renderer_type;
//double dScaleX = 270.0 / dwImgWidth;
//double dScaleY = 190.0 / dwImgHeight;
agg::trans_affine mtx_Work(mImgMtx.m_agg_mtx);
//mtx_Work.scale(dScaleX, dScaleY);
//mtx_Work.multiply(m_oFullTransform.m_agg_mtx);
mtx_Work.invert();
interpolator_type_linear interpolator(mtx_Work);
{
//agg::rendering_buffer PatRendBuff((BYTE *)pImgBuff, dwImgWidth, dwImgHeight, nImgStride);
agg::rendering_buffer PatRendBuff;
if (nImgStride < 0)
{
BYTE* pBuffer = (BYTE*)pImgBuff + (dwImgHeight - 1) * nImgStride;
PatRendBuff.attach(pBuffer, dwImgWidth, dwImgHeight, nImgStride);
}
else
{
PatRendBuff.attach((BYTE*)pImgBuff, dwImgWidth, dwImgHeight, nImgStride);
}
pixfmt img_pixf(PatRendBuff);
img_source_type img_src(img_pixf, agg::rgba(0, 0, 0, 0));
span_gen_type sg(img_src, interpolator);
renderer_type ri(m_frame_buffer.ren_base(), span_allocator, sg);
//agg::render_scanlines(m_rasterizer.get_rasterizer(), m_rasterizer.get_scanline(), ri);
double dAlpha = m_dGlobalAlpha * Alpha / 255.0;
if (fabs(dAlpha - 1.0) < FLT_EPSILON)
{
render_scanlines(ri);
}
else
{
m_rasterizer.gamma_multi(dAlpha);
render_scanlines(ri);
m_rasterizer.gamma(1.0);
}
}
}
else
{
span_alloc_type span_allocator; // Span Allocator
typedef agg::pixfmt_rgba32 pixfmt;
typedef agg::image_accessor_clip<pixfmt> img_source_type;
typedef agg::span_image_filter_rgba_nn<img_source_type, interpolator_type_linear> span_gen_type;
typedef agg::renderer_scanline_aa<base_renderer_type, span_alloc_type, span_gen_type> renderer_type;
//double dScaleX = 270.0 / dwImgWidth;
//double dScaleY = 190.0 / dwImgHeight;
agg::trans_affine mtx_Work(mImgMtx.m_agg_mtx);
//mtx_Work.scale(dScaleX, dScaleY);
//mtx_Work.multiply(m_oFullTransform.m_agg_mtx);
mtx_Work.invert();
interpolator_type_linear interpolator(mtx_Work);
{
//agg::rendering_buffer PatRendBuff((BYTE *)pImgBuff, dwImgWidth, dwImgHeight, nImgStride);
agg::rendering_buffer PatRendBuff;
if (nImgStride < 0)
{
BYTE* pBuffer = (BYTE*)pImgBuff + (dwImgHeight - 1) * nImgStride;
PatRendBuff.attach(pBuffer, dwImgWidth, dwImgHeight, nImgStride);
}
else
{
PatRendBuff.attach((BYTE*)pImgBuff, dwImgWidth, dwImgHeight, nImgStride);
}
pixfmt img_pixf(PatRendBuff);
img_source_type img_src(img_pixf, agg::rgba(0, 0, 0, 0));
span_gen_type sg(img_src, interpolator);
renderer_type ri(m_frame_buffer.ren_base(), span_allocator, sg);
//agg::render_scanlines(m_rasterizer.get_rasterizer(), m_rasterizer.get_scanline(), ri);
double dAlpha = m_dGlobalAlpha * Alpha / 255.0;
if (fabs(dAlpha - 1.0) < FLT_EPSILON)
{
render_scanlines(ri);
}
else
{
m_rasterizer.gamma_multi(dAlpha);
render_scanlines(ri);
m_rasterizer.gamma(1.0);
}
}
}
}
template<class ColorSpacePix>
void CGraphics::DoFillPathTextureClampSz3(const CMatrix &matrix, const void *pImgBuff, DWORD dwImgWidth, DWORD dwImgHeight, int nImgStride, Aggplus::WrapMode wrapmode, BYTE Alpha)
{
agg::trans_affine mtx_Work( matrix.m_agg_mtx );
agg::trans_affine coords = m_oCoordTransform.m_agg_mtx;
coords.invert();
mtx_Work.multiply(coords);
//mtx_Work.multiply(m_oFullTransform.m_agg_mtx);
mtx_Work.invert();
span_alloc_type span_allocator; // Span Allocator
interpolator_type_linear interpolator(mtx_Work);
//agg::rendering_buffer PatRendBuff((BYTE *)pImgBuff, dwImgWidth, dwImgHeight, nImgStride);
agg::rendering_buffer PatRendBuff;
if (nImgStride < 0)
{
BYTE* pBuffer = (BYTE*)pImgBuff + (dwImgHeight - 1) * nImgStride;
PatRendBuff.attach(pBuffer, dwImgWidth, dwImgHeight, nImgStride);
}
else
{
PatRendBuff.attach((BYTE*)pImgBuff, dwImgWidth, dwImgHeight, nImgStride);
}
typedef ColorSpacePix pixfmt;
if(wrapmode == WrapModeTileFlipX)
{
//image_accessor_wrap
typedef agg::wrap_mode_reflect wrap_x_type;
typedef agg::wrap_mode_repeat wrap_y_type;
typedef agg::image_accessor_wrap<pixfmt, wrap_x_type, wrap_y_type> img_source_type;
typedef agg::span_image_filter_rgba_bilinear<img_source_type, interpolator_type_linear> span_gen_type;
typedef agg::renderer_scanline_aa<base_renderer_type, span_alloc_type, span_gen_type> renderer_type;
pixfmt img_pixf(PatRendBuff);
img_source_type img_src(img_pixf);
span_gen_type sg(img_src, interpolator);
renderer_type ri(m_frame_buffer.ren_base(), span_allocator, sg);
double dAlpha = m_dGlobalAlpha * Alpha / 255.0;
if (fabs(dAlpha - 1.0) < FLT_EPSILON)
{
render_scanlines(ri);
}
else
{
m_rasterizer.gamma_multi(dAlpha);
render_scanlines(ri);
m_rasterizer.gamma(1.0);
}
}
else if(wrapmode == WrapModeTileFlipY)
{
//image_accessor_wrap
typedef agg::wrap_mode_repeat wrap_x_type;
typedef agg::wrap_mode_reflect wrap_y_type;
typedef agg::image_accessor_wrap<pixfmt, wrap_x_type, wrap_y_type> img_source_type;
typedef agg::span_image_filter_rgba_bilinear<img_source_type, interpolator_type_linear> span_gen_type;
typedef agg::renderer_scanline_aa<base_renderer_type, span_alloc_type, span_gen_type> renderer_type;
pixfmt img_pixf(PatRendBuff);
img_source_type img_src(img_pixf);
span_gen_type sg(img_src, interpolator);
renderer_type ri(m_frame_buffer.ren_base(), span_allocator, sg);
double dAlpha = m_dGlobalAlpha * Alpha / 255.0;
if (fabs(dAlpha - 1.0) < FLT_EPSILON)
{
render_scanlines(ri);
}
else
{
m_rasterizer.gamma_multi(dAlpha);
render_scanlines(ri);
m_rasterizer.gamma(1.0);
}
}
else if(wrapmode == WrapModeTileFlipXY)
{
//image_accessor_wrap
typedef agg::wrap_mode_reflect wrap_x_type;
typedef agg::wrap_mode_reflect wrap_y_type;
typedef agg::image_accessor_wrap<pixfmt, wrap_x_type, wrap_y_type> img_source_type;
typedef agg::span_image_filter_rgba_bilinear<img_source_type, interpolator_type_linear> span_gen_type;
typedef agg::renderer_scanline_aa<base_renderer_type, span_alloc_type, span_gen_type> renderer_type;
pixfmt img_pixf(PatRendBuff);
img_source_type img_src(img_pixf);
span_gen_type sg(img_src, interpolator);
renderer_type ri(m_frame_buffer.ren_base(), span_allocator, sg);
double dAlpha = m_dGlobalAlpha * Alpha / 255.0;
if (fabs(dAlpha - 1.0) < FLT_EPSILON)
{
render_scanlines(ri);
}
else
{
m_rasterizer.gamma_multi(dAlpha);
render_scanlines(ri);
m_rasterizer.gamma(1.0);
}
}
else //Repeat
{
//image_accessor_wrap
typedef agg::wrap_mode_repeat wrap_x_type;
typedef agg::wrap_mode_repeat wrap_y_type;
typedef agg::image_accessor_wrap<pixfmt, wrap_x_type, wrap_y_type> img_source_type;
typedef agg::span_image_filter_rgba_bilinear<img_source_type, interpolator_type_linear> span_gen_type;
typedef agg::renderer_scanline_aa<base_renderer_type, span_alloc_type, span_gen_type> renderer_type;
pixfmt img_pixf(PatRendBuff);
img_source_type img_src(img_pixf);
span_gen_type sg(img_src, interpolator);
renderer_type ri(m_frame_buffer.ren_base(), span_allocator, sg);
double dAlpha = m_dGlobalAlpha * Alpha / 255.0;
if (fabs(dAlpha - 1.0) < FLT_EPSILON)
{
render_scanlines(ri);
}
else
{
m_rasterizer.gamma_multi(dAlpha);
render_scanlines(ri);
m_rasterizer.gamma(1.0);
}
}
}
void CGraphics::DoFillPath(const CBrush* Brush)
{
if (NULL == Brush)
return;
if (Brush->GetType() == BrushTypeSolidColor)
{
CColor clr;
((CBrushSolid*)Brush)->GetColor(&clr);
DoFillPathSolid(clr);
}
else if (Brush->GetType() == BrushTypeHatchFill)
{
DoFillPathHatch((Aggplus::CBrushHatch*)Brush);
}
else if (Brush->GetType() == BrushTypeTextureFill)
{
CBrushTexture *ptxBrush = (CBrushTexture *)Brush;
LPVOID pImgBuff = ptxBrush->PatternFinalize();
if (pImgBuff)
{
DWORD dwImgWidth = ptxBrush->PatternGetWidth();
DWORD dwImgHeight = ptxBrush->PatternGetHeight();
int nImgStride = ptxBrush->PatternGetStride();
if(pImgBuff && dwImgWidth && dwImgHeight)
{
Aggplus::WrapMode wrapmode = ptxBrush->m_wrapMode;
Aggplus::CMatrix matrix = ptxBrush->m_mtx;
BYTE* pTmpBuffer = NULL;
if( ptxBrush->m_bUsePattern )
{
pTmpBuffer = new BYTE[dwImgWidth*dwImgHeight*4];
if( pTmpBuffer )
{
BYTE clr2[4] = {ptxBrush->m_colors[0].GetR(), ptxBrush->m_colors[0].GetG(), ptxBrush->m_colors[0].GetB(), ptxBrush->m_colors[0].GetA()};
BYTE clr1[4] = {ptxBrush->m_colors[1].GetR(), ptxBrush->m_colors[1].GetG(), ptxBrush->m_colors[1].GetB(), ptxBrush->m_colors[1].GetA()};
BYTE* src = (BYTE*)pImgBuff;
BYTE* dst = pTmpBuffer;
int stride = nImgStride - dwImgWidth * 4;
for( unsigned y = 0; y < dwImgHeight; ++y, src += stride )
{
for( unsigned x = 0; x < dwImgWidth; ++x, src += 4, dst += 4 )
{
unsigned grey2 = (src[2] * 77 + src[1] * 150 + src[0] * 29 + 128) >> 8;
unsigned grey1 = 255 - grey2;
dst[0] = (BYTE)((clr1[0] * grey1 + clr2[0] * grey2 + 128) * 0x8081 >> 23);
dst[1] = (BYTE)((clr1[1] * grey1 + clr2[1] * grey2 + 128) * 0x8081 >> 23);
dst[2] = (BYTE)((clr1[2] * grey1 + clr2[2] * grey2 + 128) * 0x8081 >> 23);
dst[3] = (BYTE)((clr1[3] * (255 - src[3]) + clr2[3] * src[3] + 128) * 0x8081 >> 23);
}
}
pImgBuff = pTmpBuffer;
nImgStride = dwImgWidth * 4;
wrapmode = WrapModeTile;
matrix.Reset();
}
}
if(wrapmode == WrapModeClamp)
{
DoFillPathTextureClampSz2( matrix, pImgBuff, dwImgWidth, dwImgHeight, nImgStride, ptxBrush->Alpha);
}
else
{
if (!m_bSwapRGB)
{
DoFillPathTextureClampSz3<agg::pixfmt_bgra32>(matrix, pImgBuff, dwImgWidth, dwImgHeight, nImgStride, wrapmode, ptxBrush->Alpha);
}
else
{
DoFillPathTextureClampSz3<agg::pixfmt_rgba32>(matrix, pImgBuff, dwImgWidth, dwImgHeight, nImgStride, wrapmode, ptxBrush->Alpha);
}
}
if( pTmpBuffer )
delete [] pTmpBuffer;
}
}
}
else if (Brush->GetType() == BrushTypeLinearGradient)
{
DoFillPathGradient((CBrushLinearGradient*)Brush);
}
else if (Brush->GetType() == BrushTypePathGradient)
{
DoFillPathGradient2((CBrushLinearGradient*)Brush);
}
}
// text methods
int CGraphics::FillGlyph2(int nX, int nY, TGlyph* pGlyph, Aggplus::CBrush* pBrush)
{
int lWidth = pGlyph->oBitmap.nWidth;
int lHeight = pGlyph->oBitmap.nHeight;
BYTE* pData = pGlyph->oBitmap.pData;
int nFrameW = (int)m_frame_buffer.width();
int nFrameH = (int)m_frame_buffer.height();
if (NULL == pData)
return 0;
if (NULL == pData || (nX + lWidth < 0) || (nX >= nFrameW) || (nY + lHeight < 0))
return 0;
if (!m_oClip.IsClip() && (0 <= nX) && (0 <= nY) && ((nX + lWidth) < nFrameW) && ((nY + lHeight) < nFrameH))
{
return FillGlyphSimple(nX, nY, lWidth, lHeight, pData, pBrush);
}
typedef agg::scanline_u8_am<agg::alpha_mask_gray8> scanline_type;
agg::scanline_storage_aa8 storage;
//PrepareScanlineStorage(&storage, nX, nY, pGlyph);
for (int j = 0; j < lHeight; ++j)
{
agg::scanline_p8 sl;
sl.reset(nX, nX + lWidth);
sl.add_cells(nX, lWidth, pData + j * lWidth);
sl.finalize(nY + j);
storage.render(sl);
}
if (pBrush->GetType() == Aggplus::BrushTypeSolidColor)
{
CColor clr;
((CBrushSolid*)pBrush)->GetColor(&clr);
typedef agg::renderer_scanline_aa_solid<base_renderer_type> solid_renderer_type;
solid_renderer_type ren_fine(m_frame_buffer.ren_base());
ren_fine.color(clr.GetAggColor());
//agg::render_scanlines(storage, m_rasterizer.get_scanline(), ren_fine);
render_scanlines(storage, ren_fine);
}
return 0;
}
int CGraphics::FillGlyphSimple(int nX, int nY, LONG lWidth, LONG lHeight, BYTE* pData, Aggplus::CBrush* pBrush)
{
CColor clr;
((CBrushSolid*)pBrush)->GetColor(&clr);
typedef agg::renderer_scanline_aa_solid<base_renderer_type> solid_renderer_type;
solid_renderer_type ren_fine(m_frame_buffer.ren_base());
ren_fine.color(clr.GetAggColor());
ren_fine.render(lWidth, lHeight, pData, nX, nY);
return 0;
}
void CGraphics::PrepareScanlineStorage(agg::scanline_storage_aa8* storage, int x, int y, TGlyphBitmap *pGlyph)
{
//agg::scanline_p8 sl;
int width = pGlyph->nWidth;
m_rasterizer.get_scanline().reset(x, x + width);
for (int j = 0; j < pGlyph->nHeight; ++j)
{
m_rasterizer.get_scanline().add_cells(x + j * width, width, pGlyph->pData + j * width);
}
m_rasterizer.get_scanline().finalize(y);
storage->render(m_rasterizer.get_scanline());
}
void CGraphics::UpdateUnits()
{
// здесь - пересчет координат
m_oCoordTransform.Reset();
double dScaleX = 1.0;
double dScaleY = 1.0;
switch (m_ePageUnits)
{
case UnitPoint:
{
dScaleX = m_dDpiX / c_ag_Inch_to_Point;
dScaleY = m_dDpiY / c_ag_Inch_to_Point;
break;
}
case UnitMillimeter:
{
dScaleX = m_dDpiX / c_ag_Inch_to_MM;
dScaleY = m_dDpiY / c_ag_Inch_to_MM;
break;
}
case UnitInch:
{
dScaleX = m_dDpiX;
dScaleY = m_dDpiY;
break;
}
default:
break;
};
m_oCoordTransform.Scale(dScaleX, dScaleY, MatrixOrderAppend);
CalculateFullTransform();
}
}
#ifndef _BUILD_GRAPHICS_H_
#define _BUILD_GRAPHICS_H_
//#define _WINDOWS_GDIPLUS_USE_
#include "AggPlusEnums.h"
#include "../agg-2.4/include/agg_pixfmt_rgba.h"
#include "../agg-2.4/include/agg_conv_curve.h"
#include "../agg-2.4/include/agg_conv_stroke.h"
#include "../agg-2.4/include/agg_conv_dash.h"
#include "../agg-2.4/include/agg_span_gradient.h"
#include "../agg-2.4/include/agg_span_hatch.h"
#include "../agg-2.4/include/agg_span_interpolator_linear.h"
#include "../agg-2.4/include/agg_conv_transform.h"
#include "../agg-2.4/include/agg_span_image_filter_rgba.h"
#include "../agg-2.4/include/agg_span_pattern_rgba.h"
#include "../agg-2.4/include/agg_image_accessors.h"
#include "../agg-2.4/include/agg_span_allocator.h"
#include "../agg-2.4/include/agg_image_filters.h"
#include "../agg-2.4/include/agg_basics.h"
#include "../agg-2.4/include/agg_color_rgba.h"
#include "../agg-2.4/include/agg_pixfmt_rgba.h"
#include "../agg-2.4/include/agg_rasterizer_scanline_aa.h"
#include "../agg-2.4/include/agg_renderer_scanline.h"
#include "../agg-2.4/include/agg_scanline_u.h"
#include "../agg-2.4/include/agg_pixfmt_amask_adaptor.h"
#include "../agg-2.4/include/agg_scanline_boolean_algebra.h"
#include "../agg-2.4/svg/agg_svg_rasterizer.h"
#include "Color.h"
#include "Matrix.h"
#include "GraphicsPath.h"
#include "Clip.h"
#include "Brush.h"
#include "Image.h"
#if defined(_WIN32) || defined (_WIN64)
namespace NSStringFormat
{
// printf-like formatting using variable arguments parameter
static std::wstring FormatV(wchar_t* lpszFormat, va_list argList)
{
std::wstring s;
int sizeBuff = 512 * 2;
wchar_t* szFormat = NULL;
int write = -1;
do
{
szFormat = new wchar_t[sizeBuff];
write = _vsnwprintf(szFormat, sizeBuff - 1, lpszFormat, argList);
if (write >= 0)
{
s = szFormat;
}
delete [] szFormat;
} while (write < 0);
return s;
}
static std::wstring Format(wchar_t* lpszFormat, ...)
{
va_list arglist;
va_start(arglist, lpszFormat);
std::wstring s = FormatV(lpszFormat, arglist);
va_end(arglist);
return s;
}
}
#endif
const double c_ag_Inch_to_MM = 25.4;
const double c_ag_Inch_to_Point = 72;
const long c_ag_CombineModeReplace = 0;
const long c_ag_CombineModeIntersect = 1;
const long c_ag_CombineModeUnion = 2;
const long c_ag_CombineModeXor = 3;
const long c_ag_CombineModeExclude = 4;
const long c_ag_CombineModeComplement = 5;
const long c_ag_PageUnitPixel = 0;
const long c_ag_PageUnitPoint = 1;
const long c_ag_PageUnitInch = 2;
const long c_ag_PageUnitMillimeter = 3;
namespace Aggplus
{
typedef agg::rendering_buffer rendering_buffer_type;
typedef agg::pixfmt_bgra32 pixformat_type;
typedef agg::blender_rgba< agg::svg::color_type, agg::svg::component_order > blender_type;
typedef agg::pixfmt_alpha_blend_rgba< blender_type, agg::rendering_buffer, agg::svg::pixel_type > pixfmt_type;
typedef agg::renderer_base<pixfmt_type> base_renderer_type;
typedef agg::scanline_u8 scanline_type;
typedef agg::span_interpolator_linear<> interpolator_type_linear;
typedef agg::span_allocator<agg::rgba8> span_alloc_type;
#define def_flag_G_ExtBuffer 0x0001
#define def_flag_G_FromHDC 0x0002
// Расстояние от центра до контрольных точек Безье для аппроксимации окружности = (4 * (sqrt(2) - 1) / 3) * r
static const double c_dKappa = ((double)0.55228475);
static const double c_dKappa_2 = ((double)(0.5 * 0.55228475));
// Делим 16-битное значение [0, 255*255] на 255, возвращаем 8-битное значение.
static inline unsigned char Div255(int nValue)
{
return (unsigned char)((nValue + (nValue >> 8) + 0x80) >> 8);
}
//-------------------------------------------------------------------------------------------------------------------------------
class CDIB : public IGrObject
{
public:
BYTE* m_pBits;
LONG m_lWidth;
LONG m_lHeight;
public:
CDIB() : IGrObject()
{
m_pBits = NULL;
m_lWidth = 0;
m_lHeight = 0;
}
virtual ~CDIB()
{
// delete all in system wrapper
}
virtual INT Create(LONG lWidth, LONG lHeight, double dDPIX, double dDPIY) = 0;
};
class CGraphics
{
friend class CGlyphImage;
friend class CMatrix;
friend class CGraphicsPath;
friend class CColor;
friend class CBrush;
friend class CBrushLinearGradient;
friend class CBrushTexture;
friend class CImage;
friend class CGraphicsRenderer;
protected:
BYTE* m_pPixels;
DWORD m_dwConfigFlags;
double m_dWidthPix;
double m_dHeightPix;
double m_dDpiX;
double m_dDpiY;
Unit m_ePageUnits;
Aggplus::CMatrix m_oCoordTransform;
Aggplus::CMatrix m_oBaseTransform;
Aggplus::CMatrix m_oTransform;
Aggplus::CMatrix m_oFullTransform;
double m_dClipLeft;
double m_dClipTop;
double m_dClipWidth;
double m_dClipHeight;
CClipMulti m_oClip;
agg::svg::frame_buffer_rgba m_frame_buffer;
agg::svg::rasterizer m_rasterizer;
#ifdef _WINDOW_GRAPHIS_USE_
// для отрисовки картинок - используем Gdiplus
Gdiplus::Graphics* m_pGraphics;
Gdiplus::Bitmap* m_pBitmap;
CGdiPlusInit m_oInitGdiplus;
#endif
CDIB* m_pDib;
public:
agg::svg::frame_buffer_rgba& get_frame_buffer();
agg::svg::rasterizer& get_rasterizer();
bool m_bIntegerGrid;
double m_dGlobalAlpha;
// for RGBA painting
bool m_bSwapRGB;
public:
CGraphics();
CGraphics(int dwWidth, int dwHeight, int stride, BYTE* pBuffer);
CGraphics(CImage* pImage);
~CGraphics();
INT IsDib();
Status Create(BYTE* pPixels, int lWidth, int lHeight, int lStride, LONG lPitch);
Status Create2(BYTE* pPixels, int lWidth, int lHeight, int lStride, LONG lPitch, LONG x, LONG y, LONG w, LONG h, double dW, double dH, CDIB* pDib = NULL);
Status CreatePart(LONG lLeft, LONG lTop, LONG lWidth, LONG lHeight, CGraphics** ppPart);
double GetDpiX();
double GetDpiY();
Status SetDpiX(double dDpiX);
Status SetDpiY(double dDpiY);
Status SetPageWidth(double lWidth, LONG lUnit);
Status SetPageHeight(double lHeight, LONG lUnit);
Unit GetPageUnit();
Status SetPageUnit(Unit lUnits);
Aggplus::CMatrix* GetTransform();
Status SetTransform(CMatrix* pTransform);
Aggplus::CMatrix* GetBaseTransform();
Status SetBaseTransform(CMatrix* pTransform);
Status TranslateTransform(double x, double y, MatrixOrder order = MatrixOrderPrepend);
Status RotateTransform(double dAngle, MatrixOrder order = MatrixOrderPrepend);
Status ScaleTransform(double dScaleX, double dScaleY, MatrixOrder order = MatrixOrderPrepend);
Status ShearTransform(double shearX, double shearY, MatrixOrder order = MatrixOrderPrepend);
Status MultiplyTransform(CMatrix* pMatrix, MatrixOrder order = MatrixOrderPrepend);
// функции отсечения
Status SetClipRect(double dLeft, double dTop, double dWidth, double dHeight);
Status SetClipRect2(double dLeft, double dTop, double dWidth, double dHeight);
Status SetClipRect3(double dLeft, double dTop, double dWidth, double dHeight);
Status SetClip(CGraphicsPath* pPath);
Status ResetClip();
Status ExclugeClip(CGraphicsPath* pPath);
Status CombineClip(CGraphicsPath* pPath, agg::sbool_op_e op);
// измерение текста
INT MeasureString(const std::wstring& strText, CFontManager* pManager, double* lWidth, double* lHeight);
Status Clear(CColor oColor);
Status DrawArc(NSStructures::CPen* pPen, double x, double y, double width, double height, double startAngle, double sweepAngle);
Status DrawBezier(NSStructures::CPen* pPen, double x1, double y1, double x2, double y2, double x3, double y3, double x4, double y4);
Status DrawBeziers(NSStructures::CPen* pPen, double* pPoints, LONG lCount);
Status DrawCurve(NSStructures::CPen* pPen, double* pPoints, LONG lCount);
Status DrawLine(NSStructures::CPen* pPen, double x1, double y1, double x2, double y2);
Status DrawLines(NSStructures::CPen* pPen, double* pPoints, LONG lCount);
Status DrawRectangle(NSStructures::CPen* pPen, double x, double y, double width, double height);
Status DrawEllipse(NSStructures::CPen* pPen, double x, double y, double width, double height);
Status DrawPath(NSStructures::CPen* pPen, CGraphicsPath* pPath);
Status DrawPathNoTransform(NSStructures::CPen* pPen, CGraphicsPath* pPath);
// заливка
Status FillEllipse(CBrush* pBrush, double x, double y, double width, double height);
Status FillRectangle(CBrush* pBrush, double x, double y, double width, double height);
Status FillPolygon(CBrush* pBrush, double* pPoints, LONG lCount);
Status FillPath(CBrush* pBrush, CGraphicsPath* pPath);
// отрисовка картинки
Status DrawImage(CImage* pImage, double x, double y, double width, double height);
Status DrawMeta(const std::wstring& strFile, double x, double y, double width, double height);
#ifdef _WINDOWS_GDIPLUS_USE_
Status DrawGdiplusImage(Gdiplus::Bitmap* pImage, double x, double y, double width, double height);
#endif
INT DrawImageUnscaled(CImage* pImage, double x, double y);
// отрисовка текста
INT DrawString(const std::wstring& strText, CFontManager* pFont, CBrush* pBrush, double x, double y);
INT DrawStringC(const LONG& lText, CFontManager* pFont, CBrush* pBrush, double x, double y);
INT DrawStringPath(const std::wstring& strText, CFontManager* pFont, CBrush* pBrush, double x, double y);
INT DrawStringPathC(const LONG& lText, CFontManager* pFont, CBrush* pBrush, double x, double y);
void CalculateFullTransform();
bool IsClip();
inline Aggplus::CMatrix* GetFullTransform() { return &m_oFullTransform; }
inline Aggplus::CMatrix* GetCoordTransform() { return &m_oCoordTransform; }
inline double GetPixW() { return m_dWidthPix; }
inline double GetPixH() { return m_dHeightPix; }
protected:
template<class Renderer>
void render_scanlines(Renderer& ren);
template<class Rasterizer, class Renderer>
void render_scanlines(Rasterizer& ras, Renderer& ren);
void DoFillPathSolid(CColor dwColor);
void DoFillPathGradient(CBrushLinearGradient *pBrush);
void DoFillPathGradient2(CBrushLinearGradient *pBrush);
void DoFillPathHatch(CBrushHatch *pBrush);
void DoFillPathTextureClampSz(const CMatrix &mImgMtx, const void *pImgBuff, DWORD dwImgWidth, DWORD dwImgHeight, int nImgStride);
void DoFillPathTextureClampSz2(const CMatrix &mImgMtx, const void *pImgBuff, DWORD dwImgWidth, DWORD dwImgHeight, int nImgStride, BYTE Alpha = 255);
template<class ColorSpacePix>
void DoFillPathTextureClampSz3(const CMatrix &mImgMtx, const void *pImgBuff, DWORD dwImgWidth, DWORD dwImgHeight, int nImgStride, Aggplus::WrapMode wrapmode, BYTE Alpha = 255);
void DoFillPath(const CBrush* Brush);
// text methods
int FillGlyph2(int nX, int nY, TGlyph* pGlyph, Aggplus::CBrush* pBrush);
int FillGlyphSimple(int nX, int nY, LONG lWidth, LONG lHeight, BYTE* pData, Aggplus::CBrush* pBrush);
void PrepareScanlineStorage(agg::scanline_storage_aa8* storage, int x, int y, TGlyphBitmap *pGlyph);
void UpdateUnits();
};
}
#endif // _BUILD_GRAPHICS_H_
#include "GraphicsPath.h"
#ifndef max
#define max(a,b) (((a) > (b)) ? (a) : (b))
#endif
#ifndef min
#define min(a,b) (((a) < (b)) ? (a) : (b))
#endif
namespace Aggplus
{
// GraphicsPath
CGraphicsPath::CGraphicsPath() : ISimpleGraphicsPath()
{
m_bEvenOdd = false;
}
CGraphicsPath::~CGraphicsPath()
{
}
CGraphicsPath* CGraphicsPath::Clone()
{
CGraphicsPath* pNew = new CGraphicsPath();
pNew->m_agg_ps = m_agg_ps;
pNew->m_bEvenOdd = m_bEvenOdd;
return pNew;
}
Status CGraphicsPath::Reset()
{
m_agg_ps.remove_all();
m_bIsMoveTo = false;
return Ok;
}
void CGraphicsPath::SetRuler(bool bEvenOdd)
{
m_bEvenOdd = bEvenOdd;
}
Status CGraphicsPath::StartFigure()
{
m_agg_ps.start_new_path();
return Ok;
}
Status CGraphicsPath::CloseFigure()
{
m_agg_ps.close_polygon();
return Ok;
}
bool CGraphicsPath::Is_poly_closed()
{
if (!m_agg_ps.total_vertices())
return true;
double x, y;
unsigned int nTip = m_agg_ps.last_vertex(&x, &y);
if (nTip & agg::path_flags_close)
return true;
return false;
}
Status CGraphicsPath::MoveTo(double x, double y)
{
m_bIsMoveTo = true;
m_agg_ps.move_to(x, y);
return Ok;
}
Status CGraphicsPath::LineTo(double x, double y)
{
m_agg_ps.line_to(x, y);
return Ok;
}
Status CGraphicsPath::CurveTo(double x1, double y1, double x2, double y2, double x3, double y3)
{
m_agg_ps.curve4(x1, y1, x2, y2, x3, y3);
return Ok;
}
Status CGraphicsPath::AddLine(double x1, double y1, double x2, double y2)
{
if (Is_poly_closed())
{
m_agg_ps.move_to(x1, y1);
}
else
{
m_agg_ps.line_to(x1, y1);
}
m_agg_ps.line_to(x2, y2);
return Ok;
}
Status CGraphicsPath::AddLines(double* pPoints, int nCount)
{
if (4 > nCount)
{
return InvalidParameter;
}
int nRet = 0;
if (!m_bIsMoveTo)
{
MoveTo(pPoints[0], pPoints[1]);
}
/*if (Is_poly_closed())
{
m_agg_ps.move_to((double)pPoints[0], (double)pPoints[1]);
}
else
{
m_agg_ps.line_to((double)pPoints[0], (double)pPoints[1]);
}*/
int n = (nCount / 2) - 1;
for (int i = 1; i <= n; ++i)
{
const double* points = &pPoints[i * 2];
m_agg_ps.line_to(points[0], points[1]);
}
return Ok;
}
Status CGraphicsPath::AddBezier(double x1, double y1, double x2, double y2, double x3, double y3, double x4, double y4)
{
if (Is_poly_closed())
m_agg_ps.move_to(x1, y1);
else
m_agg_ps.line_to(x1, y1);
m_agg_ps.curve4(x2, y2, x3, y3, x4, y4);
return Ok;
}
Status CGraphicsPath::AddBeziers(double* pPoints, int nCount)
{
if (8 > nCount)
return InvalidParameter;
if (!m_bIsMoveTo)
{
MoveTo(pPoints[0], pPoints[1]);
}
const double* points = pPoints;
agg::curve4 curve;
curve.approximation_method(agg::curve_inc);
curve.approximation_scale(25.0);
curve.init(points[0], points[1], points[2], points[3], points[4], points[5], points[6], points[7]);
if (Is_poly_closed())
{
m_agg_ps.concat_path(curve, 0);
}
else
{
m_agg_ps.join_path(curve, 0);
}
int nCountTo = (nCount - 8) / 6;
for (int i = 0; i < nCountTo; ++i)
{
points = pPoints + 8 + 6 * i;
CurveTo(points[0], points[1], points[2], points[3], points[4], points[5]);
}
return Ok;
}
Status CGraphicsPath::AddCurve(double* pPoints, int nCount)
{
// этим мы не пользуемся. Понадобится - реализую.
return AddBeziers(pPoints, nCount);
}
Status CGraphicsPath::AddEllipse(double x, double y, double width, double height)
{
agg::bezier_arc arc(x+width/2.0, y+height/2.0, width/2.0, height/2.0, 0.0, agg::pi2);
//2.3 m_agg_ps.add_path(arc, 0, true);
m_agg_ps.join_path(arc, 0);
return Ok;
}
Status CGraphicsPath::AddRectangle(double x, double y, double width, double height)
{
m_agg_ps.move_to(x, y);
m_agg_ps.line_to(x + width, y);
m_agg_ps.line_to(x + width, y + height);
m_agg_ps.line_to(x, y + height);
m_agg_ps.close_polygon();
return Ok;
}
Status CGraphicsPath::AddPolygon(double* pPoints, int nCount)
{
if (2 > nCount)
{
return InvalidParameter;
}
int nRet = 0;
if (Is_poly_closed())
{
m_agg_ps.move_to(pPoints[0], pPoints[1]);
}
else
{
m_agg_ps.line_to(pPoints[0], pPoints[1]);
}
int n = (nCount / 2) - 1;
for (int i = 1; i < n; ++i)
{
double* points = &pPoints[i * 2];
m_agg_ps.line_to(points[0], points[1]);
}
m_agg_ps.close_polygon();
return Ok;
}
Status CGraphicsPath::AddPath(const CGraphicsPath& oPath)
{
typedef agg::conv_curve<agg::path_storage> conv_crv_type;
agg::path_storage p_copy(oPath.m_agg_ps);
conv_crv_type p3(p_copy);
m_agg_ps.join_path(p3, 0);
return Ok;
}
Status CGraphicsPath::AddArc(double x, double y, double width, double height, double startAngle, double sweepAngle)
{
if(sweepAngle >= 360.0)
{
sweepAngle = 360;
}
agg::bezier_arc arc(x+width/2.00, y+height/2.00, width/2.00, height/2.00, agg::deg2rad(startAngle), agg::deg2rad(sweepAngle));
//2.3 m_agg_ps.add_path(arc, 0, !z_is_poly_closed());
if (Is_poly_closed())
{
m_agg_ps.concat_path(arc, 0);
}
else
{
m_agg_ps.join_path(arc, 0);
}
return Ok;
}
ULONG CGraphicsPath::GetPointCount() const
{
ULONG nPointCount=0;
ULONG nTotal = m_agg_ps.total_vertices();
double x, y;
for(ULONG i = 0; i < nTotal; ++i)
{
ULONG nTip = m_agg_ps.vertex(i, &x, &y);
if(nTip)
{
if (!(nTip & agg::path_flags_close))
{
++nPointCount;
}
}
}
return nPointCount;
}
Status CGraphicsPath::GetPathPoints(PointF* points, int count) const
{
int nTotal = m_agg_ps.total_vertices();
double x, y;
int i = 0, k = 0;
while (k < count && i < nTotal)
{
unsigned int nTip = m_agg_ps.vertex(i, &x, &y);
if (nTip)
{
if(!(nTip & agg::path_flags_close))
{
points[k].X = REAL(x);
points[k].Y = REAL(y);
++k;
}
}
++i;
}
return Ok;
}
Status CGraphicsPath::GetLastPoint(double& x, double& y)
{
m_agg_ps.last_vertex(&x, &y);
return Ok;
}
Status CGraphicsPath::GetPathPoints(double* points, int count) const
{
int nTotal = m_agg_ps.total_vertices();
double x, y;
int i = 0, k = 0;
while (k < count && i < nTotal)
{
unsigned int nTip = m_agg_ps.vertex(i, &x, &y);
if (nTip)
{
if(!(nTip & agg::path_flags_close))
{
points[2 * k] = x;
points[2 * k + 1] = y;
++k;
}
}
++i;
}
return Ok;
}
void CGraphicsPath::GetBounds(double& left, double& top, double& width, double& height)
{
unsigned int nTotal = m_agg_ps.total_vertices();
if (nTotal)
{
agg::rect_d bounds(1e100, 1e100, -1e100, -1e100);
double x, y;
for(unsigned int i = 0; i < nTotal; i++)
{
unsigned int nTip = m_agg_ps.vertex(i, &x, &y);
if(agg::is_vertex(nTip))
{
if(x < bounds.x1) bounds.x1 = x;
if(y < bounds.y1) bounds.y1 = y;
if(x > bounds.x2) bounds.x2 = x;
if(y > bounds.y2) bounds.y2 = y;
}
}
left = bounds.x1;
top = bounds.y1;
width = (bounds.x2 - bounds.x1);
height = (bounds.y2 - bounds.y1);
}
else
{
left = 0;
top = 0;
width = 0;
height = 0;
}
}
Status CGraphicsPath::Transform(const CMatrix* matrix)
{
if (NULL != matrix)
{
agg::path_storage p2(m_agg_ps);
agg::conv_transform<agg::path_storage> trans(p2, matrix->m_agg_mtx);
m_agg_ps.remove_all();
//2.3 m_agg_ps.add_path(trans, 0, false);
m_agg_ps.concat_path(trans, 0);
}
return Ok;
}
bool CGraphicsPath::_MoveTo(double x, double y)
{
return (Ok == MoveTo(x, y));
}
bool CGraphicsPath::_LineTo(double x, double y)
{
return (Ok == LineTo(x, y));
}
bool CGraphicsPath::_CurveTo(double x1, double y1, double x2, double y2, double x3, double y3)
{
return (Ok == CurveTo(x1, y1, x2, y2, x3, y3));
}
bool CGraphicsPath::_Close()
{
return (Ok == CloseFigure());
}
Status CGraphicsPath::AddString(const std::wstring& strText, CFontManager* pFont, double x, double y)
{
if (NULL == pFont)
return InvalidParameter;
pFont->LoadString1(strText, (float)x, (float)y);
return (TRUE == pFont->GetStringPath(this)) ? Ok : InvalidParameter;
}
Status CGraphicsPath::AddStringC(const LONG& lText, CFontManager* pFont, double x, double y)
{
if (NULL == pFont)
return InvalidParameter;
std::wstring strText((wchar_t)lText, 1);
pFont->LoadString1(strText, (float)x, (float)y);
return (TRUE == pFont->GetStringPath(this)) ? Ok : InvalidParameter;
}
void CGraphicsPath::z_Stroke(const NSStructures::CPen* Pen)
{
if (NULL == Pen)
return;
typedef agg::conv_stroke<agg::path_storage> Path_Conv_Stroke;
Path_Conv_Stroke pg(m_agg_ps);
pg.line_join(agg::round_join);
pg.line_cap(agg::round_cap);
pg.approximation_scale(25.00);
//pg.miter_limit(0.50);
pg.width(Pen->Size);
//pg.auto_detect_orientation(true);
agg::path_storage psNew;
//2.3 psNew.add_path(pg, 0, false);
psNew.concat_path(pg, 0);
m_agg_ps = psNew;
}
void CGraphicsPath::Widen(const NSStructures::CPen* Pen, const CMatrix* matrix, float flatness)
{
if (NULL == Pen || NULL == matrix || 0.0f == flatness)
return;
typedef agg::conv_curve<agg::path_storage> conv_crv_type;
typedef agg::conv_contour<conv_crv_type> Path_Conv_Contour;
conv_crv_type crv(m_agg_ps);
Path_Conv_Contour pg(crv);
pg.miter_limit(0.50);
//pg.miter_limit_theta(0.05);
//pg.approximation_scale(2.00);
pg.width(Pen->Size);
agg::line_join_e LineJoin;
switch (Pen->LineJoin)
{
case LineJoinMiter : LineJoin=agg::miter_join; break;
case LineJoinBevel : LineJoin=agg::bevel_join; break;
default:
case LineJoinRound : LineJoin=agg::round_join; break;
case LineJoinMiterClipped: LineJoin=agg::miter_join_revert; break;
}
pg.line_join(LineJoin);
pg.auto_detect_orientation(false);
agg::path_storage psNew;
//2.3 psNew.add_path(pg, 0, false);
//m_agg_ps.concat_path(pg, 0);
m_agg_ps.concat_path(pg, 0);
m_agg_ps = psNew;
}
agg::path_storage* CGraphicsPath::z_get_agg_path_storage()
{
return &m_agg_ps;
}
int CGraphicsPath::EllipseArc(double fX, double fY, double fXRad, double fYRad, double fAngle1, double fAngle2, INT bClockDirection)
{
int nRet = 0;
while ( fAngle1 < 0 )
fAngle1 += 360;
while ( fAngle1 > 360 )
fAngle1 -= 360;
while ( fAngle2 < 0 )
fAngle2 += 360;
while ( fAngle2 >= 360 )
fAngle2 -= 360;
if ( !bClockDirection )
{
if ( fAngle1 <= fAngle2 )
nRet = EllipseArc2( fX, fY, fXRad, fYRad, fAngle1, fAngle2, FALSE );
else
{
nRet += EllipseArc2( fX, fY, fXRad, fYRad, fAngle1, 360, FALSE );
nRet += EllipseArc2( fX, fY, fXRad, fYRad, 0, fAngle2, FALSE );
}
}
else
{
if ( fAngle1 >= fAngle2 )
nRet = EllipseArc2( fX, fY, fXRad, fYRad, fAngle1, fAngle2, TRUE );
else
{
nRet += EllipseArc2( fX, fY, fXRad, fYRad, fAngle1, 0, TRUE );
nRet += EllipseArc2( fX, fY, fXRad, fYRad, 360, fAngle2, TRUE );
}
}
return nRet;
}
double CGraphicsPath::AngToEllPrm(double fAngle, double fXRad, double fYRad)
{
// Функция для перевода реального угла в параметрическое задание эллписа
// т.е. x= a cos(t) y = b sin(t) - параметрическое задание эллписа.
// x = r cos(p), y = r sin(p) => t = atan2( sin(p) / b, cos(p) / a );
return atan2( sin( fAngle ) / fYRad, cos( fAngle ) / fXRad );
}
int CGraphicsPath::EllipseArc2(double fX, double fY, double fXRad, double fYRad, double fAngle1, double fAngle2, INT bClockDirection)
{
// переведем углы в радианы
int nRet = 0;
double dAngle1 = fAngle1 * 3.141592 / 180;
double dAngle2 = fAngle2 * 3.141592 / 180;
// Выясним в каких четвертях находятся начальная и конечная точки
unsigned int nFirstPointQuard = int(fAngle1) / 90 + 1;
unsigned int nSecondPointQuard = int(fAngle2) / 90 + 1;
nSecondPointQuard = min( 4, max( 1, nSecondPointQuard ) );
nFirstPointQuard = min( 4, max( 1, nFirstPointQuard ) );
// Проведем линию в начальную точку дуги
double fStartX = 0.0, fStartY = 0.0, fEndX = 0.0, fEndY = 0.0;
fStartX = fX + fXRad * cos( AngToEllPrm( dAngle1, fXRad, fYRad ) );
fStartY = fY + fYRad * sin( AngToEllPrm( dAngle1, fXRad, fYRad ) );
LineTo(fStartX, fStartY);
// Дальше рисуем по четверям
double fCurX = fStartX, fCurY = fStartY;
double dStartAngle = dAngle1;
double dEndAngle = 0;
if ( !bClockDirection )
{
for( unsigned int nIndex = nFirstPointQuard; nIndex <= nSecondPointQuard; nIndex++ )
{
if ( nIndex == nSecondPointQuard )
dEndAngle = dAngle2;
else
dEndAngle = (90 * (nIndex ) ) * 3.141592f / 180;
if ( !( nIndex == nFirstPointQuard ) )
dStartAngle = (90 * (nIndex - 1 ) ) * 3.141592f / 180;
EllipseArc3(fX, fY, fXRad, fYRad, AngToEllPrm( dStartAngle, fXRad, fYRad ), AngToEllPrm( dEndAngle, fXRad, fYRad ), &fEndX, &fEndY, FALSE);
}
}
else
{
for( unsigned int nIndex = nFirstPointQuard; nIndex >= nSecondPointQuard; nIndex-- )
{
if ( nIndex == nFirstPointQuard )
dStartAngle = dAngle1;
else
dStartAngle = (90 * (nIndex ) ) * 3.141592f / 180;
if ( !( nIndex == nSecondPointQuard ) )
dEndAngle = (90 * (nIndex - 1 ) ) * 3.141592f / 180;
else
dEndAngle = dAngle2;
EllipseArc3(fX, fY, fXRad, fYRad, AngToEllPrm( dStartAngle, fXRad, fYRad ), AngToEllPrm( dEndAngle, fXRad, fYRad ), &fEndX, &fEndY, FALSE);
}
}
return nRet;
}
int CGraphicsPath::EllipseArc3(double fX, double fY, double fXRad, double fYRad, double dAngle1, double dAngle2, double *pfXCur, double *pfYCur, INT bClockDirection)
{
// Рассчитаем начальную, конечную и контрольные точки
double fX1 = 0.0, fX2 = 0.0, fY1 = 0.0, fY2 = 0.0;
double fCX1 = 0.0, fCX2 = 0.0, fCY1 = 0.0, fCY2 = 0.0;
double fAlpha = sin( dAngle2 - dAngle1 ) * ( sqrt( 4.0 + 3.0 * tan( (dAngle2 - dAngle1) / 2.0 ) * tan( (dAngle2 - dAngle1) / 2.0 ) ) - 1.0 ) / 3.0;
double fKoef = 1;
fX1 = fX + fXRad * cos( dAngle1 );
fY1 = fY + fYRad * sin( dAngle1 );
fX2 = fX + fXRad * cos( dAngle2 );
fY2 = fY + fYRad * sin( dAngle2 );
fCX1 = fX1 - fAlpha * fXRad * sin ( dAngle1 );
fCY1 = fY1 + fAlpha * fYRad * cos ( dAngle1 );
fCX2 = fX2 + fAlpha * fXRad * sin ( dAngle2 );
fCY2 = fY2 - fAlpha * fYRad * cos ( dAngle2 );
if ( !bClockDirection )
{
CurveTo(fCX1, fCY1, fCX2, fCY2, fX2, fY2);
*pfXCur = fX2;
*pfYCur = fY2;
}
else
{
CurveTo(fCX2, fCY2, fCX1, fCY1, fX1, fY1);
*pfXCur = fX1;
*pfYCur = fY1;
}
return 0;
}
int CGraphicsPath::Ellipse(double fX, double fY, double fXRad, double fYRad)
{
MoveTo(fX - fXRad, fY);
double c_fKappa = 0.552;
CurveTo(fX - fXRad, fY + fYRad * c_fKappa, fX - fXRad * c_fKappa, fY + fYRad, fX, fY + fYRad);
CurveTo(fX + fXRad * c_fKappa, fY + fYRad, fX + fXRad, fY + fYRad * c_fKappa, fX + fXRad, fY);
CurveTo(fX + fXRad, fY - fYRad * c_fKappa, fX + fXRad * c_fKappa, fY - fYRad, fX, fY - fYRad);
CurveTo(fX - fXRad * c_fKappa, fY - fYRad, fX - fXRad, fY - fYRad * c_fKappa, fX - fXRad, fY);
return 0;
}
Status CGraphicsPath::AddArc2(double fX, double fY, double fWidth, double fHeight, double fStartAngle, double fSweepAngle)
{
if (0 >= fWidth || 0 >= fHeight)
return InvalidParameter;
if ( Is_poly_closed() )
{
double dStartAngle = fStartAngle * agg::pi / 180;
double fStartX = fX + fWidth / 2.0 + fWidth / 2 * cos( AngToEllPrm( dStartAngle, fWidth / 2, fHeight / 2 ) );
double fStartY = fY + fHeight / 2.0 - fHeight / 2 * sin( AngToEllPrm ( dStartAngle, fWidth / 2, fHeight / 2 ) );
// В случае, когда эллипс рисуется целиком используется команда AppendEllipse, в которой команда MoveTo уже есть
if ( fSweepAngle < 360 )
if ( Ok != MoveTo( fStartX, fStartY ) )
return GenericError;
}
INT bClockDirection = FALSE;
double fEndAngle = 360 - ( fSweepAngle + fStartAngle );
double fSrtAngle = 360 - fStartAngle;
if( fSweepAngle > 0 )
bClockDirection = TRUE;
if( fabs(fSweepAngle) >= 360 ) // Целый эллипс
{
return (0 == Ellipse(fX + fWidth / 2, fY + fHeight / 2, fWidth / 2, fHeight / 2)) ? Ok : GenericError;
}
else // Дуга эллипса
{
return (0 == EllipseArc(fX + fWidth / 2, fY + fHeight / 2, fWidth / 2, fHeight / 2, fSrtAngle, fEndAngle, bClockDirection)) ? Ok : GenericError;
}
return Ok;
}
// Converter
CGraphicsPathSimpleConverter::CGraphicsPathSimpleConverter()
{
m_pRenderer = NULL;
m_bEvenOdd = false;
m_bIsMoveTo = false;
m_bIsClosed = false;
}
CGraphicsPathSimpleConverter::~CGraphicsPathSimpleConverter()
{
RELEASEINTERFACE(m_pRenderer);
}
void CGraphicsPathSimpleConverter::SetRenderer(IRenderer* pRenderer)
{
RELEASEINTERFACE(m_pRenderer);
m_pRenderer = pRenderer;
ADDREFINTERFACE(m_pRenderer);
}
IRenderer* CGraphicsPathSimpleConverter::GetRenderer(INT bIsAddref)
{
if (bIsAddref)
{
ADDREFINTERFACE(m_pRenderer);
}
return m_pRenderer;
}
bool CGraphicsPathSimpleConverter::PathCommandMoveTo(double fX, double fY)
{
return _MoveTo(fX, fY);
}
bool CGraphicsPathSimpleConverter::PathCommandLineTo(double fX, double fY)
{
return _LineTo(fX, fY);
}
bool CGraphicsPathSimpleConverter::PathCommandLinesTo(double* pPoints, LONG lCount)
{
if (NULL == pPoints)
return false;
double* pData = pPoints;
if (2 == lCount)
{
return _LineTo(pData[0], pData[1]);
}
if (4 > lCount)
{
return false;
}
int nRet = 0;
if (!m_bIsMoveTo)
{
_MoveTo(pData[0], pData[1]);
}
int n = (lCount / 2) - 1;
for (int i = 1; i <= n; ++i)
{
double* points = &pData[i * 2];
_LineTo(points[0], points[1]);
}
return true;
}
bool CGraphicsPathSimpleConverter::PathCommandCurveTo(double fX1, double fY1, double fX2, double fY2, double fX3, double fY3)
{
return _CurveTo(fX1, fY1, fX2, fY2, fX3, fY3);
}
bool CGraphicsPathSimpleConverter::PathCommandCurvesTo(double* pData, LONG lCount)
{
if (NULL == pData)
return false;
if (8 > lCount)
return false;
if (!m_bIsMoveTo)
{
_MoveTo(pData[0], pData[1]);
pData += 2;
lCount -= 2;
}
else
{
_LineTo(pData[0], pData[1]);
pData += 2;
lCount -= 2;
}
double* points = pData;
int nCountTo = (lCount) / 6;
for (int i = 0; i < nCountTo; ++i)
{
points = pData + 6 * i;
_CurveTo(points[0], points[1], points[2], points[3], points[4], points[5]);
}
return true;
}
bool CGraphicsPathSimpleConverter::PathCommandArcTo(double fX, double fY, double fWidth, double fHeight, double fStartAngle, double fSweepAngle)
{
return AddArc(fX, fY, fWidth, fHeight, -fStartAngle, -fSweepAngle);
}
bool CGraphicsPathSimpleConverter::PathCommandClose()
{
return _Close();
}
bool CGraphicsPathSimpleConverter::PathCommandEnd()
{
return _Reset();
}
bool CGraphicsPathSimpleConverter::PathCommandStart()
{
return _Start();
}
bool CGraphicsPathSimpleConverter::PathCommandGetCurrentPoint(double* fX, double* fY)
{
m_agg_ps.last_vertex(fX, fY);
return true;
}
bool CGraphicsPathSimpleConverter::PathCommandText(const std::wstring& bsText, CFontManager* pManager, double fX, double fY, double fWidth, double fHeight, double fBaseLineOffset)
{
return AddString(bsText, pManager, fX, fY + fBaseLineOffset);
}
bool CGraphicsPathSimpleConverter::PathCommandTextEx(std::wstring& bsText, std::wstring& bsGidText, CFontManager* pManager, double fX, double fY, double fWidth, double fHeight, double fBaseLineOffset, DWORD lFlags)
{
if (!bsGidText.empty())
{
return PathCommandText(bsGidText, pManager, fX, fY, fWidth, fHeight, fBaseLineOffset);
}
return PathCommandText(bsText, pManager, fX, fY, fWidth, fHeight, fBaseLineOffset);
}
bool CGraphicsPathSimpleConverter::PathCommandGetBounds(double& left, double& top, double& width, double &height)
{
unsigned int nTotal = m_agg_ps.total_vertices();
if (nTotal)
{
agg::rect_d bounds(1e100, 1e100, -1e100, -1e100);
double x, y;
for(unsigned int i = 0; i < nTotal; i++)
{
unsigned int nTip = m_agg_ps.vertex(i, &x, &y);
if(agg::is_vertex(nTip))
{
if(x < bounds.x1) bounds.x1 = x;
if(y < bounds.y1) bounds.y1 = y;
if(x > bounds.x2) bounds.x2 = x;
if(y > bounds.y2) bounds.y2 = y;
}
}
left = bounds.x1;
top = bounds.y1;
width = (bounds.x2 - bounds.x1);
height = (bounds.y2 - bounds.y1);
}
else
{
left = 0;
top = 0;
width = 0;
height = 0;
}
return true;
}
bool CGraphicsPathSimpleConverter::_MoveTo(double x, double y)
{
m_bIsMoveTo = true;
m_agg_ps.move_to(x, y);
if (NULL != m_pRenderer)
{
m_pRenderer->BeginCommand(c_nSimpleGraphicType);
m_pRenderer->PathCommandMoveTo(x, y);
m_pRenderer->EndCommand(c_nSimpleGraphicType);
}
return true;
}
bool CGraphicsPathSimpleConverter::_LineTo(double x, double y)
{
if (!m_bIsMoveTo)
{
_MoveTo(x, y);
}
m_agg_ps.line_to(x, y);
if (NULL != m_pRenderer)
{
m_pRenderer->BeginCommand(c_nSimpleGraphicType);
m_pRenderer->PathCommandLineTo(x, y);
m_pRenderer->EndCommand(c_nSimpleGraphicType);
}
return true;
}
bool CGraphicsPathSimpleConverter::_CurveTo(double x1, double y1, double x2, double y2, double x3, double y3)
{
if (!m_bIsMoveTo)
{
_MoveTo(x1, y1);
}
m_agg_ps.curve4(x1, y1, x2, y2, x3, y3);
if (NULL != m_pRenderer)
{
m_pRenderer->BeginCommand(c_nSimpleGraphicType);
m_pRenderer->PathCommandCurveTo(x1, y1, x2, y2, x3, y3);
m_pRenderer->EndCommand(c_nSimpleGraphicType);
}
return true;
}
bool CGraphicsPathSimpleConverter::_Close()
{
m_bIsClosed = true;
m_agg_ps.close_polygon();
if (NULL != m_pRenderer)
{
m_pRenderer->BeginCommand(c_nSimpleGraphicType);
m_pRenderer->PathCommandClose();
m_pRenderer->EndCommand(c_nSimpleGraphicType);
}
return true;
}
bool CGraphicsPathSimpleConverter::_Reset()
{
m_bEvenOdd = false;
m_bIsMoveTo = false;
m_bIsClosed = false;
m_agg_ps.remove_all();
if (NULL != m_pRenderer)
{
m_pRenderer->BeginCommand(c_nSimpleGraphicType);
m_pRenderer->PathCommandEnd();
m_pRenderer->EndCommand(c_nSimpleGraphicType);
}
return true;
}
bool CGraphicsPathSimpleConverter::_Start()
{
m_agg_ps.start_new_path();
if (NULL != m_pRenderer)
{
m_pRenderer->BeginCommand(c_nSimpleGraphicType);
m_pRenderer->PathCommandStart();
m_pRenderer->EndCommand(c_nSimpleGraphicType);
}
return true;
}
bool CGraphicsPathSimpleConverter::AddString(const std::wstring& bstrText, CFontManager* pFont, double x, double y)
{
if (NULL == pFont)
return false;
pFont->LoadString1(bstrText, (float)x, (float)y);
return (TRUE == pFont->GetStringPath(this)) ? true : false;
}
int CGraphicsPathSimpleConverter::EllipseArc(double fX, double fY, double fXRad, double fYRad, double fAngle1, double fAngle2, INT bClockDirection)
{
int nRet = 0;
while ( fAngle1 < 0 )
fAngle1 += 360;
while ( fAngle1 > 360 )
fAngle1 -= 360;
while ( fAngle2 < 0 )
fAngle2 += 360;
while ( fAngle2 >= 360 )
fAngle2 -= 360;
if ( !bClockDirection )
{
if ( fAngle1 <= fAngle2 )
nRet = EllipseArc2( fX, fY, fXRad, fYRad, fAngle1, fAngle2, FALSE );
else
{
nRet += EllipseArc2( fX, fY, fXRad, fYRad, fAngle1, 360, FALSE );
nRet += EllipseArc2( fX, fY, fXRad, fYRad, 0, fAngle2, FALSE );
}
}
else
{
if ( fAngle1 >= fAngle2 )
nRet = EllipseArc2( fX, fY, fXRad, fYRad, fAngle1, fAngle2, TRUE );
else
{
nRet += EllipseArc2( fX, fY, fXRad, fYRad, fAngle1, 0, TRUE );
nRet += EllipseArc2( fX, fY, fXRad, fYRad, 360, fAngle2, TRUE );
}
}
return nRet;
}
double CGraphicsPathSimpleConverter::AngToEllPrm(double fAngle, double fXRad, double fYRad)
{
// Функция для перевода реального угла в параметрическое задание эллписа
// т.е. x= a cos(t) y = b sin(t) - параметрическое задание эллписа.
// x = r cos(p), y = r sin(p) => t = atan2( sin(p) / b, cos(p) / a );
return atan2( sin( fAngle ) / fYRad, cos( fAngle ) / fXRad );
}
int CGraphicsPathSimpleConverter::EllipseArc2(double fX, double fY, double fXRad, double fYRad, double fAngle1, double fAngle2, INT bClockDirection)
{
// переведем углы в радианы
int nRet = 0;
double dAngle1 = fAngle1 * 3.141592 / 180;
double dAngle2 = fAngle2 * 3.141592 / 180;
// Выясним в каких четвертях находятся начальная и конечная точки
unsigned int nFirstPointQuard = int(fAngle1) / 90 + 1;
unsigned int nSecondPointQuard = int(fAngle2) / 90 + 1;
nSecondPointQuard = min( 4, max( 1, nSecondPointQuard ) );
nFirstPointQuard = min( 4, max( 1, nFirstPointQuard ) );
// Проведем линию в начальную точку дуги
double fStartX = 0.0, fStartY = 0.0, fEndX = 0.0, fEndY = 0.0;
fStartX = fX + fXRad * cos( AngToEllPrm( dAngle1, fXRad, fYRad ) );
fStartY = fY + fYRad * sin( AngToEllPrm( dAngle1, fXRad, fYRad ) );
_LineTo(fStartX, fStartY);
// Дальше рисуем по четверям
double fCurX = fStartX, fCurY = fStartY;
double dStartAngle = dAngle1;
double dEndAngle = 0;
if ( !bClockDirection )
{
for( unsigned int nIndex = nFirstPointQuard; nIndex <= nSecondPointQuard; nIndex++ )
{
if ( nIndex == nSecondPointQuard )
dEndAngle = dAngle2;
else
dEndAngle = (90 * (nIndex ) ) * 3.141592f / 180;
if ( !( nIndex == nFirstPointQuard ) )
dStartAngle = (90 * (nIndex - 1 ) ) * 3.141592f / 180;
EllipseArc3(fX, fY, fXRad, fYRad, AngToEllPrm( dStartAngle, fXRad, fYRad ), AngToEllPrm( dEndAngle, fXRad, fYRad ), &fEndX, &fEndY, FALSE);
}
}
else
{
for( unsigned int nIndex = nFirstPointQuard; nIndex >= nSecondPointQuard; nIndex-- )
{
if ( nIndex == nFirstPointQuard )
dStartAngle = dAngle1;
else
dStartAngle = (90 * (nIndex ) ) * 3.141592f / 180;
if ( !( nIndex == nSecondPointQuard ) )
dEndAngle = (90 * (nIndex - 1 ) ) * 3.141592f / 180;
else
dEndAngle = dAngle2;
EllipseArc3(fX, fY, fXRad, fYRad, AngToEllPrm( dStartAngle, fXRad, fYRad ), AngToEllPrm( dEndAngle, fXRad, fYRad ), &fEndX, &fEndY, FALSE);
}
}
return nRet;
}
int CGraphicsPathSimpleConverter::EllipseArc3(double fX, double fY, double fXRad, double fYRad, double dAngle1, double dAngle2, double *pfXCur, double *pfYCur, INT bClockDirection)
{
// Рассчитаем начальную, конечную и контрольные точки
double fX1 = 0.0, fX2 = 0.0, fY1 = 0.0, fY2 = 0.0;
double fCX1 = 0.0, fCX2 = 0.0, fCY1 = 0.0, fCY2 = 0.0;
double fAlpha = sin( dAngle2 - dAngle1 ) * ( sqrt( 4.0 + 3.0 * tan( (dAngle2 - dAngle1) / 2.0 ) * tan( (dAngle2 - dAngle1) / 2.0 ) ) - 1.0 ) / 3.0;
double fKoef = 1;
fX1 = fX + fXRad * cos( dAngle1 );
fY1 = fY + fYRad * sin( dAngle1 );
fX2 = fX + fXRad * cos( dAngle2 );
fY2 = fY + fYRad * sin( dAngle2 );
fCX1 = fX1 - fAlpha * fXRad * sin ( dAngle1 );
fCY1 = fY1 + fAlpha * fYRad * cos ( dAngle1 );
fCX2 = fX2 + fAlpha * fXRad * sin ( dAngle2 );
fCY2 = fY2 - fAlpha * fYRad * cos ( dAngle2 );
if ( !bClockDirection )
{
_CurveTo(fCX1, fCY1, fCX2, fCY2, fX2, fY2);
*pfXCur = fX2;
*pfYCur = fY2;
}
else
{
_CurveTo(fCX2, fCY2, fCX1, fCY1, fX1, fY1);
*pfXCur = fX1;
*pfYCur = fY1;
}
return 0;
}
int CGraphicsPathSimpleConverter::Ellipse(double fX, double fY, double fXRad, double fYRad)
{
_MoveTo(fX - fXRad, fY);
double c_fKappa = 0.552;
_CurveTo(fX - fXRad, fY + fYRad * c_fKappa, fX - fXRad * c_fKappa, fY + fYRad, fX, fY + fYRad);
_CurveTo(fX + fXRad * c_fKappa, fY + fYRad, fX + fXRad, fY + fYRad * c_fKappa, fX + fXRad, fY);
_CurveTo(fX + fXRad, fY - fYRad * c_fKappa, fX + fXRad * c_fKappa, fY - fYRad, fX, fY - fYRad);
_CurveTo(fX - fXRad * c_fKappa, fY - fYRad, fX - fXRad, fY - fYRad * c_fKappa, fX - fXRad, fY);
return 0;
}
bool CGraphicsPathSimpleConverter::AddArc(double fX, double fY, double fWidth, double fHeight, double fStartAngle, double fSweepAngle)
{
if (0 >= fWidth || 0 >= fHeight)
return false;
if ( Is_poly_closed() )
{
double dStartAngle = fStartAngle * agg::pi / 180;
double fStartX = fX + fWidth / 2.0 + fWidth / 2 * cos( AngToEllPrm( dStartAngle, fWidth / 2, fHeight / 2 ) );
double fStartY = fY + fHeight / 2.0 - fHeight / 2 * sin( AngToEllPrm ( dStartAngle, fWidth / 2, fHeight / 2 ) );
// В случае, когда эллипс рисуется целиком используется команда AppendEllipse, в которой команда MoveTo уже есть
if ( fSweepAngle < 360 )
if ( false == _MoveTo( fStartX, fStartY ) )
return false;
}
INT bClockDirection = FALSE;
double fEndAngle = 360 - ( fSweepAngle + fStartAngle );
double fSrtAngle = 360 - fStartAngle;
if( fSweepAngle > 0 )
bClockDirection = TRUE;
if( fabs(fSweepAngle) >= 360 ) // Целый эллипс
{
return (0 == Ellipse(fX + fWidth / 2, fY + fHeight / 2, fWidth / 2, fHeight / 2)) ? true : false;
}
else // Дуга эллипса
{
return (0 == EllipseArc(fX + fWidth / 2, fY + fHeight / 2, fWidth / 2, fHeight / 2, fSrtAngle, fEndAngle, bClockDirection)) ? true : false;
}
return Ok;
}
bool CGraphicsPathSimpleConverter::Is_poly_closed()
{
if (!m_agg_ps.total_vertices())
return true;
double x, y;
unsigned int nTip = m_agg_ps.last_vertex(&x, &y);
if (nTip & agg::path_flags_close)
return true;
return false;
}
}
\ No newline at end of file
#ifndef _BUILD_GRAPHICSPATH_H_
#define _BUILD_GRAPHICSPATH_H_
#include "AggPlusEnums.h"
#include "../agg-2.4/include/agg_basics.h"
#include "../agg-2.4/include/agg_path_storage.h"
#include "../agg-2.4/include/agg_rasterizer_scanline_aa.h"
#include "../agg-2.4/include/agg_conv_transform.h"
#include "../agg-2.4/include/agg_conv_stroke.h"
#include "../agg-2.4/include/agg_conv_contour.h"
#include "../agg-2.4/include/agg_conv_unclose_polygon.h"
#include "../agg-2.4/include/agg_bezier_arc.h"
#include "../agg-2.4/include/agg_conv_curve.h"
#include "../agg-2.4/include/agg_renderer_base.h"
#include "../agg-2.4/include/agg_renderer_scanline.h"
#include "IRenderer.h"
#include "Matrix.h"
#include "structures.h"
#include "../fontengine/FontManager.h"
namespace Aggplus
{
class CGraphicsPath : public ISimpleGraphicsPath
{
friend class CClip;
friend class CFontManager;
friend class CGraphics;
public:
CGraphicsPath();
~CGraphicsPath();
CGraphicsPath* Clone();
Status Reset();
void SetRuler(bool bEvenOdd);
Status StartFigure();
Status CloseFigure();
bool Is_poly_closed();
Status MoveTo(double x, double y);
Status LineTo(double x, double y);
Status CurveTo(double x1, double y1, double x2, double y2, double x3, double y3);
Status AddLine(double x1, double y1, double x2, double y2);
Status AddLines(double* pPoints, int nCount);
// методы, которые просто будем сводить к трем основным
Status AddBezier(double x1, double y1, double x2, double y2, double x3, double y3, double x4, double y4);
Status AddBeziers(double* pPoints, int nCount);
Status AddCurve(double* pPoints, int nCount);
Status AddEllipse(double x, double y, double width, double height);
Status AddRectangle(double x, double y, double width, double height);
Status AddPolygon(double* pPoints, int nCount);
Status AddPath(const CGraphicsPath& oPath);
Status AddArc(double x, double y, double width, double height, double startAngle, double sweepAngle);
ULONG GetPointCount() const;
Status GetPathPoints(PointF* points, int count) const;
Status GetLastPoint(double& x, double& y);
Status GetPathPoints(double* points, int count) const;
void GetBounds(double& left, double& top, double& width, double& height);
Status Transform(const CMatrix* matrix);
virtual bool _MoveTo(double x, double y);
virtual bool _LineTo(double x, double y);
virtual bool _CurveTo(double x1, double y1, double x2, double y2, double x3, double y3);
virtual bool _Close();
Status AddString(const std::wstring& strText, CFontManager* pFont, double x, double y);
Status AddStringC(const LONG& lText, CFontManager* pFont, double x, double y);
void z_Stroke(const NSStructures::CPen* Pen);
void Widen(const NSStructures::CPen* Pen, const CMatrix* matrix, float flatness);
agg::path_storage *z_get_agg_path_storage();
public:
agg::path_storage m_agg_ps;
bool m_bEvenOdd;
bool m_bIsMoveTo;
public:
int EllipseArc(double fX, double fY, double fXRad, double fYRad, double fAngle1, double fAngle2, INT bClockDirection);
double AngToEllPrm(double fAngle, double fXRad, double fYRad);
int EllipseArc2(double fX, double fY, double fXRad, double fYRad, double fAngle1, double fAngle2, INT bClockDirection);
int EllipseArc3(double fX, double fY, double fXRad, double fYRad, double dAngle1, double dAngle2, double *pfXCur, double *pfYCur, INT bClockDirection = FALSE);
int Ellipse(double fX, double fY, double fXRad, double fYRad);
Status AddArc2(double fX, double fY, double fWidth, double fHeight, double fStartAngle, double fSweepAngle);
};
class CGraphicsPathSimpleConverter : public ISimpleGraphicsPath
{
friend class CFontManager;
private:
IRenderer* m_pRenderer;
bool m_bEvenOdd;
bool m_bIsMoveTo;
bool m_bIsClosed;
agg::path_storage m_agg_ps;
public:
CGraphicsPathSimpleConverter();
~CGraphicsPathSimpleConverter();
public:
void SetRenderer(IRenderer* pRenderer);
IRenderer* GetRenderer(INT bIsAddref = FALSE);
public:
bool PathCommandMoveTo(double fX, double fY);
bool PathCommandLineTo(double fX, double fY);
bool PathCommandLinesTo(double* pPoints, LONG lCount);
bool PathCommandCurveTo(double fX1, double fY1, double fX2, double fY2, double fX3, double fY3);
bool PathCommandCurvesTo(double* pData, LONG lCount);
bool PathCommandArcTo(double fX, double fY, double fWidth, double fHeight, double fStartAngle, double fSweepAngle);
bool PathCommandClose();
bool PathCommandEnd();
bool PathCommandStart();
bool PathCommandGetCurrentPoint(double* fX, double* fY);
bool PathCommandText(const std::wstring& bsText, CFontManager* pManager, double fX, double fY, double fWidth, double fHeight, double fBaseLineOffset);
bool PathCommandTextEx(std::wstring& bsText, std::wstring& bsGidText, CFontManager* pManager, double fX, double fY, double fWidth, double fHeight, double fBaseLineOffset, DWORD lFlags);
bool PathCommandGetBounds(double& left, double& top, double& width, double &height);
public:
virtual bool _MoveTo(double x, double y);
virtual bool _LineTo(double x, double y);
virtual bool _CurveTo(double x1, double y1, double x2, double y2, double x3, double y3);
virtual bool _Close();
bool _Reset();
bool _Start();
protected:
bool AddString(const std::wstring& bstrText, CFontManager* pFont, double x, double y);
int EllipseArc(double fX, double fY, double fXRad, double fYRad, double fAngle1, double fAngle2, INT bClockDirection);
double AngToEllPrm(double fAngle, double fXRad, double fYRad);
int EllipseArc2(double fX, double fY, double fXRad, double fYRad, double fAngle1, double fAngle2, INT bClockDirection);
int EllipseArc3(double fX, double fY, double fXRad, double fYRad, double dAngle1, double dAngle2, double *pfXCur, double *pfYCur, INT bClockDirection = FALSE);
int Ellipse(double fX, double fY, double fXRad, double fYRad);
bool AddArc(double fX, double fY, double fWidth, double fHeight, double fStartAngle, double fSweepAngle);
bool Is_poly_closed();
};
}
#endif // _BUILD_GRAPHICSPATH_H_
\ No newline at end of file
#include "GraphicsRenderer.h"
#include <algorithm>
////////////////////////////////////////////////////////////////////////////////
Aggplus::CBrush* CGraphicsRenderer::CreateBrush(NSStructures::CBrush* pBrush)
{
if (NULL == pBrush)
return NULL;
bool bIsSwappedRGB = false;
if (m_pRenderer && m_pRenderer->m_bSwapRGB)
bIsSwappedRGB = true;
LONG Type = pBrush->Type;
if ((0 == Type) || (c_BrushTypeSolid == Type))
{
Aggplus::CColor oColor((BYTE)(pBrush->Alpha1 * m_dGlobalAlpha), pBrush->Color1, bIsSwappedRGB);
Aggplus::CBrushSolid* pNew = new Aggplus::CBrushSolid(oColor);
return pNew;
}
else if ((c_BrushTypeHorizontal == Type) ||
(c_BrushTypeVertical == Type) ||
(c_BrushTypeDiagonal1 == Type) ||
(c_BrushTypeDiagonal2 == Type) ||
(c_BrushTypeCenter == Type) ||
(c_BrushTypePathGradient1 == Type) ||
(c_BrushTypePathGradient2 == Type) ||
(c_BrushTypeCylinderHor == Type) ||
(c_BrushTypeCylinderVer == Type))
{
Aggplus::CColor o1((BYTE)(pBrush->Alpha1 * m_dGlobalAlpha), pBrush->Color1, bIsSwappedRGB);
Aggplus::CColor o2((BYTE)(pBrush->Alpha2 * m_dGlobalAlpha), pBrush->Color2, bIsSwappedRGB);
Aggplus::CBrushLinearGradient* pNew = new Aggplus::CBrushLinearGradient( Aggplus::RectF(0.0f, 0.0f, 1.0f, 1.0f), o1, o2, (float)pBrush->LinearAngle, TRUE );
if( pNew )
{
pNew->SetRelativeCoords( TRUE );
int nCountSubColors = pBrush->m_arrSubColors.GetSize();
if( nCountSubColors > 0 )
{
Aggplus::CColor* pColors = new Aggplus::CColor[nCountSubColors];
float* pBlends = new float[nCountSubColors];
if( pColors && pBlends )
{
for( int i = 0; i < nCountSubColors; i++ )
{
DWORD dwColor = (DWORD)pBrush->m_arrSubColors[i].color;
BYTE r = (dwColor >> 24) & 0xFF;
BYTE g = (dwColor >> 16) & 0xFF;
BYTE b = (dwColor >> 8) & 0xFF;
BYTE a = (dwColor) & 0xFF;
if (bIsSwappedRGB)
{
BYTE tmp = r;
r = b;
b = tmp;
}
pColors[i] = Aggplus::CColor((BYTE)(a * m_dGlobalAlpha), b, g, r);
pBlends[i] = (float)(pBrush->m_arrSubColors[i].position / 65536.0);
}
pNew->SetInterpolationColors( pColors, pBlends, nCountSubColors );
}
delete [] pColors;
delete [] pBlends;
}
pNew->SetBounds(pBrush->Bounds);
}
if (pNew && c_BrushTypePathGradient2 == Type)
pNew->m_bType = Aggplus::BrushTypePathGradient;
return pNew;
}
else if (c_BrushTypeHatch1 == Type)
{
Aggplus::CColor o1((BYTE)(pBrush->Alpha1 * m_dGlobalAlpha), pBrush->Color1, bIsSwappedRGB);
Aggplus::CColor o2((BYTE)(pBrush->Alpha2 * m_dGlobalAlpha), pBrush->Color2, bIsSwappedRGB);
Aggplus::CBrushHatch* pNew = new Aggplus::CBrushHatch();
pNew->m_dwColor1 = o1;
pNew->m_dwColor2 = o2;
pNew->m_name = pBrush->TexturePath;
pNew->Bounds = pBrush->Bounds;
return pNew;
}
else
{
Aggplus::CBrushTexture* pNew = new Aggplus::CBrushTexture(pBrush->TexturePath, /*(Aggplus::WrapMode)TextureMode*/Aggplus::WrapModeClamp);
return pNew;
}
}
CGraphicsRenderer::CGraphicsRenderer()
{
m_pRenderer = NULL;
m_pPath = NULL;
m_dWidth = 210;
m_dHeight = 190;
m_dPixelsWidth = 720;
m_dPixelsHeight = 576;
m_lCurrentCommandType = 0;
m_lCurrentClipMode = 0;
m_bIsSetupClip = FALSE;
m_pFontManager = NULL;
m_oInstalledFont.Name = L"";
m_pPixels = NULL;
m_pDIB = NULL;
m_pCache = NULL;
m_dGlobalAlpha = 1.0;
m_bGlobalAlphaEnabled = FALSE;
}
CGraphicsRenderer::~CGraphicsRenderer()
{
Clear();
RELEASEOBJECT(m_pDIB);
RELEASEINTERFACE(m_pFontManager);
RELEASEINTERFACE(m_pCache);
}
void CGraphicsRenderer::SetImageCache(CImageFilesCache* pCache)
{
RELEASEINTERFACE(m_pCache);
m_pCache = pCache;
ADDREFINTERFACE(m_pCache);
}
void CGraphicsRenderer::SetFontManager(CFontManager* pManager)
{
RELEASEINTERFACE(m_pFontManager);
if (NULL == pManager)
{
m_pFontManager = new CFontManager();
m_pFontManager->Initialize();
}
else
{
m_pFontManager = pManager;
ADDREFINTERFACE(m_pFontManager);
}
}
void CGraphicsRenderer::CheckFontManager()
{
if (NULL == m_pFontManager)
SetFontManager(NULL);
}
CFontManager* CGraphicsRenderer::GetFontManager()
{
return m_pFontManager;
}
BYTE* CGraphicsRenderer::GetPixels(LONG& lWidth, LONG& lHeight)
{
lWidth = (LONG)m_dPixelsWidth;
lHeight = (LONG)m_dPixelsHeight;
return m_pPixels;
}
void CGraphicsRenderer::ClearInstallFont()
{
m_oInstalledFont.Name = L"";
m_oInstalledFont.Path = L"";
}
void CGraphicsRenderer::SetClipRect(double x, double y, double w, double h)
{
m_pRenderer->SetClipRect3(x, y, w, h);
}
INT CGraphicsRenderer::CheckValidate(INT bOnlyGraphics)
{
if (NULL == m_pRenderer)
return FALSE;
if (!bOnlyGraphics)
return (NULL != m_pPath);
return TRUE;
}
void CGraphicsRenderer::Clear()
{
RELEASEOBJECT(m_pPath);
RELEASEOBJECT(m_pRenderer);
}
void CGraphicsRenderer::UpdateSize()
{
if (NULL == m_pRenderer)
return;
m_pRenderer->SetPageWidth(m_dWidth, Aggplus::UnitMillimeter);
m_pRenderer->SetPageHeight(m_dHeight, Aggplus::UnitMillimeter);
m_pRenderer->SetPageUnit(Aggplus::UnitMillimeter);
}
// тип рендерера-----------------------------------------------------------------------------
HRESULT CGraphicsRenderer::get_Type(LONG* lType)
{
if (NULL == lType)
return S_FALSE;
*lType = c_nGrRenderer;
return S_OK;
}
//-------- Функции для работы со страницей --------------------------------------------------
HRESULT CGraphicsRenderer::NewPage()
{
// ну не влезло так не влезло
return S_OK;
}
HRESULT CGraphicsRenderer::put_Height(const double& dHeight)
{
m_dHeight = dHeight;
if (NULL != m_pRenderer)
{
m_pRenderer->SetPageHeight(m_dHeight, Aggplus::UnitMillimeter);
m_pRenderer->SetPageUnit(Aggplus::UnitMillimeter);
}
return S_OK;
}
HRESULT CGraphicsRenderer::get_Height(double* dHeight)
{
if (NULL == dHeight)
return S_FALSE;
*dHeight = m_dHeight;
return S_OK;
}
HRESULT CGraphicsRenderer::put_Width(const double& dWidth)
{
m_dWidth = dWidth;
if (NULL != m_pRenderer)
{
m_pRenderer->SetPageWidth(m_dWidth, Aggplus::UnitMillimeter);
m_pRenderer->SetPageUnit(Aggplus::UnitMillimeter);
}
return S_OK;
}
HRESULT CGraphicsRenderer::get_Width(double* dWidth)
{
if (NULL == dWidth)
return S_FALSE;
*dWidth = m_dWidth;
return S_OK;
}
HRESULT CGraphicsRenderer::get_DpiX(double* dDpiX)
{
if (NULL == dDpiX)
return S_FALSE;
*dDpiX = 25.4 * m_dPixelsWidth / m_dWidth;
return S_OK;
}
HRESULT CGraphicsRenderer::get_DpiY(double* dDpiY)
{
if (NULL == dDpiY)
return S_FALSE;
*dDpiY = 25.4 * m_dPixelsHeight / m_dHeight;
return S_OK;
}
// pen --------------------------------------------------------------------------------------
HRESULT CGraphicsRenderer::get_PenColor(LONG* lColor)
{
*lColor = m_oPen.Color;
return S_OK;
}
HRESULT CGraphicsRenderer::put_PenColor(const LONG& lColor)
{
m_oPen.Color = lColor;
return S_OK;
}
HRESULT CGraphicsRenderer::get_PenAlpha(LONG* lAlpha)
{
*lAlpha = m_oPen.Alpha;
return S_OK;
}
HRESULT CGraphicsRenderer::put_PenAlpha(const LONG& lAlpha)
{
m_oPen.Alpha = lAlpha;
return S_OK;
}
HRESULT CGraphicsRenderer::get_PenSize(double* dSize)
{
*dSize = m_oPen.Size;
return S_OK;
}
HRESULT CGraphicsRenderer::put_PenSize(const double& dSize)
{
m_oPen.Size = dSize;
return S_OK;
}
HRESULT CGraphicsRenderer::get_PenDashStyle(BYTE* val)
{
*val = m_oPen.DashStyle;
return S_OK;
}
HRESULT CGraphicsRenderer::put_PenDashStyle(const BYTE& val)
{
m_oPen.DashStyle = val;
return S_OK;
}
HRESULT CGraphicsRenderer::get_PenLineStartCap(BYTE* val)
{
*val = m_oPen.LineStartCap;
return S_OK;
}
HRESULT CGraphicsRenderer::put_PenLineStartCap(const BYTE& val)
{
m_oPen.LineStartCap = val;
return S_OK;
}
HRESULT CGraphicsRenderer::get_PenLineEndCap(BYTE* val)
{
*val = m_oPen.LineEndCap;
return S_OK;
}
HRESULT CGraphicsRenderer::put_PenLineEndCap(const BYTE& val)
{
m_oPen.LineEndCap = val;
return S_OK;
}
HRESULT CGraphicsRenderer::get_PenLineJoin(BYTE* val)
{
*val = m_oPen.LineJoin;
return S_OK;
}
HRESULT CGraphicsRenderer::put_PenLineJoin(const BYTE& val)
{
m_oPen.LineJoin = val;
return S_OK;
}
HRESULT CGraphicsRenderer::get_PenDashOffset(double* dOffset)
{
*dOffset = m_oPen.DashOffset;
return S_OK;
}
HRESULT CGraphicsRenderer::put_PenDashOffset(const double& dOffset)
{
m_oPen.DashOffset = dOffset;
return S_OK;
}
HRESULT CGraphicsRenderer::get_PenAlign(LONG* lAlign)
{
*lAlign = m_oPen.Align;
return S_OK;
}
HRESULT CGraphicsRenderer::put_PenAlign(const LONG& lAlign)
{
m_oPen.Align = lAlign;
return S_OK;
}
HRESULT CGraphicsRenderer::get_PenMiterLimit(double* dOffset)
{
*dOffset = m_oPen.MiterLimit;
return S_OK;
}
HRESULT CGraphicsRenderer::put_PenMiterLimit(const double& dOffset)
{
m_oPen.MiterLimit = dOffset;
return S_OK;
}
HRESULT CGraphicsRenderer::PenDashPattern(double* pPattern, LONG lCount)
{
RELEASEARRAYOBJECTS((m_oPen.DashPattern));
m_oPen.DashPattern = new double[lCount];
memcpy(m_oPen.DashPattern, pPattern, lCount * sizeof(double));
m_oPen.Count = lCount;
return S_OK;
}
// brush ------------------------------------------------------------------------------------
HRESULT CGraphicsRenderer::get_BrushType(LONG* lType)
{
*lType = m_oBrush.Type;
return S_OK;
}
HRESULT CGraphicsRenderer::put_BrushType(const LONG& lType)
{
m_oBrush.Type = lType;
return S_OK;
}
HRESULT CGraphicsRenderer::get_BrushColor1(LONG* lColor)
{
*lColor = m_oBrush.Color1;
return S_OK;
}
HRESULT CGraphicsRenderer::put_BrushColor1(const LONG& lColor)
{
m_oBrush.Color1 = lColor;
return S_OK;
}
HRESULT CGraphicsRenderer::get_BrushAlpha1(LONG* lAlpha)
{
*lAlpha = m_oBrush.Alpha1;
return S_OK;
}
HRESULT CGraphicsRenderer::put_BrushAlpha1(const LONG& lAlpha)
{
m_oBrush.Alpha1 = lAlpha;
return S_OK;
}
HRESULT CGraphicsRenderer::get_BrushColor2(LONG* lColor)
{
*lColor = m_oBrush.Color2;
return S_OK;
}
HRESULT CGraphicsRenderer::put_BrushColor2(const LONG& lColor)
{
m_oBrush.Color2 = lColor;
return S_OK;
}
HRESULT CGraphicsRenderer::get_BrushAlpha2(LONG* lAlpha)
{
*lAlpha = m_oBrush.Alpha2;
return S_OK;
}
HRESULT CGraphicsRenderer::put_BrushAlpha2(const LONG& lAlpha)
{
m_oBrush.Alpha2 = lAlpha;
return S_OK;
}
HRESULT CGraphicsRenderer::get_BrushTexturePath(std::wstring* bsPath)
{
*bsPath = m_oBrush.TexturePath;
return S_OK;
}
HRESULT CGraphicsRenderer::put_BrushTexturePath(const std::wstring& bsPath)
{
m_oBrush.TexturePath = bsPath;
return S_OK;
}
HRESULT CGraphicsRenderer::get_BrushTextureMode(LONG* lMode)
{
*lMode = m_oBrush.TextureMode;
return S_OK;
}
HRESULT CGraphicsRenderer::put_BrushTextureMode(const LONG& lMode)
{
m_oBrush.TextureMode = lMode;
return S_OK;
}
HRESULT CGraphicsRenderer::get_BrushTextureAlpha(LONG* lTxAlpha)
{
*lTxAlpha = m_oBrush.TextureAlpha;
return S_OK;
}
HRESULT CGraphicsRenderer::put_BrushTextureAlpha(const LONG& lTxAlpha)
{
m_oBrush.TextureAlpha = lTxAlpha;
return S_OK;
}
HRESULT CGraphicsRenderer::get_BrushLinearAngle(double* dAngle)
{
*dAngle = m_oBrush.LinearAngle;
return S_OK;
}
HRESULT CGraphicsRenderer::put_BrushLinearAngle(const double& dAngle)
{
m_oBrush.LinearAngle = dAngle;
return S_OK;
}
HRESULT CGraphicsRenderer::BrushRect(const INT& val, const double& left, const double& top, const double& width, const double& height)
{
m_oBrush.Rectable = val;
m_oBrush.Rect.X = (float)left;
m_oBrush.Rect.Y = (float)top;
m_oBrush.Rect.Width = (float)width;
m_oBrush.Rect.Height = (float)height;
return S_OK;
}
HRESULT CGraphicsRenderer::BrushBounds(const double& left, const double& top, const double& width, const double& height)
{
m_oBrush.Bounds.left = left;
m_oBrush.Bounds.top = top;
m_oBrush.Bounds.right = left + width;
m_oBrush.Bounds.bottom = top + height;
return S_OK;
}
HRESULT CGraphicsRenderer::put_BrushGradientColors(LONG* lColors, double* pPositions, LONG nCount)
{
m_oBrush.m_arrSubColors.RemoveAll();
for (LONG i = 0; i < nCount; ++i)
{
NSStructures::CBrush::TSubColor color;
color.color = lColors[i];
color.position = (long)(pPositions[i] * 65536);
m_oBrush.m_arrSubColors.Add(color);
}
return S_OK;
}
// font -------------------------------------------------------------------------------------
HRESULT CGraphicsRenderer::get_FontName(std::wstring* bsName)
{
*bsName = m_oFont.Name;
return S_OK;
}
HRESULT CGraphicsRenderer::put_FontName(const std::wstring& bsName)
{
m_oFont.Name = bsName;
return S_OK;
}
HRESULT CGraphicsRenderer::get_FontPath(std::wstring* bsName)
{
*bsName = m_oFont.Path;
return S_OK;
}
HRESULT CGraphicsRenderer::put_FontPath(const std::wstring& bsName)
{
m_oFont.Path = bsName;
return S_OK;
}
HRESULT CGraphicsRenderer::get_FontSize(double* dSize)
{
*dSize = m_oFont.Size;
return S_OK;
}
HRESULT CGraphicsRenderer::put_FontSize(const double& dSize)
{
m_oFont.Size = dSize;
return S_OK;
}
HRESULT CGraphicsRenderer::get_FontStyle(LONG* lStyle)
{
*lStyle = m_oFont.GetStyle();
return S_OK;
}
HRESULT CGraphicsRenderer::put_FontStyle(const LONG& lStyle)
{
m_oFont.SetStyle(lStyle);
return S_OK;
}
HRESULT CGraphicsRenderer::get_FontStringGID(INT* bGID)
{
*bGID = m_oFont.StringGID;
return S_OK;
}
HRESULT CGraphicsRenderer::put_FontStringGID(const INT& bGID)
{
m_oFont.StringGID = bGID;
return S_OK;
}
HRESULT CGraphicsRenderer::get_FontCharSpace(double* dSpace)
{
*dSpace = m_oFont.CharSpace;
return S_OK;
}
HRESULT CGraphicsRenderer::put_FontCharSpace(const double& dSpace)
{
m_oFont.CharSpace = dSpace;
return S_OK;
}
HRESULT CGraphicsRenderer::get_FontFaceIndex(int* lFaceIndex)
{
*lFaceIndex = m_oFont.FaceIndex;
return S_OK;
}
HRESULT CGraphicsRenderer::put_FontFaceIndex(const int& lFaceIndex)
{
m_oFont.FaceIndex = lFaceIndex;
return S_OK;
}
//-------- Функции для вывода текста --------------------------------------------------------
HRESULT CGraphicsRenderer::CommandDrawTextCHAR(const LONG& c, const double& x, const double& y, const double& w, const double& h, const double& baselineOffset)
{
if (c_nHyperlinkType == m_lCurrentCommandType)
return S_OK;
put_BrushType(c_BrushTypeSolid);
_SetFont();
Aggplus::CBrush* pBrush = CreateBrush(&m_oBrush);
m_pRenderer->DrawStringC(c, m_pFontManager, pBrush, x, y + baselineOffset);
RELEASEOBJECT(pBrush);
return S_OK;
}
HRESULT CGraphicsRenderer::CommandDrawText(const std::wstring& bsText, const double& x, const double& y, const double& w, const double& h, const double& baselineOffset)
{
if (c_nHyperlinkType == m_lCurrentCommandType)
return S_OK;
put_BrushType(c_BrushTypeSolid);
_SetFont();
Aggplus::CBrush* pBrush = CreateBrush(&m_oBrush);
m_pRenderer->DrawString(bsText, m_pFontManager, pBrush, x, y + baselineOffset);
RELEASEOBJECT(pBrush);
return S_OK;
}
HRESULT CGraphicsRenderer::CommandDrawTextExCHAR(const LONG& c, const LONG& gid, const double& x, const double& y, const double& w, const double& h, const double& baselineOffset, const DWORD& lFlags)
{
if (gid >= 0)
{
m_oFont.StringGID = TRUE;
return CommandDrawTextCHAR(gid, x, y, w, h, baselineOffset);
}
m_oFont.StringGID = FALSE;
return CommandDrawTextCHAR(c, x, y, w, h, baselineOffset);
}
HRESULT CGraphicsRenderer::CommandDrawTextEx(const std::wstring& bsUnicodeText, const std::wstring& bsGidText, const double& x, const double& y, const double& w, const double& h, const double& baselineOffset, const DWORD& lFlags)
{
if (!bsGidText.empty())
{
m_oFont.StringGID = TRUE;
return CommandDrawText(bsGidText, x, y, w, h, baselineOffset);
}
m_oFont.StringGID = FALSE;
return CommandDrawText(bsUnicodeText, x, y, w, h, baselineOffset);
}
//-------- Маркеры для команд ---------------------------------------------------------------
HRESULT CGraphicsRenderer::BeginCommand(const DWORD& lType)
{
m_lCurrentCommandType = lType;
switch (lType)
{
case c_nPageType:
{
return NewPage();
}
default:
break;
};
return S_OK;
}
HRESULT CGraphicsRenderer::EndCommand(const DWORD& lType)
{
switch (lType)
{
case c_nClipType:
{
INT bIsIn = (c_nClipRegionTypeWinding == (0x0001 & m_lCurrentClipMode));
m_pPath->SetRuler(bIsIn ? false : true);
INT bIsIntersect = (c_nClipRegionIntersect == (0x0100 & m_lCurrentClipMode));
m_pRenderer->CombineClip(m_pPath, bIsIntersect ? agg::sbool_and : agg::sbool_or);
//m_pRenderer->SetClip(m_pPath);
break;
}
case c_nResetClipType:
{
m_pRenderer->ResetClip();
m_bIsSetupClip = FALSE;
break;
}
default:
break;
};
m_lCurrentCommandType = 0;
return S_OK;
}
//-------- Функции для работы с Graphics Path -----------------------------------------------
HRESULT CGraphicsRenderer::PathCommandMoveTo(const double& x, const double& y)
{
if (!CheckValidate())
return S_FALSE;
m_pPath->MoveTo(x, y);
return S_OK;
}
HRESULT CGraphicsRenderer::PathCommandLineTo(const double& x, const double& y)
{
if (!CheckValidate())
return S_FALSE;
m_pPath->LineTo(x, y);
return S_OK;
}
HRESULT CGraphicsRenderer::PathCommandLinesTo(double* points, const int& count)
{
if (!CheckValidate())
return S_FALSE;
m_pPath->AddLines(points, count);
return S_OK;
}
HRESULT CGraphicsRenderer::PathCommandCurveTo(const double& x1, const double& y1, const double& x2, const double& y2, const double& x3, const double& y3)
{
if (!CheckValidate())
return S_FALSE;
m_pPath->CurveTo(x1, y1, x2, y2, x3, y3);
return S_OK;
}
HRESULT CGraphicsRenderer::PathCommandCurvesTo(double* points, const int& count)
{
if (!CheckValidate())
return S_FALSE;
m_pPath->AddBeziers(points, count);
return S_OK;
}
HRESULT CGraphicsRenderer::PathCommandArcTo(const double& x, const double& y, const double& w, const double& h, const double& startAngle, const double& sweepAngle)
{
if (!CheckValidate())
return S_FALSE;
m_pPath->AddArc2(x, y, w, h, -startAngle, -sweepAngle);
return S_OK;
}
HRESULT CGraphicsRenderer::PathCommandClose()
{
if (!CheckValidate())
return S_FALSE;
m_pPath->CloseFigure();
return S_OK;
}
HRESULT CGraphicsRenderer::PathCommandEnd()
{
if (!CheckValidate())
return S_FALSE;
m_pPath->Reset();
return S_OK;
}
HRESULT CGraphicsRenderer::DrawPath(const LONG& nType)
{
if (!CheckValidate(TRUE))
return S_FALSE;
LONG lFillType = (nType & 0xFF00);
INT bIsStroke = (0x01 == (nType & 0x01));
switch (lFillType)
{
case c_nWindingFillMode:
{
m_pPath->SetRuler(false);
CCacheImage* pCacheImage = NULL;
Aggplus::CBrush* pBrush = NULL;
if (m_oBrush.Type == c_BrushTypeTexture || m_oBrush.Type == c_BrushTypePattern)
{
Aggplus::WrapMode oMode = Aggplus::WrapModeClamp;
switch (m_oBrush.TextureMode)
{
case c_BrushTextureModeTile:
oMode = Aggplus::WrapModeTile;
break;
case c_BrushTextureModeTileCenter:
oMode = Aggplus::WrapModeTile;
break;
default:
break;
}
Aggplus::CBrushTexture* pTextureBrush = NULL;
if (NULL != m_pCache)
{
pCacheImage = m_pCache->Lock(m_oBrush.TexturePath);
pTextureBrush = new Aggplus::CBrushTexture(pCacheImage->GetImage(), oMode);
}
else
{
pTextureBrush = new Aggplus::CBrushTexture(m_oBrush.TexturePath, oMode);
}
if( pTextureBrush )
{
if( m_oBrush.Type == c_BrushTypePattern )
{
pTextureBrush->m_bUsePattern = TRUE;
pTextureBrush->m_colors[0] = Aggplus::CColor((BYTE)m_oBrush.Alpha1, m_oBrush.Color1);
pTextureBrush->m_colors[1] = Aggplus::CColor((BYTE)m_oBrush.Alpha2, m_oBrush.Color2);
}
pTextureBrush->Alpha = (BYTE)m_oBrush.TextureAlpha;
}
pBrush = pTextureBrush;
}
else
{
pBrush = CreateBrush(&m_oBrush);
}
m_pRenderer->FillPath(pBrush, m_pPath);
RELEASEOBJECT(pBrush);
RELEASEINTERFACE(pCacheImage);
break;
}
case c_nEvenOddFillMode:
{
m_pPath->SetRuler(true);
CCacheImage* pCacheImage = NULL;
Aggplus::CBrush* pBrush = NULL;
if (m_oBrush.Type == c_BrushTypeTexture || m_oBrush.Type == c_BrushTypePattern)
{
Aggplus::CBrushTexture* pTextureBrush = NULL;
if (NULL != m_pCache)
{
pCacheImage = m_pCache->Lock(m_oBrush.TexturePath);
pTextureBrush = new Aggplus::CBrushTexture(pCacheImage->GetImage(), /*(Aggplus::WrapMode)TextureMode*/Aggplus::WrapModeClamp);
}
else
{
pTextureBrush = new Aggplus::CBrushTexture(m_oBrush.TexturePath, /*(Aggplus::WrapMode)TextureMode*/Aggplus::WrapModeClamp);
}
if( pTextureBrush )
{
if( m_oBrush.Type == c_BrushTypePattern )
{
pTextureBrush->m_bUsePattern = TRUE;
pTextureBrush->m_colors[0] = Aggplus::CColor((BYTE)m_oBrush.Alpha1, m_oBrush.Color1);
pTextureBrush->m_colors[1] = Aggplus::CColor((BYTE)m_oBrush.Alpha2, m_oBrush.Color2);
}
}
pBrush = pTextureBrush;
}
else
{
pBrush = CreateBrush(&m_oBrush);
}
m_pRenderer->FillPath(pBrush, m_pPath);
RELEASEOBJECT(pBrush);
RELEASEINTERFACE(pCacheImage);
break;
}
default:
break;
};
if (bIsStroke)
{
m_pRenderer->DrawPath(&m_oPen, m_pPath);
}
return S_OK;
}
HRESULT CGraphicsRenderer::PathCommandStart()
{
if (!CheckValidate())
return S_FALSE;
m_pPath->StartFigure();
return S_OK;
}
HRESULT CGraphicsRenderer::PathCommandGetCurrentPoint(double* x, double* y)
{
if (!CheckValidate())
return S_FALSE;
m_pPath->GetLastPoint(*x, *y);
return S_OK;
}
// textpath
HRESULT CGraphicsRenderer::PathCommandTextCHAR(const LONG& c, const double& x, const double& y, const double& w, const double& h, const double& baselineOffset)
{
if (!CheckValidate())
return S_FALSE;
_SetFont();
// так как пат рисуется в миллиметрах - надо перевести пункты в миллиметры
float fSize = (float)(0.3528 * m_oFont.Size);
m_pPath->AddStringC(c, m_pFontManager, x, y + baselineOffset);
return S_OK;
}
HRESULT CGraphicsRenderer::PathCommandText(const std::wstring& bsText, const double& x, const double& y, const double& w, const double& h, const double& baselineOffset)
{
if (!CheckValidate())
return S_FALSE;
_SetFont();
// так как пат рисуется в миллиметрах - надо перевести пункты в миллиметры
float fSize = (float)(0.3528 * m_oFont.Size);
m_pPath->AddString(bsText, m_pFontManager, x, y + baselineOffset);
return S_OK;
}
HRESULT CGraphicsRenderer::PathCommandTextExCHAR(const LONG& c, const LONG& gid, const double& x, const double& y, const double& w, const double& h, const double& baselineOffset, const DWORD& lFlags)
{
if (gid >= 0)
{
m_oFont.StringGID = TRUE;
return PathCommandTextCHAR(gid, x, y, w, h, baselineOffset);
}
m_oFont.StringGID = FALSE;
return PathCommandTextCHAR(c, x, y, w, h, baselineOffset);
}
HRESULT CGraphicsRenderer::PathCommandTextEx(const std::wstring& bsUnicodeText, const std::wstring& bsGidText, const double& x, const double& y, const double& w, const double& h, const double& baselineOffset, const DWORD& lFlags)
{
if (!bsGidText.empty())
{
m_oFont.StringGID = TRUE;
return PathCommandText(bsGidText, x, y, w, h, baselineOffset);
}
m_oFont.StringGID = FALSE;
return PathCommandText(bsUnicodeText, x, y, w, h, baselineOffset);
}
//-------- Функции для вывода изображений ---------------------------------------------------
HRESULT CGraphicsRenderer::DrawImage(IGrObject* pImage, const double& x, const double& y, const double& w, const double& h)
{
if (!CheckValidate(TRUE) || NULL == pImage)
return S_FALSE;
m_pRenderer->DrawImage((Aggplus::CImage*)pImage, x, y, w, h);
return S_OK;
}
HRESULT CGraphicsRenderer::DrawImageFromFile(const std::wstring& bstrVal, const double& x, const double& y, const double& w, const double& h, const BYTE& lAlpha)
{
CCacheImage* pCacheImage = NULL;
if (NULL != m_pCache)
{
pCacheImage = m_pCache->Lock(bstrVal);
}
if (NULL != pCacheImage)
{
Aggplus::CImage* pImage = pCacheImage->GetImage();
m_pRenderer->DrawImage(pImage, x, y, w, h);
RELEASEINTERFACE(pCacheImage);
}
return S_OK;
}
// transform --------------------------------------------------------------------------------
HRESULT CGraphicsRenderer::SetTransform(const double& m1, const double& m2, const double& m3, const double& m4, const double& m5, const double& m6)
{
if (!CheckValidate())
return S_FALSE;
ApplyTransform(m1, m2, m3, m4, m5, m6);
return S_OK;
}
HRESULT CGraphicsRenderer::GetTransform(double *pdA, double *pdB, double *pdC, double *pdD, double *pdE, double *pdF)
{
if (!CheckValidate())
return S_FALSE;
double buffer[6];
Aggplus::CMatrix oMatrix;
m_pRenderer->GetTransform()->GetElements(buffer);
*pdA = (double)buffer[0];
*pdB = (double)buffer[1];
*pdC = (double)buffer[2];
*pdD = (double)buffer[3];
*pdE = (double)buffer[4];
*pdF = (double)buffer[5];
return S_OK;
}
HRESULT CGraphicsRenderer::ResetTransform()
{
_ResetTransform();
return S_OK;
}
// -----------------------------------------------------------------------------------------
HRESULT CGraphicsRenderer::get_ClipMode(LONG* plMode)
{
*plMode = m_lCurrentClipMode;
return S_OK;
}
HRESULT CGraphicsRenderer::put_ClipMode(const LONG& lMode)
{
if (!CheckValidate())
return S_FALSE;
m_lCurrentClipMode = lMode;
return S_OK;
}
// additiaonal params ----------------------------------------------------------------------
HRESULT CGraphicsRenderer::CommandLong(const LONG& lType, const LONG& lCommand)
{
return S_OK;
}
HRESULT CGraphicsRenderer::CommandDouble(const LONG& lType, const double& dCommand)
{
return S_OK;
}
HRESULT CGraphicsRenderer::CommandString(const LONG& lType, const std::wstring& sCommand)
{
return S_OK;
}
// common
void CGraphicsRenderer::_SetFont()
{
if (m_oInstalledFont.IsEqual(&m_oFont))
{
if (1 < m_dWidth)
{
double dPix = m_oFont.CharSpace * m_dPixelsWidth / m_dWidth;
m_pFontManager->m_fCharSpacing = dPix;
}
return;
}
m_pFontManager->SetStringGID(m_oFont.StringGID);
if (1 < m_dWidth)
{
double dPix = m_oFont.CharSpace * m_dPixelsWidth / m_dWidth;
m_pFontManager->m_fCharSpacing = dPix;
}
if (m_oFont.Path.empty())
{
m_pFontManager->LoadFontByName(m_oFont.Name, m_oFont.Size, m_oFont.GetStyle(), m_pRenderer->GetDpiX(), m_pRenderer->GetDpiY());
}
else
{
m_pFontManager->LoadFontFromFile(m_oFont.Path, m_oFont.FaceIndex, m_oFont.Size, m_pRenderer->GetDpiX(), m_pRenderer->GetDpiY());
}
m_pFontManager->m_oString.ResetCTM();
m_oInstalledFont = m_oFont;
}
void CGraphicsRenderer::ApplyTransform(const double& d1, const double& d2, const double& d3, const double& d4, const double& d5, const double& d6)
{
Aggplus::CMatrix oMatrix(d1, d2, d3, d4, d5, d6);
ApplyTransform(&oMatrix);
}
void CGraphicsRenderer::ApplyTransform(Aggplus::CMatrix* pMatrix)
{
if (!CheckValidate())
return;
m_pRenderer->SetTransform(pMatrix);
m_pRenderer->CalculateFullTransform();
}
void CGraphicsRenderer::_ResetTransform()
{
if (!CheckValidate())
return;
ApplyTransform(1, 0, 0, 1, 0, 0);
}
void CGraphicsRenderer::CreateFromBgraFrame(CBgraFrame* pFrame)
{
Aggplus::CDoubleRect oRect;
oRect.left = 0;
oRect.top = 0;
oRect.right = pFrame->get_Width();
oRect.bottom = pFrame->get_Height();
if (pFrame->get_Stride() > 0)
{
CreateFlip(pFrame->get_Data(), oRect, pFrame->get_Width(), pFrame->get_Height());
}
else
{
Create(pFrame->get_Data(), oRect, pFrame->get_Width(), pFrame->get_Height());
}
}
void CGraphicsRenderer::Create(BYTE* pPixels, const Aggplus::CDoubleRect& oRect, LONG lWidthControl, LONG lHeightControl, Aggplus::CDIB* pDib)
{
LONG lRectLeft = (LONG)oRect.left;
LONG lRectTop = (LONG)oRect.top;
LONG lWidth = (LONG)oRect.GetWidth();
LONG lHeight = (LONG)oRect.GetHeight();
m_dPixelsWidth = lWidth;
m_dPixelsHeight = lHeight;
LONG lStride = 4 * lWidthControl;
m_pPixels = pPixels + (4 * lRectLeft);
m_pPixels += lStride * lRectTop;
RELEASEOBJECT(m_pRenderer);
RELEASEOBJECT(m_pPath);
m_pRenderer = new Aggplus::CGraphics();
m_pPath = new Aggplus::CGraphicsPath();
m_lClipLeft = (std::max)(0, (int) lRectLeft);
m_lClipTop = (std::max)(0, (int) lRectTop);
//LONG lClipRight = min(lWidth, -lRectLeft + lWidthControl);
//LONG lClipBottom = min(lHeight, -lRectTop + lHeightControl);
LONG lClipRight = (std::min)((LONG)oRect.right, lWidthControl);
LONG lClipBottom = (std::min)((LONG)oRect.bottom, lHeightControl);
m_lClipWidth = lClipRight - m_lClipLeft;
m_lClipHeight = lClipBottom - m_lClipTop;
m_pRenderer->Create2(pPixels, lWidthControl, lHeightControl, -4 * lWidthControl, 0,
m_lClipLeft, m_lClipTop, m_lClipWidth, m_lClipHeight, oRect.GetWidth(), oRect.GetHeight(), pDib);
Aggplus::CMatrix oBase(1, 0, 0, 1, oRect.left, oRect.top);
m_pRenderer->SetBaseTransform(&oBase);
m_pRenderer->SetPageWidth(m_dWidth, Aggplus::UnitMillimeter);
m_pRenderer->SetPageHeight(m_dHeight, Aggplus::UnitMillimeter);
m_pRenderer->SetPageUnit(Aggplus::UnitMillimeter);
}
void CGraphicsRenderer::CreateFlip(BYTE* pPixels, const Aggplus::CDoubleRect& oRect, LONG lWidthControl, LONG lHeightControl, Aggplus::CDIB* pDib)
{
LONG lRectLeft = (LONG)oRect.left;
LONG lRectTop = (LONG)oRect.top;
LONG lWidth = (LONG)oRect.GetWidth();
LONG lHeight = (LONG)oRect.GetHeight();
m_dPixelsWidth = lWidth;
m_dPixelsHeight = lHeight;
LONG lStride = 4 * lWidthControl;
RELEASEOBJECT(m_pRenderer);
RELEASEOBJECT(m_pPath);
m_pRenderer = new Aggplus::CGraphics();
m_pPath = new Aggplus::CGraphicsPath();
m_lClipLeft = (std::max) (0, (int) lRectLeft);
m_lClipTop = (std::max) (0, (int) lRectTop);
//LONG lClipRight = min(lWidth, -lRectLeft + lWidthControl);
//LONG lClipBottom = min(lHeight, -lRectTop + lHeightControl);
LONG lClipRight = (std::min) ((LONG)oRect.right, lWidthControl);
LONG lClipBottom = (std::min) ((LONG)oRect.bottom, lHeightControl);
m_lClipWidth = lClipRight - m_lClipLeft;
m_lClipHeight = lClipBottom - m_lClipTop;
//m_pRenderer->Create(m_pPixels, lWidth, lHeight, -4 * lWidthControl, 0, colorModeRGBA8);
m_pRenderer->Create2(pPixels, lWidthControl, lHeightControl, 4 * lWidthControl, 0,
m_lClipLeft, m_lClipTop, m_lClipWidth, m_lClipHeight, oRect.GetWidth(), oRect.GetHeight(), pDib);
Aggplus::CMatrix oBase(1, 0, 0, 1, oRect.left, oRect.top);
m_pRenderer->SetBaseTransform(&oBase);
m_pRenderer->SetPageWidth(m_dWidth, Aggplus::UnitMillimeter);
m_pRenderer->SetPageHeight(m_dHeight, Aggplus::UnitMillimeter);
m_pRenderer->SetPageUnit(Aggplus::UnitMillimeter);
}
void CGraphicsRenderer::put_GlobalAlphaEnabled(const bool& bEnabled, const double& dVal)
{
m_bGlobalAlphaEnabled = bEnabled;
if (m_bGlobalAlphaEnabled)
m_dGlobalAlpha = dVal;
else
m_dGlobalAlpha = 1.0;
m_pRenderer->m_dGlobalAlpha = m_dGlobalAlpha;
}
void CGraphicsRenderer::AddRect(const double& x, const double& y, const double& w, const double& h)
{
if (!CheckValidate())
return;
m_pPath->MoveTo(x, y);
m_pPath->LineTo(x + w, y);
m_pPath->LineTo(x + w, y + h);
m_pPath->LineTo(x, y + h);
m_pPath->CloseFigure();
}
#ifndef _BUILD_GRAPHICS_RENDERER_H_
#define _BUILD_GRAPHICS_RENDERER_H_
#include "IRenderer.h"
#include "Graphics.h"
#include "ImageFilesCache.h"
#include "../raster/BgraFrame.h"
class CGraphicsRenderer : public IRenderer
{
private:
CFontManager* m_pFontManager;
Aggplus::CGraphics* m_pRenderer;
Aggplus::CGraphicsPath* m_pPath;
NSStructures::CPen m_oPen;
NSStructures::CBrush m_oBrush;
NSStructures::CFont m_oFont;
NSStructures::CFont m_oInstalledFont;
double m_dWidth;
double m_dHeight;
double m_dPixelsWidth;
double m_dPixelsHeight;
DWORD m_lCurrentCommandType;
LONG m_lCurrentClipMode;
INT m_bIsSetupClip;
// область отсечения
LONG m_lClipLeft;
LONG m_lClipTop;
LONG m_lClipWidth;
LONG m_lClipHeight;
// пикселы
BYTE* m_pPixels;
Aggplus::CDIB* m_pDIB;
CImageFilesCache* m_pCache;
double m_dGlobalAlpha;
INT m_bGlobalAlphaEnabled;
public:
CGraphicsRenderer();
~CGraphicsRenderer();
public:
void SetImageCache(CImageFilesCache* pCache);
void SetFontManager(CFontManager* pManager = NULL);
void CheckFontManager();
CFontManager* GetFontManager();
BYTE* GetPixels(LONG& lWidth, LONG& lHeight);
void ClearInstallFont();
void SetClipRect(double x, double y, double w, double h);
protected:
INT CheckValidate(INT bOnlyGraphics = FALSE);
void Clear();
void UpdateSize();
public:
void SavePen(NSStructures::CPen& oPen) { oPen = m_oPen; }
void RestorePen(const NSStructures::CPen& oPen) { m_oPen = oPen; }
void SaveBrush(NSStructures::CBrush& oBrush) { oBrush = m_oBrush; }
void RestoreBrush(const NSStructures::CBrush& oBrush) { m_oBrush = oBrush; }
public:
// тип рендерера-----------------------------------------------------------------------------
virtual HRESULT get_Type(LONG* lType);
//-------- Функции для работы со страницей --------------------------------------------------
virtual HRESULT NewPage();
virtual HRESULT get_Height(double* dHeight);
virtual HRESULT put_Height(const double& dHeight);
virtual HRESULT get_Width(double* dWidth);
virtual HRESULT put_Width(const double& dWidth);
virtual HRESULT get_DpiX(double* dDpiX);
virtual HRESULT get_DpiY(double* dDpiY);
// pen --------------------------------------------------------------------------------------
virtual HRESULT get_PenColor(LONG* lColor);
virtual HRESULT put_PenColor(const LONG& lColor);
virtual HRESULT get_PenAlpha(LONG* lAlpha);
virtual HRESULT put_PenAlpha(const LONG& lAlpha);
virtual HRESULT get_PenSize(double* dSize);
virtual HRESULT put_PenSize(const double& dSize);
virtual HRESULT get_PenDashStyle(BYTE* val);
virtual HRESULT put_PenDashStyle(const BYTE& val);
virtual HRESULT get_PenLineStartCap(BYTE* val);
virtual HRESULT put_PenLineStartCap(const BYTE& val);
virtual HRESULT get_PenLineEndCap(BYTE* val);
virtual HRESULT put_PenLineEndCap(const BYTE& val);
virtual HRESULT get_PenLineJoin(BYTE* val);
virtual HRESULT put_PenLineJoin(const BYTE& val);
virtual HRESULT get_PenDashOffset(double* dOffset);
virtual HRESULT put_PenDashOffset(const double& dOffset);
virtual HRESULT get_PenAlign(LONG* lAlign);
virtual HRESULT put_PenAlign(const LONG& lAlign);
virtual HRESULT get_PenMiterLimit(double* dOffset);
virtual HRESULT put_PenMiterLimit(const double& dOffset);
virtual HRESULT PenDashPattern(double* pPattern, LONG lCount);
// brush ------------------------------------------------------------------------------------
virtual HRESULT get_BrushType(LONG* lType);
virtual HRESULT put_BrushType(const LONG& lType);
virtual HRESULT get_BrushColor1(LONG* lColor);
virtual HRESULT put_BrushColor1(const LONG& lColor);
virtual HRESULT get_BrushAlpha1(LONG* lAlpha);
virtual HRESULT put_BrushAlpha1(const LONG& lAlpha);
virtual HRESULT get_BrushColor2(LONG* lColor);
virtual HRESULT put_BrushColor2(const LONG& lColor);
virtual HRESULT get_BrushAlpha2(LONG* lAlpha);
virtual HRESULT put_BrushAlpha2(const LONG& lAlpha);
virtual HRESULT get_BrushTexturePath(std::wstring* bsPath);
virtual HRESULT put_BrushTexturePath(const std::wstring& bsPath);
virtual HRESULT get_BrushTextureMode(LONG* lMode);
virtual HRESULT put_BrushTextureMode(const LONG& lMode);
virtual HRESULT get_BrushTextureAlpha(LONG* lTxAlpha);
virtual HRESULT put_BrushTextureAlpha(const LONG& lTxAlpha);
virtual HRESULT get_BrushLinearAngle(double* dAngle);
virtual HRESULT put_BrushLinearAngle(const double& dAngle);
virtual HRESULT BrushRect(const INT& val, const double& left, const double& top, const double& width, const double& height);
virtual HRESULT BrushBounds(const double& left, const double& top, const double& width, const double& height);
virtual HRESULT put_BrushGradientColors(LONG* lColors, double* pPositions, LONG nCount);
// font -------------------------------------------------------------------------------------
virtual HRESULT get_FontName(std::wstring* bsName);
virtual HRESULT put_FontName(const std::wstring& bsName);
virtual HRESULT get_FontPath(std::wstring* bsName);
virtual HRESULT put_FontPath(const std::wstring& bsName);
virtual HRESULT get_FontSize(double* dSize);
virtual HRESULT put_FontSize(const double& dSize);
virtual HRESULT get_FontStyle(LONG* lStyle);
virtual HRESULT put_FontStyle(const LONG& lStyle);
virtual HRESULT get_FontStringGID(INT* bGID);
virtual HRESULT put_FontStringGID(const INT& bGID);
virtual HRESULT get_FontCharSpace(double* dSpace);
virtual HRESULT put_FontCharSpace(const double& dSpace);
virtual HRESULT get_FontFaceIndex(int* lFaceIndex);
virtual HRESULT put_FontFaceIndex(const int& lFaceIndex);
//-------- Функции для вывода текста --------------------------------------------------------
virtual HRESULT CommandDrawTextCHAR(const LONG& c, const double& x, const double& y, const double& w, const double& h, const double& baselineOffset);
virtual HRESULT CommandDrawText(const std::wstring& bsText, const double& x, const double& y, const double& w, const double& h, const double& baselineOffset);
virtual HRESULT CommandDrawTextExCHAR(const LONG& c, const LONG& gid, const double& x, const double& y, const double& w, const double& h, const double& baselineOffset, const DWORD& lFlags);
virtual HRESULT CommandDrawTextEx(const std::wstring& bsUnicodeText, const std::wstring& bsGidText, const double& x, const double& y, const double& w, const double& h, const double& baselineOffset, const DWORD& lFlags);
//-------- Маркеры для команд ---------------------------------------------------------------
virtual HRESULT BeginCommand(const DWORD& lType);
virtual HRESULT EndCommand(const DWORD& lType);
//-------- Функции для работы с Graphics Path -----------------------------------------------
virtual HRESULT PathCommandMoveTo(const double& x, const double& y);
virtual HRESULT PathCommandLineTo(const double& x, const double& y);
virtual HRESULT PathCommandLinesTo(double* points, const int& count);
virtual HRESULT PathCommandCurveTo(const double& x1, const double& y1, const double& x2, const double& y2, const double& x3, const double& y3);
virtual HRESULT PathCommandCurvesTo(double* points, const int& count);
virtual HRESULT PathCommandArcTo(const double& x, const double& y, const double& w, const double& h, const double& startAngle, const double& sweepAngle);
virtual HRESULT PathCommandClose();
virtual HRESULT PathCommandEnd();
virtual HRESULT DrawPath(const LONG& nType);
virtual HRESULT PathCommandStart();
virtual HRESULT PathCommandGetCurrentPoint(double* x, double* y);
virtual HRESULT PathCommandTextCHAR(const LONG& c, const double& x, const double& y, const double& w, const double& h, const double& baselineOffset);
virtual HRESULT PathCommandText(const std::wstring& bsText, const double& x, const double& y, const double& w, const double& h, const double& baselineOffset);
virtual HRESULT PathCommandTextExCHAR(const LONG& c, const LONG& gid, const double& x, const double& y, const double& w, const double& h, const double& baselineOffset, const DWORD& lFlags);
virtual HRESULT PathCommandTextEx(const std::wstring& bsUnicodeText, const std::wstring& bsGidText, const double& x, const double& y, const double& w, const double& h, const double& baselineOffset, const DWORD& lFlags);
//-------- Функции для вывода изображений ---------------------------------------------------
virtual HRESULT DrawImage(IGrObject* pImage, const double& x, const double& y, const double& w, const double& h);
virtual HRESULT DrawImageFromFile(const std::wstring& sFile, const double& x, const double& y, const double& w, const double& h, const BYTE& lAlpha = 255);
// transform --------------------------------------------------------------------------------
virtual HRESULT SetTransform(const double& m1, const double& m2, const double& m3, const double& m4, const double& m5, const double& m6);
virtual HRESULT GetTransform(double *pdA, double *pdB, double *pdC, double *pdD, double *pdE, double *pdF);
virtual HRESULT ResetTransform();
// -----------------------------------------------------------------------------------------
virtual HRESULT get_ClipMode(LONG* plMode);
virtual HRESULT put_ClipMode(const LONG& lMode);
// additiaonal params ----------------------------------------------------------------------
virtual HRESULT CommandLong(const LONG& lType, const LONG& lCommand);
virtual HRESULT CommandDouble(const LONG& lType, const double& dCommand);
virtual HRESULT CommandString(const LONG& lType, const std::wstring& sCommand);
void put_GlobalAlphaEnabled(const bool& bEnabled, const double& dVal);
inline void put_IntegerGrid(const bool& bEnabled)
{
if (!m_pRenderer)
return;
m_pRenderer->m_bIntegerGrid = bEnabled;
}
inline bool get_IntegerGrid()
{
if (!m_pRenderer)
return false;
return m_pRenderer->m_bIntegerGrid;
}
void AddRect(const double& x, const double& y, const double& w, const double& h);
inline void SetFontAttack()
{
_SetFont();
}
protected:
void _SetFont();
void ApplyTransform(const double& d1, const double& d2, const double& d3, const double& d4, const double& d5, const double& d6);
void ApplyTransform(Aggplus::CMatrix* pMatrix);
void _ResetTransform();
Aggplus::CBrush* CreateBrush(NSStructures::CBrush* pBrush);
public:
void CreateFromBgraFrame(CBgraFrame* pFrame);
void Create(BYTE* pPixels, const Aggplus::CDoubleRect& oRect, LONG lWidthControl, LONG lHeightControl, Aggplus::CDIB* pDib = NULL);
void CreateFlip(BYTE* pPixels, const Aggplus::CDoubleRect& oRect, LONG lWidthControl, LONG lHeightControl, Aggplus::CDIB* pDib = NULL);
inline Aggplus::CMatrix* GetFullTransform()
{
return m_pRenderer->GetFullTransform();
}
inline Aggplus::CMatrix* GetTransformMatrix()
{
return m_pRenderer->GetTransform();
}
inline void SetCoordTransformOffset(double dOffsetX, double dOffsetY)
{
Aggplus::CMatrix* pCoord = m_pRenderer->GetCoordTransform();
pCoord->m_agg_mtx.tx = dOffsetX;
pCoord->m_agg_mtx.ty = dOffsetY;
m_pRenderer->CalculateFullTransform();
}
inline void CalculateFullTransform()
{
m_pRenderer->CalculateFullTransform();
}
public:
inline void PathCommandRect(double x, double y, double w, double h)
{
PathCommandMoveTo(x, y);
PathCommandLineTo(x + w, y);
PathCommandLineTo(x + w, y + h);
PathCommandLineTo(x, y + h);
PathCommandClose();
}
inline Aggplus::CMatrix* GetCoordTransform()
{
return m_pRenderer->GetCoordTransform();
}
inline void Fill()
{
DrawPath(c_nWindingFillMode);
}
inline void Stroke()
{
DrawPath(1);
}
inline double GetPixW() { return m_pRenderer->GetPixW(); }
inline double GetPixH() { return m_pRenderer->GetPixH(); }
// smart methods
void drawHorLine(BYTE align, double y, double x, double r, double penW)
{
int pen_w = (int)((m_pRenderer->GetDpiX() * penW / 25.4) + 0.5);
if (0 == pen_w)
pen_w = 1;
double __x = x;
double __y1 = y;
double __r = r;
double __y2 = y;
Aggplus::CMatrix* pMatrix = GetFullTransform();
pMatrix->TransformPoint(__x, __y1);
pMatrix->TransformPoint(__r, __y2);
double _x = (int)__x;
double _r = (int)__r + 1;
m_oPen.Size = pen_w;
switch (align)
{
case 0:
{
double _top = (int)__y1 + 0.5;
_top = _top + pen_w / 2.0 - 0.5;
m_pPath->Reset();
m_pPath->MoveTo(_x, _top);
m_pPath->LineTo(_r, _top);
Stroke();
break;
}
case 1:
{
// center
double _center = (int)__y1 + 0.5;
m_pPath->Reset();
if (0 == (pen_w % 2))
{
m_pPath->MoveTo(_x, _center - 0.5);
m_pPath->LineTo(_r, _center - 0.5);
}
else
{
m_pPath->MoveTo(_x, _center);
m_pPath->LineTo(_r, _center);
}
Stroke();
break;
}
case 2:
{
double _bottom = (int)__y1 + 0.5;
_bottom = _bottom - pen_w / 2.0 + 0.5;
m_pPath->Reset();
m_pPath->MoveTo(_x, _bottom);
m_pPath->LineTo(_r, _bottom);
Stroke();
break;
}
}
}
void drawHorLine2(BYTE align, double y, double x, double r, double penW)
{
int pen_w = (int)((m_pRenderer->GetDpiX() * penW / 25.4) + 0.5);
if (0 == pen_w)
pen_w = 1;
double __x = x;
double __y1 = y;
double __r = r;
double __y2 = y;
Aggplus::CMatrix* pMatrix = GetFullTransform();
pMatrix->TransformPoint(__x, __y1);
pMatrix->TransformPoint(__r, __y2);
double _x = (int)__x;
double _r = (int)__r + 1;
switch (align)
{
case 0:
{
// top
double _top = (int)__y1 + 0.5;
double _pos1 = _top + pen_w / 2.0 - 0.5 - pen_w;
double _pos2 = _pos1 + pen_w * 2.0;
m_pPath->Reset();
m_pPath->MoveTo(_x, _pos1);
m_pPath->LineTo(_r, _pos1);
Stroke();
m_pPath->Reset();
m_pPath->MoveTo(_x, _pos2);
m_pPath->LineTo(_r, _pos2);
Stroke();
break;
}
case 1:
{
// center
// TODO:
break;
}
case 2:
{
// bottom
// TODO:
break;
}
}
}
void drawVerLine(BYTE align, double x, double y, double b, double penW)
{
int pen_w = (int)((m_pRenderer->GetDpiX() * penW / 25.4) + 0.5);
if (0 == pen_w)
pen_w = 1;
double __x1 = x;
double __y = y;
double __x2 = x;
double __b = b;
Aggplus::CMatrix* pMatrix = GetFullTransform();
pMatrix->TransformPoint(__x1, __y);
pMatrix->TransformPoint(__x2, __b);
double _y = (int)__y;
double _b = (int)__b + 1;
m_oPen.Size = pen_w;
switch (align)
{
case 0:
{
// left
double _left = (int)__x1 + 0.5;
_left = _left + pen_w / 2.0 - 0.5;
m_pPath->Reset();
m_pPath->MoveTo(_left, _y);
m_pPath->LineTo(_left, _b);
Stroke();
break;
}
case 1:
{
// center
double _center = (int)__x1 + 0.5;
m_pPath->Reset();
if (0 == (pen_w % 2))
{
m_pPath->MoveTo(_center - 0.5, _y);
m_pPath->LineTo(_center - 0.5, _b);
}
else
{
m_pPath->MoveTo(_center, _y);
m_pPath->LineTo(_center, _b);
}
Stroke();
break;
}
case 2:
{
// right
double _right = (int)__x1 + 0.5;
_right = _right - pen_w / 2.0 + 0.5;
m_pPath->Reset();
m_pPath->MoveTo(_right, _y);
m_pPath->LineTo(_right, _b);
Stroke();
break;
}
}
}
void drawHorLineExt(BYTE align, double y, double x, double r, double penW, double leftMW, double rightMW)
{
int pen_w = (int)((m_pRenderer->GetDpiX() * penW / 25.4) + 0.5);
if (0 == pen_w)
pen_w = 1;
double __x = x;
double __y1 = y;
double __r = r;
double __y2 = y;
Aggplus::CMatrix* pMatrix = GetFullTransform();
pMatrix->TransformPoint(__x, __y1);
pMatrix->TransformPoint(__r, __y2);
double _x = (int)__x + 0.5;
double _r = (int)__r + 0.5;
if (leftMW != 0)
{
double _center = _x;
int pen_mw = (int)((m_pRenderer->GetDpiX() * abs(leftMW) * 2 / 25.4) + 0.5);
if (0 == pen_mw)
pen_mw = 1;
if (leftMW < 0)
{
_x = _center - (pen_mw >> 1);
}
else
{
_x = _center + ((pen_mw - 1) >> 1);
}
}
if (rightMW != 0)
{
double _center = _r;
int pen_mw = (int)((m_pRenderer->GetDpiX() * abs(rightMW) * 2 / 25.4) + 0.5);
if (0 == pen_mw)
pen_mw = 1;
if (rightMW < 0)
{
_r = _center - (pen_mw >> 1);
}
else
{
_r = _center + ((pen_mw - 1) >> 1);
}
}
m_oPen.Size = pen_w;
_x -= 0.5;
_r += 0.5;
switch (align)
{
case 0:
{
// top
double _top = (int)__y1 + 0.5;
_top = _top + pen_w / 2.0 - 0.5;
m_pPath->Reset();
m_pPath->MoveTo(_x, _top);
m_pPath->LineTo(_r, _top);
Stroke();
break;
}
case 1:
{
// center
double _center = (int)__y1 + 0.5;
m_pPath->Reset();
if (0 == (pen_w % 2))
{
m_pPath->MoveTo(_x, _center - 0.5);
m_pPath->LineTo(_r, _center - 0.5);
}
else
{
m_pPath->MoveTo(_x, _center);
m_pPath->LineTo(_r, _center);
}
Stroke();
break;
}
case 2:
{
// bottom
double _bottom = (int)__y1 + 0.5;
_bottom = _bottom - pen_w / 2.0 + 0.5;
m_pPath->Reset();
m_pPath->MoveTo(_x, _bottom);
m_pPath->LineTo(_r, _bottom);
Stroke();
break;
}
}
}
};
#endif // _BUILD_GRAPHICS_RENDERER_H_
#ifndef _BUILD_IRENDERER_H_
#define _BUILD_IRENDERER_H_
#pragma once
#include "../common/Types.h"
#include "Matrix.h"
#include <string>
#ifdef __APPLE__
#include <libkern/OSAtomic.h>
#endif
class IGrObject
{
protected:
#ifdef __APPLE__
volatile int32_t m_lRef;
#else
ULONG m_lRef;
#endif
public:
IGrObject()
{
m_lRef = 1;
}
virtual ~IGrObject()
{
}
#ifdef __APPLE__
virtual ULONG AddRef()
{
OSAtomicIncrement32(&m_lRef);
return (ULONG)m_lRef;
}
virtual ULONG Release()
{
int32_t ret = OSAtomicDecrement32(&m_lRef);
if (0 == m_lRef)
delete this;
return (ULONG)ret;
}
#else
virtual ULONG AddRef()
{
++m_lRef;
return m_lRef;
}
virtual ULONG Release()
{
ULONG ret = --m_lRef;
if (0 == m_lRef)
delete this;
return ret;
}
#endif
};
// тип в DrawPath
const long c_nStroke = 0x0001;
const long c_nWindingFillMode = 0x0100;
const long c_nEvenOddFillMode = 0x0200;
// тип в BeginCommand, EndCommand
const long c_nNone = 0x0000;
const long c_nPageType = 0x0001;
const long c_nTextType = 0x0002;
const long c_nImageType = 0x0003;
const long c_nPathType = 0x0004;
const long c_nNumberingMarker = 0x0005;
const long c_nHyperlinkType = 0x0008;
const long c_nWatermarkType = 0x0010;
const long c_nClipType = 0x0020;
const long c_nResetClipType = 0x0040;
const long c_nTextGraphicType = 0x0080;
const long c_nStrokeTextType = 0x0100;
const long c_nSimpleGraphicType = 0x0200;
const long c_nParagraphType = 0x0400;
const long c_nComplexFigureType = 0x0800;
const long c_nPDFGradientType = 0x1000;
const long c_nTableCell = 0x2000;
const long c_nPDFTilingFill = 0x2001;
const long c_nPDFTilingFillIteration = 0x2002;
const long c_nHeader = 0xa000;
const long c_nColumnCount = 0xa001;
const long c_nFootnote = 0xa002;
const long c_nPageBreak = 0xa003;
const long c_nShape = 0xa010;
const long c_nShapeGroup = 0xa011;
const long c_nShapeWrap = 0xa012;
const long c_nTable = 0xa020;
const long c_nTableXml = 0xa021;
const long c_nTableTop = 0xa022;
const long c_nBlock = 0xa030;
const long c_nBlockHeadingLevel = 0xa031;
const long c_nBlockNumberingLevel = 0xa032;
const long c_nBlockHorzAlign = 0xa033;
const long c_nLine = 0xa040;
const long c_nBaselineShift = 0xa041;
// типы клипа
const long c_nClipRegionTypeWinding = 0x0000;
const long c_nClipRegionTypeEvenOdd = 0x0001;
// тип объединения клипов
const long c_nClipRegionIntersect = 0x0000;
const long c_nClipRegionUnion = 0x0100;
// флаги в CommandDrawTextEx
const long c_nFlagNone = 0x0000;
const long c_nFlagHyperlink = 0x0001;
// флаги в CommandParams
const long c_nParamFlipX = 0x0001;
const long c_nParamFlipY = 0x0002;
const long c_nFlipNextRotate = 0x0004;
// типы рендерера
const long c_nUnknownRenderer = 0x0000;
const long c_nPDFWriter = 0x0001;
const long c_nHtmlRendrerer = 0x0002;
const long c_nSVGRendrerer = 0x0003;
const long c_nSWFRenderer = 0x0004;
const long c_nSVGConverter = 0x0005;
const long c_nHtmlRendrerer2 = 0x0006;
const long c_nEbookWriter = 0x0007;
const long c_nDocxWriter = 0x0008;
const long c_nVifFormat = 0x0009;
const long c_nGrRenderer = 0x0010;
// IRenderer
class IRenderer : public IGrObject
{
public:
// тип рендерера-----------------------------------------------------------------------------
virtual HRESULT get_Type(LONG* lType) = 0;
//-------- Функции для работы со страницей --------------------------------------------------
virtual HRESULT NewPage() = 0;
virtual HRESULT get_Height(double* dHeight) = 0;
virtual HRESULT put_Height(const double& dHeight) = 0;
virtual HRESULT get_Width(double* dWidth) = 0;
virtual HRESULT put_Width(const double& dWidth) = 0;
virtual HRESULT get_DpiX(double* dDpiX) = 0;
virtual HRESULT get_DpiY(double* dDpiY) = 0;
// pen --------------------------------------------------------------------------------------
virtual HRESULT get_PenColor(LONG* lColor) = 0;
virtual HRESULT put_PenColor(const LONG& lColor) = 0;
virtual HRESULT get_PenAlpha(LONG* lAlpha) = 0;
virtual HRESULT put_PenAlpha(const LONG& lAlpha) = 0;
virtual HRESULT get_PenSize(double* dSize) = 0;
virtual HRESULT put_PenSize(const double& dSize) = 0;
virtual HRESULT get_PenDashStyle(BYTE* val) = 0;
virtual HRESULT put_PenDashStyle(const BYTE& val) = 0;
virtual HRESULT get_PenLineStartCap(BYTE* val) = 0;
virtual HRESULT put_PenLineStartCap(const BYTE& val) = 0;
virtual HRESULT get_PenLineEndCap(BYTE* val) = 0;
virtual HRESULT put_PenLineEndCap(const BYTE& val) = 0;
virtual HRESULT get_PenLineJoin(BYTE* val) = 0;
virtual HRESULT put_PenLineJoin(const BYTE& val) = 0;
virtual HRESULT get_PenDashOffset(double* dOffset) = 0;
virtual HRESULT put_PenDashOffset(const double& dOffset) = 0;
virtual HRESULT get_PenAlign(LONG* lAlign) = 0;
virtual HRESULT put_PenAlign(const LONG& lAlign) = 0;
virtual HRESULT get_PenMiterLimit(double* dOffset) = 0;
virtual HRESULT put_PenMiterLimit(const double& dOffset) = 0;
virtual HRESULT PenDashPattern(double* pPattern, LONG lCount)= 0;
// brush ------------------------------------------------------------------------------------
virtual HRESULT get_BrushType(LONG* lType) = 0;
virtual HRESULT put_BrushType(const LONG& lType) = 0;
virtual HRESULT get_BrushColor1(LONG* lColor) = 0;
virtual HRESULT put_BrushColor1(const LONG& lColor) = 0;
virtual HRESULT get_BrushAlpha1(LONG* lAlpha) = 0;
virtual HRESULT put_BrushAlpha1(const LONG& lAlpha) = 0;
virtual HRESULT get_BrushColor2(LONG* lColor) = 0;
virtual HRESULT put_BrushColor2(const LONG& lColor) = 0;
virtual HRESULT get_BrushAlpha2(LONG* lAlpha) = 0;
virtual HRESULT put_BrushAlpha2(const LONG& lAlpha) = 0;
virtual HRESULT get_BrushTexturePath(std::wstring* bsPath) = 0;
virtual HRESULT put_BrushTexturePath(const std::wstring& bsPath) = 0;
virtual HRESULT get_BrushTextureMode(LONG* lMode) = 0;
virtual HRESULT put_BrushTextureMode(const LONG& lMode) = 0;
virtual HRESULT get_BrushTextureAlpha(LONG* lTxAlpha) = 0;
virtual HRESULT put_BrushTextureAlpha(const LONG& lTxAlpha) = 0;
virtual HRESULT get_BrushLinearAngle(double* dAngle) = 0;
virtual HRESULT put_BrushLinearAngle(const double& dAngle) = 0;
virtual HRESULT BrushRect(const INT& val, const double& left, const double& top, const double& width, const double& height) = 0;
virtual HRESULT BrushBounds(const double& left, const double& top, const double& width, const double& height) = 0;
virtual HRESULT put_BrushGradientColors(LONG* lColors, double* pPositions, LONG nCount) = 0;
// font -------------------------------------------------------------------------------------
virtual HRESULT get_FontName(std::wstring* bsName) = 0;
virtual HRESULT put_FontName(const std::wstring& bsName) = 0;
virtual HRESULT get_FontPath(std::wstring* bsName) = 0;
virtual HRESULT put_FontPath(const std::wstring& bsName) = 0;
virtual HRESULT get_FontSize(double* dSize) = 0;
virtual HRESULT put_FontSize(const double& dSize) = 0;
virtual HRESULT get_FontStyle(LONG* lStyle) = 0;
virtual HRESULT put_FontStyle(const LONG& lStyle) = 0;
virtual HRESULT get_FontStringGID(INT* bGID) = 0;
virtual HRESULT put_FontStringGID(const INT& bGID) = 0;
virtual HRESULT get_FontCharSpace(double* dSpace) = 0;
virtual HRESULT put_FontCharSpace(const double& dSpace) = 0;
virtual HRESULT get_FontFaceIndex(int* lFaceIndex) = 0;
virtual HRESULT put_FontFaceIndex(const int& lFaceIndex) = 0;
//-------- Функции для вывода текста --------------------------------------------------------
virtual HRESULT CommandDrawTextCHAR(const LONG& c, const double& x, const double& y, const double& w, const double& h, const double& baselineOffset) = 0;
virtual HRESULT CommandDrawText(const std::wstring& bsText, const double& x, const double& y, const double& w, const double& h, const double& baselineOffset) = 0;
virtual HRESULT CommandDrawTextExCHAR(const LONG& c, const LONG& gid, const double& x, const double& y, const double& w, const double& h, const double& baselineOffset, const DWORD& lFlags) = 0;
virtual HRESULT CommandDrawTextEx(const std::wstring& bsUnicodeText, const std::wstring& bsGidText, const double& x, const double& y, const double& w, const double& h, const double& baselineOffset, const DWORD& lFlags) = 0;
//-------- Маркеры для команд ---------------------------------------------------------------
virtual HRESULT BeginCommand(const DWORD& lType) = 0;
virtual HRESULT EndCommand(const DWORD& lType) = 0;
//-------- Функции для работы с Graphics Path -----------------------------------------------
virtual HRESULT PathCommandMoveTo(const double& x, const double& y) = 0;
virtual HRESULT PathCommandLineTo(const double& x, const double& y) = 0;
virtual HRESULT PathCommandLinesTo(double* points, const int& count) = 0;
virtual HRESULT PathCommandCurveTo(const double& x1, const double& y1, const double& x2, const double& y2, const double& x3, const double& y3) = 0;
virtual HRESULT PathCommandCurvesTo(double* points, const int& count) = 0;
virtual HRESULT PathCommandArcTo(const double& x, const double& y, const double& w, const double& h, const double& startAngle, const double& sweepAngle) = 0;
virtual HRESULT PathCommandClose() = 0;
virtual HRESULT PathCommandEnd() = 0;
virtual HRESULT DrawPath(const LONG& nType) = 0;
virtual HRESULT PathCommandStart() = 0;
virtual HRESULT PathCommandGetCurrentPoint(double* x, double* y) = 0;
virtual HRESULT PathCommandTextCHAR(const LONG& c, const double& x, const double& y, const double& w, const double& h, const double& baselineOffset) = 0;
virtual HRESULT PathCommandText(const std::wstring& bsText, const double& x, const double& y, const double& w, const double& h, const double& baselineOffset) = 0;
virtual HRESULT PathCommandTextExCHAR(const LONG& c, const LONG& gid, const double& x, const double& y, const double& w, const double& h, const double& baselineOffset, const DWORD& lFlags) = 0;
virtual HRESULT PathCommandTextEx(const std::wstring& bsUnicodeText, const std::wstring& bsGidText, const double& x, const double& y, const double& w, const double& h, const double& baselineOffset, const DWORD& lFlags) = 0;
//-------- Функции для вывода изображений ---------------------------------------------------
virtual HRESULT DrawImage(IGrObject* pImage, const double& x, const double& y, const double& w, const double& h) = 0;
virtual HRESULT DrawImageFromFile(const std::wstring&, const double& x, const double& y, const double& w, const double& h, const BYTE& lAlpha = 255) = 0;
// transform --------------------------------------------------------------------------------
virtual HRESULT GetCommandParams(double* dAngle, double* dLeft, double* dTop, double* dWidth, double* dHeight, DWORD* lFlags)
{
return S_OK;
}
virtual HRESULT SetCommandParams(double dAngle, double dLeft, double dTop, double dWidth, double dHeight, DWORD lFlags)
{
if ((dWidth <= 1) || (dHeight <= 1))
lFlags = 0;
INT bFlipX = (0 != (c_nParamFlipX & lFlags));
INT bFlipY = (0 != (c_nParamFlipY & lFlags));
float m11 = bFlipX ? -1.0f : 1.0f;
float m22 = bFlipY ? -1.0f : 1.0f;
Aggplus::CMatrix oMatrix(1, 0, 0, 1, 0, 0);
if ((0 != dAngle) || (0 != lFlags))
{
double dCentreX = (double)(dLeft + dWidth / 2.0);
double dCentreY = (double)(dTop + dHeight / 2.0);
oMatrix.Translate(-dCentreX, -dCentreY , Aggplus::MatrixOrderAppend);
oMatrix.Rotate(dAngle , Aggplus::MatrixOrderAppend);
oMatrix.Scale(m11, m22 , Aggplus::MatrixOrderAppend);
oMatrix.Translate(dCentreX, dCentreY , Aggplus::MatrixOrderAppend);
}
double mass[6];
oMatrix.GetElements(mass);
SetTransform(mass[0], mass[1], mass[2], mass[3], mass[4], mass[5]);
return S_OK;
}
virtual HRESULT SetTransform(const double& m1, const double& m2, const double& m3, const double& m4, const double& m5, const double& m6) = 0;
virtual HRESULT GetTransform(double *pdA, double *pdB, double *pdC, double *pdD, double *pdE, double *pdF) = 0;
virtual HRESULT ResetTransform() = 0;
// -----------------------------------------------------------------------------------------
virtual HRESULT get_ClipMode(LONG* plMode) = 0;
virtual HRESULT put_ClipMode(const LONG& lMode) = 0;
// additiaonal params ----------------------------------------------------------------------
virtual HRESULT CommandLong(const LONG& lType, const LONG& lCommand) = 0;
virtual HRESULT CommandDouble(const LONG& lType, const double& dCommand) = 0;
virtual HRESULT CommandString(const LONG& lType, const std::wstring& sCommand) = 0;
};
#define PROPERTY_RENDERER(NameBase, Name, Type) \
STDMETHOD(get_##NameBase##Name)(Type* pVal) \
{ \
if (NULL == pVal) \
return S_FALSE; \
*pVal = m_o##NameBase.##Name; \
return S_OK; \
} \
STDMETHOD(put_##NameBase##Name)(Type Val) \
{ \
m_o##NameBase.##Name = Val; \
return S_OK; \
}
// exapmle:
// PROPERTY_RENDERER(Pen, Color, LONG)
// PROPERTY_RENDERER(Pen, Alpha, LONG)
#endif // _BUILD_IRENDERER_H_
\ No newline at end of file
#include "Image.h"
#include "../raster/BgraFrame.h"
#include <cstring> // memset
namespace Aggplus
{
////////////////////////////////////////////////////////////////////////////////////////
CImage::CImage() : m_dwWidth(0), m_dwHeight(0),
m_nStride(0), m_pImgData(NULL),
m_bExternalBuffer(false), m_Status(WrongState)
{
}
CImage::CImage(const std::wstring& filename) : m_dwWidth(0), m_dwHeight(0),
m_nStride(0), m_pImgData(NULL),
m_bExternalBuffer(false)
{
Create(filename);
}
CImage::~CImage()
{
Destroy();
}
void CImage::Create(const std::wstring& filename)
{
Destroy();
CBgraFrame oFrame;
bool bOpen = oFrame.OpenFile(filename);
if (bOpen)
{
m_pImgData = oFrame.get_Data();
m_dwWidth = (DWORD)oFrame.get_Width();
m_dwHeight = (DWORD)oFrame.get_Height();
m_nStride = oFrame.get_Stride();
m_Status = Ok;
}
oFrame.ClearNoAttack();
}
void CImage::Create(BYTE* pImgData, const DWORD& dwWidth, const DWORD& dwHeight, const long& nStride)
{
m_pImgData = pImgData;
m_dwWidth = dwWidth;
m_dwHeight = dwHeight;
m_nStride = nStride;
m_bExternalBuffer = false;
m_Status = Ok;
}
bool CImage::SaveFile(const std::wstring& strFileName, UINT nFileType)
{
CBgraFrame oBgraFrame;
oBgraFrame.put_Width(m_dwWidth);
oBgraFrame.put_Height(m_dwHeight);
oBgraFrame.put_Stride(m_nStride);
oBgraFrame.put_Data(m_pImgData);
bool bRes = oBgraFrame.SaveFile(strFileName, nFileType);
//чтобы не удалялся на destructor
oBgraFrame.put_Data(NULL);
return bRes;
}
void CImage::Destroy()
{
if (NULL != m_pImgData)
{
if (!m_bExternalBuffer)
{
delete [] m_pImgData;
}
}
m_Status = WrongState;
m_pImgData = NULL;
m_dwWidth = 0;
m_dwHeight = 0;
m_nStride = 0;
m_bExternalBuffer = false;
}
DWORD CImage::GetWidth() const { return(m_dwWidth); }
DWORD CImage::GetHeight() const { return(m_dwHeight); }
long CImage::GetStride() const { return(m_nStride); }
BYTE* CImage::GetData() const { return(m_pImgData); }
Status CImage::GetLastStatus() const { return(m_Status); }
////////////////////////////////////////////////////////////////////////////////////////
CBitmap::CBitmap(LONG width, LONG height, PixelFormat format) : CImage()
{
if(width <= 0 || height <= 0)
{
m_Status=InvalidParameter;
return;
}
LONG lSize = 4 * width * height;
m_pImgData = new BYTE[lSize];
if (m_pImgData)
{
memset(m_pImgData, 0, lSize);
m_dwWidth = width;
m_dwHeight = height;
m_nStride = 4 * m_dwWidth;
m_Status = Ok;
}
}
CBitmap::CBitmap(LONG width, LONG height, LONG stride, PixelFormat format, BYTE* scan0) : CImage()
{
//Warning! This is not Gdiplus behavior; it returns Ok!
if(width <= 0 || height <= 0 || stride == 0)
{
m_Status = InvalidParameter;
return;
}
m_bExternalBuffer = true;
if (stride > 0)
{
m_pImgData = scan0;
}
else
{
m_pImgData = scan0 + (height - 1) * (-stride);
}
m_dwWidth = width;
m_dwHeight = height;
m_nStride = stride;
m_Status = Ok;
}
CBitmap::CBitmap(const std::wstring& filename) : CImage(filename)
{
}
CBitmap::~CBitmap()
{
}
void CBitmap::LockBits(const RectF* rect, PixelFormat format, CBitmapData* lockedBitmapData)
{
// TODO:
return;
}
}
#ifndef _BUILD_IMAGE_H_
#define _BUILD_IMAGE_H_
#include "AggPlusEnums.h"
#include <string>
#include "IRenderer.h"
namespace Aggplus
{
class CImage : public IGrObject
{
public:
friend class CGraphics;
friend class CBrushTexture;
public:
CImage();
CImage(const std::wstring& filename);
virtual ~CImage();
DWORD GetWidth() const;
DWORD GetHeight() const;
long GetStride() const;
BYTE* GetData() const;
Status GetLastStatus() const;
void Create(const std::wstring& filename);
void Create(BYTE* pImgData, const DWORD& dwWidth, const DWORD& dwHeight, const long& nStride);
bool SaveFile(const std::wstring& strFileName, UINT nFileType);
void Destroy();
public:
Status m_Status;
DWORD m_dwWidth;
DWORD m_dwHeight;
long m_nStride;
BYTE* m_pImgData;
bool m_bExternalBuffer;
};
//---------------------------------------------------------------------------
// Information about image pixel data
//---------------------------------------------------------------------------
class CBitmapData
{
public:
UINT Width;
UINT Height;
LONG Stride;
Aggplus::PixelFormat PixelFormat;
void* Scan0;
UINT* Reserved;
};
class CBitmap : public CImage
{
public:
CBitmap(LONG width, LONG height, PixelFormat format = PixelFormat32bppARGB);
CBitmap(LONG width, LONG height, LONG stride, PixelFormat format, BYTE* scan0);
CBitmap(const std::wstring& filename);
virtual ~CBitmap();
void LockBits(const RectF* rect, PixelFormat format, CBitmapData* lockedBitmapData);
};
}
#endif // _BUILD_IMAGE_H_
\ No newline at end of file
#ifndef _BUILD_IMAGEFILESCACHE_H_
#define _BUILD_IMAGEFILESCACHE_H_
#include "Image.h"
#include "TemporaryCS.h"
#include <map>
class CCacheImage
{
private:
Aggplus::CImage m_oImage;
LONG m_lRef;
public:
CCacheImage() : m_oImage()
{
m_lRef = 1;
}
CCacheImage(const std::wstring& strFile) : m_oImage(strFile)
{
m_lRef = 1;
}
LONG AddRef()
{
++m_lRef;
return m_lRef;
}
LONG Release()
{
--m_lRef;
if (0 == m_lRef)
{
delete this;
return 0;
}
return m_lRef;
}
Aggplus::CImage* GetImage()
{
return &m_oImage;
}
};
class CImageFilesCache
{
private:
std::map<std::wstring, CCacheImage*> m_mapImages;
LONG m_lMaxCount;
LONG m_lRef;
NSCriticalSection::CRITICAL_SECTION m_oCS;
public:
CImageFilesCache()
{
m_lMaxCount = 10;
m_lRef = 1;
m_oCS.InitializeCriticalSection();
}
~CImageFilesCache()
{
Clear();
m_oCS.DeleteCriticalSection();
}
void Clear()
{
CTemporaryCS oCS(&m_oCS);
for (std::map<std::wstring,CCacheImage*>::iterator it = m_mapImages.begin(); it != m_mapImages.end(); ++it)
{
it->second->Release();
}
m_mapImages.clear();
}
CCacheImage* Lock(const std::wstring& strFile)
{
CTemporaryCS oCS(&m_oCS);
std::map<std::wstring,CCacheImage*>::iterator it = m_mapImages.find(strFile);
if (it != m_mapImages.end())
{
CCacheImage* pImage = it->second;
pImage->AddRef();
return pImage;
}
int nCount = (int)m_mapImages.size();
if (nCount >= m_lMaxCount)
{
int nNeedDelete = nCount - m_lMaxCount;
std::map<std::wstring,CCacheImage*>::iterator it2 = m_mapImages.begin();
while (nNeedDelete > 0 && it2 != m_mapImages.end())
{
it2->second->Release();
m_mapImages.erase(it2);
it2++;
--nNeedDelete;
}
}
CCacheImage* pImage = new CCacheImage(strFile);
m_mapImages[strFile] = pImage;
pImage->AddRef();
return pImage;
}
LONG AddRef()
{
++m_lRef;
return m_lRef;
}
LONG Release()
{
m_oCS.Enter();
--m_lRef;
if (0 == m_lRef)
{
m_oCS.Leave();
delete this;
return 0;
}
m_oCS.Leave();
return m_lRef;
}
};
#endif // _BUILD_IMAGEFILESCACHE_H_
#include "Matrix.h"
namespace Aggplus
{
CMatrix::CMatrix(double m11, double m12, double m21, double m22, double dx, double dy) : m_agg_mtx(m11, m12, m21, m22, dx, dy)
{
}
CMatrix::CMatrix() : m_agg_mtx()
{
}
CMatrix::~CMatrix()
{
}
void CMatrix::Translate(double offsetX, double offsetY, MatrixOrder order)
{
if (order == MatrixOrderPrepend)
{
m_agg_mtx.premultiply(agg::trans_affine_translation(offsetX, offsetY));
}
else
{
m_agg_mtx.multiply(agg::trans_affine_translation(offsetX, offsetY));
}
}
void CMatrix::Scale(double scaleX, double scaleY, MatrixOrder order)
{
if (order == MatrixOrderPrepend)
{
m_agg_mtx.premultiply(agg::trans_affine_scaling(scaleX, scaleY));
}
else
{
m_agg_mtx.multiply(agg::trans_affine_scaling(scaleX, scaleY));
}
}
void CMatrix::Shear(double shearX, double shearY, MatrixOrder order)
{
if (order == MatrixOrderPrepend)
{
m_agg_mtx.premultiply(agg::trans_affine_skewing(shearX, shearY));
}
else
{
m_agg_mtx.multiply(agg::trans_affine_skewing(shearX, shearY));
}
}
void CMatrix::TransformVectors(PointF* pts, int count)
{
// Store matrix to an array [6] of double
double M[6]; m_agg_mtx.store_to(M);
for(int i = 0; i < count; ++i)
{
double x =pts[i].X;
double y =pts[i].Y;
m_agg_mtx.transform(&x, &y);
pts[i].X =(float)(x-M[4]);
pts[i].Y =(float)(y-M[5]);
}
}
void CMatrix::TransformPoints(PointF* pts, int count)
{
for(int i = 0; i < count; ++i)
{
double x = pts[i].X;
double y = pts[i].Y;
m_agg_mtx.transform(&x, &y);
pts[i].X = (float)x;
pts[i].Y = (float)y;
}
}
void CMatrix::TransformPoint(double& x, double& y)
{
m_agg_mtx.transform(&x, &y);
}
void CMatrix::Rotate(double angle, MatrixOrder order)
{
if (order == MatrixOrderPrepend)
{
m_agg_mtx.premultiply(agg::trans_affine_rotation(agg::deg2rad(angle)));
}
else
{
m_agg_mtx.multiply(agg::trans_affine_rotation(agg::deg2rad(angle)));
}
}
void CMatrix::RotateAt(double angle, const PointF &center, MatrixOrder order)
{
Translate(-center.X, -center.Y, order);
if(order == MatrixOrderPrepend)
{
m_agg_mtx.premultiply(agg::trans_affine_rotation(agg::deg2rad(angle)));
}
else
{
m_agg_mtx.multiply(agg::trans_affine_rotation(agg::deg2rad(angle)));
}
Translate(center.X, center.Y, order);
return;
}
void CMatrix::RotateAt(double angle, double x, double y, MatrixOrder order)
{
Translate(-x, -y, order);
if (order == MatrixOrderPrepend)
{
m_agg_mtx.premultiply(agg::trans_affine_rotation(agg::deg2rad(angle)));
}
else
{
m_agg_mtx.multiply(agg::trans_affine_rotation(agg::deg2rad(angle)));
}
Translate(x, y, order);
}
void CMatrix::Multiply(const CMatrix* matrix, MatrixOrder order)
{
if (order == MatrixOrderPrepend)
{
m_agg_mtx.premultiply(matrix->m_agg_mtx);
}
else
{
m_agg_mtx.multiply(matrix->m_agg_mtx);
}
}
double CMatrix::OffsetX() const
{
double M[6]; m_agg_mtx.store_to(M);
return (M[4]);
}
double CMatrix::OffsetY() const
{
double M[6]; m_agg_mtx.store_to(M);
return (M[5]);
}
Status CMatrix::GetElements(REAL* m) const
{
double M[6]; m_agg_mtx.store_to(M);
m[0]=(REAL)M[0];
m[1]=(REAL)M[1];
m[2]=(REAL)M[2];
m[3]=(REAL)M[3];
m[4]=(REAL)M[4];
m[5]=(REAL)M[5];
return Ok;
}
Status CMatrix::GetElements(double* m) const
{
m_agg_mtx.store_to(m);
return Ok;
}
void CMatrix::Reset()
{
m_agg_mtx.reset();
}
const CMatrix& CMatrix::operator=(const CMatrix& Src)
{
m_agg_mtx = Src.m_agg_mtx;
return *this;
}
Status CMatrix::Invert()
{
double d = m_agg_mtx.determinant();
if (0.0001 >= fabs(d))
return InvalidParameter;
m_agg_mtx.invert();
return Ok;
}
//Temp
//Used in X_BrushLinearGradient constructor
double CMatrix::z_Rotation() const
{
return agg::rad2deg(m_agg_mtx.rotation());
}
void CMatrix::TransformPoints( PointF* dst, const PointF* src, int count ) const
{
for(int i = 0; i < count; ++i)
{
double x = src[i].X * m_agg_mtx.sx + src[i].Y * m_agg_mtx.shx + m_agg_mtx.tx;
double y = src[i].Y * m_agg_mtx.sy + src[i].X * m_agg_mtx.shy + m_agg_mtx.ty;
dst[i].X = (float)x;
dst[i].Y = (float)y;
}
}
bool CMatrix::IsIdentity() const
{
return m_agg_mtx.is_identity();
}
bool CMatrix::IsIdentity2() const
{
return agg::is_equal_eps(m_agg_mtx.sx, 1.0, agg::affine_epsilon) &&
agg::is_equal_eps(m_agg_mtx.shy, 0.0, agg::affine_epsilon) &&
agg::is_equal_eps(m_agg_mtx.shx, 0.0, agg::affine_epsilon) &&
agg::is_equal_eps(m_agg_mtx.sy, 1.0, agg::affine_epsilon);
}
}
\ No newline at end of file
#ifndef _BUILD_MATRIX_H_
#define _BUILD_MATRIX_H_
#include "AggPlusEnums.h"
#include "../agg-2.4/include/agg_trans_affine.h"
namespace Aggplus
{
class CMatrix
{
friend class CGraphics;
friend class CGraphicsPath;
public:
CMatrix(double m11, double m12, double m21, double m22, double dx, double dy);
CMatrix();
~CMatrix();
void Translate(double offsetX, double offsetY, MatrixOrder order = MatrixOrderPrepend);
void Scale(double scaleX, double scaleY, MatrixOrder order = MatrixOrderPrepend);
void Shear(double shearX, double shearY, MatrixOrder order = MatrixOrderPrepend);
void TransformVectors(PointF* pts, int count);
void TransformPoints(PointF* pts, int count);
void TransformPoint(double& x, double& y);
void Rotate(double angle, MatrixOrder order = MatrixOrderPrepend);
void RotateAt(double angle, const PointF &center, MatrixOrder order = MatrixOrderPrepend);
void RotateAt(double angle, double x, double y, MatrixOrder order = MatrixOrderPrepend);
void Multiply(const CMatrix* matrix, MatrixOrder order = MatrixOrderPrepend);
double OffsetX() const;
double OffsetY() const;
Status GetElements(float* m) const;
Status GetElements(double* m) const;
void Reset();
bool IsIdentity() const;
bool IsIdentity2() const;
const CMatrix& operator=(const CMatrix& Src);
Status Invert();
//Temp
//Used in X_BrushLinearGradient constructor
double z_Rotation() const;
void TransformPoints( PointF* dst, const PointF* src, int count ) const;
public:
agg::trans_affine m_agg_mtx;
};
}
#endif // _BUILD_MATRIX_H_
\ No newline at end of file
#include "TemporaryCS.h"
#include "../common/Types.h"
#if defined(_WIN32) || defined(_WIN64) || defined(_WIN32_WCE)
#include "windows.h"
#include "winbase.h"
class __critical_section : public NSCriticalSection::CRITICAL_SECTION_NATIVE
{
private:
::CRITICAL_SECTION m_cs;
public:
virtual void Enter()
{
EnterCriticalSection(&m_cs);
}
virtual void Leave()
{
LeaveCriticalSection(&m_cs);
}
public:
static void InitializeCriticalSection(NSCriticalSection::CRITICAL_SECTION_NATIVE* pNative)
{
__critical_section* pCS = (__critical_section*)pNative;
::InitializeCriticalSection(&pCS->m_cs);
}
static void DeleteCriticalSection(NSCriticalSection::CRITICAL_SECTION_NATIVE* pNative)
{
__critical_section* pCS = (__critical_section*)pNative;
::DeleteCriticalSection(&pCS->m_cs);
}
};
#else
#include <pthread.h>
#ifndef PTHREAD_MUTEX_RECURSIVE_NP
#define PTHREAD_MUTEX_RECURSIVE_NP PTHREAD_MUTEX_RECURSIVE
#endif
class __critical_section : public NSCriticalSection::CRITICAL_SECTION_NATIVE
{
private:
pthread_mutex_t m_cs;
public:
virtual void Enter()
{
pthread_mutex_lock(&m_cs);
}
virtual void Leave()
{
pthread_mutex_unlock(&m_cs);
}
public:
static void InitializeCriticalSection(NSCriticalSection::CRITICAL_SECTION_NATIVE* pNative)
{
__critical_section* pCS = (__critical_section*)pNative;
pthread_mutexattr_t _attr;
pthread_mutexattr_init(&_attr);
pthread_mutexattr_settype(&_attr, PTHREAD_MUTEX_RECURSIVE_NP);
pthread_mutex_init(&pCS->m_cs, &_attr);
pthread_mutexattr_destroy(&_attr);
}
static void DeleteCriticalSection(NSCriticalSection::CRITICAL_SECTION_NATIVE* pNative)
{
__critical_section* pCS = (__critical_section*)pNative;
pthread_mutex_destroy(&pCS->m_cs);
}
};
#endif
namespace NSCriticalSection
{
CRITICAL_SECTION::CRITICAL_SECTION()
{
m_pCS = new __critical_section();
}
CRITICAL_SECTION::~CRITICAL_SECTION()
{
RELEASEOBJECT(m_pCS);
}
void CRITICAL_SECTION::InitializeCriticalSection()
{
__critical_section::InitializeCriticalSection(m_pCS);
}
void CRITICAL_SECTION::DeleteCriticalSection()
{
__critical_section::DeleteCriticalSection(m_pCS);
}
void CRITICAL_SECTION::Enter()
{
if (NULL != m_pCS)
m_pCS->Enter();
}
void CRITICAL_SECTION::Leave()
{
if (NULL != m_pCS)
m_pCS->Leave();
}
}
CTemporaryCS::CTemporaryCS(NSCriticalSection::CRITICAL_SECTION* cs)
{
cs->Enter();
m_cs = cs;
}
CTemporaryCS::~CTemporaryCS()
{
LeaveCS();
}
void CTemporaryCS::LeaveCS()
{
if (NULL != m_cs)
m_cs->Leave();
m_cs = NULL;
}
void CTemporaryCS::EnterCS(NSCriticalSection::CRITICAL_SECTION* cs)
{
LeaveCS();
cs->Enter();
m_cs = cs;
}
#ifndef _BUILD_TEMPORARY_CS_H_
#define _BUILD_TEMPORARY_CS_H_
namespace NSCriticalSection
{
class CRITICAL_SECTION_NATIVE
{
public:
CRITICAL_SECTION_NATIVE() {};
virtual ~CRITICAL_SECTION_NATIVE() {};
virtual void Enter() = 0;
virtual void Leave() = 0;
};
class CRITICAL_SECTION
{
private:
CRITICAL_SECTION_NATIVE* m_pCS;
public:
CRITICAL_SECTION();
~CRITICAL_SECTION();
void InitializeCriticalSection();
void DeleteCriticalSection();
void Enter();
void Leave();
};
}
class CTemporaryCS
{
public:
CTemporaryCS(NSCriticalSection::CRITICAL_SECTION* cs);
~CTemporaryCS();
void LeaveCS();
void EnterCS(NSCriticalSection::CRITICAL_SECTION* cs);
protected:
NSCriticalSection::CRITICAL_SECTION* m_cs;
};
#endif // _BUILD_TEMPORARY_CS_H_
\ No newline at end of file
#ifndef _BUILD_TIMER_H_
#define _BUILD_TIMER_H_
#include "BaseThread.h"
#include "time.h"
#ifdef _MAC
#include "mach/mach.h"
#include "mach/mach_time.h"
#endif
#if defined(_WIN32) || defined (_WIN64)
//#define _CAN_USE_COM_THREADS
#endif
#if defined(_WIN32) || defined (_WIN64)
typedef DWORD ASC_THREAD_ID;
#else
typedef pthread_t ASC_THREAD_ID;
#endif
namespace NSThreads
{
static ASC_THREAD_ID GetCurrentThreadId()
{
#if defined(_WIN32) || defined (_WIN64)
return ::GetCurrentThreadId();
#else
return pthread_self();
#endif
}
}
namespace NSTimers
{
#ifdef _MAC
static DWORD getUptimeInMilliseconds()
{
const int64_t kOneMillion = 1000 * 1000;
static mach_timebase_info_data_t s_timebase_info;
if (s_timebase_info.denom == 0) {
(void) mach_timebase_info(&s_timebase_info);
}
// mach_absolute_time() returns billionth of seconds,
// so divide by one million to get milliseconds
return (DWORD)((mach_absolute_time() * s_timebase_info.numer) / (kOneMillion * s_timebase_info.denom));
}
#endif
static DWORD GetTickCount()
{
#if defined(_WIN32) || defined(_WIN64) || defined(_WIN32_WCE)
return ::GetTickCount();
#else
#ifdef CLOCK_MONOTONIC
struct timespec ts;
clock_gettime(CLOCK_MONOTONIC, &ts);
return (ts.tv_sec * 1000 + (DWORD)(ts.tv_nsec / 1000000));
#else
//uint64_t nano = mach_absolute_time();
//return nano / 1000000;
return getUptimeInMilliseconds();
#endif
#endif
}
class CTimer : public NSThreads::CBaseThread
{
private:
DWORD m_dwInterval;
INT m_bIsCOMNeed;
public:
CTimer() : NSThreads::CBaseThread()
{
m_dwInterval = 40;
m_bIsCOMNeed = FALSE;
}
virtual ~CTimer()
{
}
inline void SetInterval(const DWORD& dwInterval) { m_dwInterval = dwInterval; }
inline void SetCOMNeed(const INT& bIsCOM) { m_bIsCOMNeed = bIsCOM; }
protected:
virtual DWORD ThreadProc()
{
#ifdef _CAN_USE_COM_THREADS
if (m_bIsCOMNeed)
CoInitialize(NULL);
#endif
DWORD m_startTime, m_curTime;
m_startTime = NSTimers::GetTickCount();
while (m_bRunThread)
{
m_curTime = NSTimers::GetTickCount();
while (m_curTime - m_startTime < m_dwInterval)
{
NSThreads::Sleep(10);
if (!m_bRunThread)
break;
m_curTime = NSTimers::GetTickCount();
}
m_startTime = NSTimers::GetTickCount();
OnTimer();
}
#ifdef _CAN_USE_COM_THREADS
if (m_bIsCOMNeed)
CoUninitialize();
#endif
return 0;
}
virtual void OnTimer() = 0;
};
}
#endif
#ifndef _AGGPLUSTYPES_H
#define _AGGPLUSTYPES_H
#include "../common/Types.h"
namespace Aggplus
{
typedef INT PixelFormat;
typedef struct tagRECT
{
long left;
long top;
long right;
long bottom;
} RECT, *PRECT;
typedef struct tagPOINT
{
long x;
long y;
} POINT, *PPOINT;
#define REAL_MAX FLT_MAX
#define REAL_MIN FLT_MIN
#define REAL_TOLERANCE (FLT_MIN * 100)
#define REAL_EPSILON 1.192092896e-07F /* FLT_EPSILON */
//--------------------------------------------------------------------------
// Status return values from AGG+ methods
//--------------------------------------------------------------------------
enum Status
{
Ok = 0,
GenericError = 1,
InvalidParameter = 2,
OutOfMemory = 3,
ObjectBusy = 4,
InsufficientBuffer = 5,
NotImplemented = 6,
Win32Error = 7,
WrongState = 8,
Aborted = 9,
FileNotFound = 10,
ValueOverflow = 11,
AccessDenied = 12,
UnknownImageFormat = 13,
FontFamilyNotFound = 14,
FontStyleNotFound = 15,
NotTrueTypeFont = 16,
UnsupportedGdiplusVersion = 17,
AggplusNotInitialized = 18,
PropertyNotFound = 19,
PropertyNotSupported = 20
};
enum PenAlignment
{
PenAlignmentCenter = 0,
PenAlignmentInset = 1
};
template <typename T>
class SizeF_T
{
public:
SizeF_T() : Width(0), Height(0) { }
SizeF_T(const SizeF_T& size) : Width(size.Width), Height(size.Height) { }
SizeF_T(T width, T height) : Width(width), Height(height) { }
SizeF_T operator+(const SizeF_T& sz) const { return SizeF_T(Width+sz.Width, Height+sz.Height); }
SizeF_T operator-(const SizeF_T& sz) const { return SizeF_T(Width-sz.Width, Height-sz.Height); }
INT Equals(const SizeF_T& sz) const { return((Width == sz.Width) && (Height == sz.Height)); }
INT Empty() const { return(Width == 0 && Height == 0); }
public:
T Width, Height;
};
typedef SizeF_T<REAL> SizeF;
typedef SizeF_T<int> Size;
template <typename T>
class PointF_T
{
public:
PointF_T() : X(0), Y(0) { }
PointF_T(const PointF_T &point) : X(point.X), Y(point.Y) { }
PointF_T(const SizeF_T<T> &size) : X(size.Width), Y(size.Height) { }
PointF_T(T x, T y) : X(x), Y(y) { }
//~PointF() { }
INT Equals(const PointF_T& point) const { return(X==point.X && Y==point.Y); }
PointF_T operator+(const PointF_T& point) const { return PointF_T(X + point.X, Y + point.Y); }
PointF_T operator-(const PointF_T& point) const { return PointF_T(X - point.X, Y - point.Y); }
public:
T X, Y;
};
typedef PointF_T<REAL> PointF;
typedef PointF_T<int> Point;
typedef PointF_T<double> PointD;
template <typename T>
class RectF_T
{
public:
RectF_T() : X(0), Y(0), Width(0), Height(0) { }
RectF_T(T x, T y, T width, T height) : X(x), Y(y), Width(width), Height(height) { }
RectF_T* Clone() const { return new RectF_T(X, Y, Width, Height); }
void GetLocation(PointF_T<T>* point) const { point->X = X; point->Y = Y; }
void GetSize(SizeF_T<T>* size) const { size->Width = Width; size->Height = Height; }
void GetBounds(RectF_T* rect) const { rect->X = X; rect->Y = Y; rect->Width = Width; rect->Height = Height; }
inline T GetLeft() const { return X; }
inline T GetTop() const { return Y; }
inline T GetRight() const { return X+Width; }
inline T GetBottom() const { return Y+Height; }
INT IsEmptyArea() const { return (Width <= (T)REAL_EPSILON) || (Height <= (T)REAL_EPSILON); }
INT Equals(const RectF_T & rect) const
{
return X == rect.X && Y == rect.Y &&
Width == rect.Width && Height == rect.Height;
}
INT Contains(T x, T y) const
{
return x >= X && x < X+Width &&
y >= Y && y < Y+Height;
}
INT Contains(const PointF_T<T>& pt) const { return Contains(pt.X, pt.Y); }
INT Contains(const RectF_T& rect) const
{
return (X <= rect.X) && (rect.GetRight() <= GetRight()) &&
(Y <= rect.Y) && (rect.GetBottom() <= GetBottom());
}
void Inflate(T dx, T dy) { X -= dx; Y -= dy; Width += 2*dx; Height += 2*dy; }
void Inflate(const PointF_T<T>& point) { Inflate(point.X, point.Y); }
INT Intersect(const RectF_T& rect) { return Intersect(*this, *this, rect); }
static INT Intersect(RectF_T& c, const RectF_T& a, const RectF_T& b)
{
T right = min(a.GetRight(), b.GetRight());
T bottom = min(a.GetBottom(), b.GetBottom());
T left = max(a.GetLeft(), b.GetLeft());
T top = max(a.GetTop(), b.GetTop());
c.X = left;
c.Y = top;
c.Width = right - left;
c.Height = bottom - top;
return !c.IsEmptyArea();
}
INT IntersectsWith(const RectF_T& rect) const
{
return (GetLeft() < rect.GetRight() &&
GetTop() < rect.GetBottom() &&
GetRight() > rect.GetLeft() &&
GetBottom() > rect.GetTop());
}
static INT Union(RectF_T& c, const RectF_T& a, const RectF_T& b)
{
T right = max(a.GetRight(), b.GetRight());
T bottom = max(a.GetBottom(), b.GetBottom());
T left = min(a.GetLeft(), b.GetLeft());
T top = min(a.GetTop(), b.GetTop());
c.X = left;
c.Y = top;
c.Width = right - left;
c.Height = bottom - top;
return !c.IsEmptyArea();
}
void Offset(const PointF_T<T>& point) { Offset(point.X, point.Y); }
void Offset(T dx, T dy) { X += dx; Y += dy; }
public:
T X, Y, Width, Height;
};
typedef RectF_T<REAL> RectF;
typedef RectF_T<int> Rect;
class CDoublePoint
{
public:
double x;
double y;
public:
CDoublePoint()
{
x = 0;
y = 0;
}
CDoublePoint(double dx, double dy)
{
x = dx;
y = dy;
}
CDoublePoint& operator=(const CDoublePoint& oSrc)
{
x = oSrc.x;
y = oSrc.y;
return *this;
}
CDoublePoint(const CDoublePoint& oSrc)
{
*this = oSrc;
}
};
class CDoubleRect
{
public:
double left;
double top;
double right;
double bottom;
public:
CDoubleRect()
{
left = 0;
top = 0;
right = 0;
bottom = 0;
}
CDoubleRect& operator=(const CDoubleRect& oSrc)
{
left = oSrc.left;
top = oSrc.top;
right = oSrc.right;
bottom = oSrc.bottom;
return *this;
}
CDoubleRect(const CDoubleRect& oSrc)
{
*this = oSrc;
}
inline double GetWidth() const
{
return right - left;
}
inline double GetHeight() const
{
return bottom - top;
}
inline void Offset(double dX, double dY)
{
left += dX;
top += dY;
right += dX;
bottom += dY;
}
inline double GetCentreX() const
{
return (left + right) / 2.0;
}
inline double GetCentreY() const
{
return (top + bottom) / 2.0;
}
inline INT IsPointInside(const CDoublePoint& oPoint)
{
return IsPointInside(oPoint.x, oPoint.y);
}
INT IsPointInside(const double& pointX, const double& pointY)
{
return ((left <= pointX) && (right >= pointX) &&
(top <= pointY) && (bottom >= pointY));
}
};
} //namespace Aggplus
#endif // _AGGPLUSTYPES_H

Microsoft Visual Studio Solution File, Format Version 10.00
# Visual Studio 2008
Project("{8BC9CEB8-8B4A-11D0-8D11-00A0C91BC942}") = "graphics", "graphics.vcproj", "{37CA072A-5BDE-498B-B3A7-5E404F5F9BF2}"
EndProject
Global
GlobalSection(SolutionConfigurationPlatforms) = preSolution
Debug|Win32 = Debug|Win32
Release|Win32 = Release|Win32
EndGlobalSection
GlobalSection(ProjectConfigurationPlatforms) = postSolution
{37CA072A-5BDE-498B-B3A7-5E404F5F9BF2}.Debug|Win32.ActiveCfg = Debug|Win32
{37CA072A-5BDE-498B-B3A7-5E404F5F9BF2}.Debug|Win32.Build.0 = Debug|Win32
{37CA072A-5BDE-498B-B3A7-5E404F5F9BF2}.Release|Win32.ActiveCfg = Release|Win32
{37CA072A-5BDE-498B-B3A7-5E404F5F9BF2}.Release|Win32.Build.0 = Release|Win32
EndGlobalSection
GlobalSection(SolutionProperties) = preSolution
HideSolutionNode = FALSE
EndGlobalSection
EndGlobal
<?xml version="1.0" encoding="windows-1251"?>
<VisualStudioProject
ProjectType="Visual C++"
Version="9,00"
Name="graphics"
ProjectGUID="{37CA072A-5BDE-498B-B3A7-5E404F5F9BF2}"
RootNamespace="graphics"
TargetFrameworkVersion="131072"
>
<Platforms>
<Platform
Name="Win32"
/>
</Platforms>
<ToolFiles>
</ToolFiles>
<Configurations>
<Configuration
Name="Release|Win32"
OutputDirectory="./Release"
IntermediateDirectory="./Release"
ConfigurationType="4"
InheritedPropertySheets="$(VCInstallDir)VCProjectDefaults\UpgradeFromVC71.vsprops"
UseOfMFC="2"
ATLMinimizesCRunTimeLibraryUsage="false"
CharacterSet="2"
DeleteExtensionsOnClean="*.obj;*.ilk;*.tlb;*.tli;*.tlh;*.tmp;*.rsp;*.pgc;*.pgd;*.meta;$(TargetPath)"
>
<Tool
Name="VCPreBuildEventTool"
/>
<Tool
Name="VCCustomBuildTool"
/>
<Tool
Name="VCXMLDataGeneratorTool"
/>
<Tool
Name="VCWebServiceProxyGeneratorTool"
/>
<Tool
Name="VCMIDLTool"
/>
<Tool
Name="VCCLCompilerTool"
Optimization="2"
InlineFunctionExpansion="1"
EnableIntrinsicFunctions="false"
FavorSizeOrSpeed="0"
AdditionalIncludeDirectories="&quot;../agg-2.4/include&quot;;&quot;../freetype-2.5.2/include&quot;"
PreprocessorDefinitions="WIN32;NDEBUG;_LIB;_CRT_SECURE_NO_DEPRECATE;$(NOINHERIT)"
StringPooling="true"
RuntimeLibrary="2"
BufferSecurityCheck="true"
EnableFunctionLevelLinking="true"
DisableLanguageExtensions="false"
PrecompiledHeaderFile=".\Release\graphics.pch"
AssemblerListingLocation=".\Release\"
ObjectFile=".\Release\"
ProgramDataBaseFileName=".\Release\graphics.pdb"
WarningLevel="3"
SuppressStartupBanner="true"
DebugInformationFormat="0"
/>
<Tool
Name="VCManagedResourceCompilerTool"
/>
<Tool
Name="VCResourceCompilerTool"
PreprocessorDefinitions="NDEBUG"
Culture="1033"
/>
<Tool
Name="VCPreLinkEventTool"
/>
<Tool
Name="VCLibrarianTool"
AdditionalDependencies=""
OutputFile="./Release/graphics.lib"
AdditionalLibraryDirectories=""
SuppressStartupBanner="true"
/>
<Tool
Name="VCALinkTool"
/>
<Tool
Name="VCXDCMakeTool"
/>
<Tool
Name="VCBscMakeTool"
/>
<Tool
Name="VCFxCopTool"
/>
<Tool
Name="VCPostBuildEventTool"
/>
</Configuration>
<Configuration
Name="Debug|Win32"
OutputDirectory="./Debug"
IntermediateDirectory="./Debug"
ConfigurationType="4"
InheritedPropertySheets="$(VCInstallDir)VCProjectDefaults\UpgradeFromVC71.vsprops"
UseOfMFC="2"
ATLMinimizesCRunTimeLibraryUsage="false"
CharacterSet="2"
DeleteExtensionsOnClean=""
>
<Tool
Name="VCPreBuildEventTool"
/>
<Tool
Name="VCCustomBuildTool"
/>
<Tool
Name="VCXMLDataGeneratorTool"
/>
<Tool
Name="VCWebServiceProxyGeneratorTool"
/>
<Tool
Name="VCMIDLTool"
/>
<Tool
Name="VCCLCompilerTool"
Optimization="0"
AdditionalIncludeDirectories="&quot;../agg-2.4/include&quot;;&quot;../freetype-2.5.2/include&quot;"
PreprocessorDefinitions="WIN32;_DEBUG;_LIB;_CRT_SECURE_NO_DEPRECATE;$(NOINHERIT)"
MinimalRebuild="false"
BasicRuntimeChecks="3"
RuntimeLibrary="3"
StructMemberAlignment="0"
DisableLanguageExtensions="false"
PrecompiledHeaderFile="..\Debug\graphics.pch"
AssemblerListingLocation=".\Debug\"
ObjectFile=".\Debug\"
ProgramDataBaseFileName=".\Debug\graphics.pdb"
BrowseInformation="0"
WarningLevel="3"
SuppressStartupBanner="true"
DebugInformationFormat="3"
/>
<Tool
Name="VCManagedResourceCompilerTool"
/>
<Tool
Name="VCResourceCompilerTool"
PreprocessorDefinitions="_DEBUG"
Culture="1033"
/>
<Tool
Name="VCPreLinkEventTool"
/>
<Tool
Name="VCLibrarianTool"
OutputFile="./Debug/graphics.lib"
AdditionalLibraryDirectories=""
SuppressStartupBanner="true"
/>
<Tool
Name="VCALinkTool"
/>
<Tool
Name="VCXDCMakeTool"
/>
<Tool
Name="VCBscMakeTool"
/>
<Tool
Name="VCFxCopTool"
/>
<Tool
Name="VCPostBuildEventTool"
/>
</Configuration>
</Configurations>
<References>
</References>
<Files>
<Filter
Name="Source Files"
Filter="cpp;c;cxx;rc;def;r;odl;idl;hpj;bat"
>
<File
RelativePath=".\ArrowHead.cpp"
>
</File>
<File
RelativePath=".\Brush.cpp"
>
</File>
<File
RelativePath=".\Clip.cpp"
>
</File>
<File
RelativePath=".\Graphics.cpp"
>
</File>
<File
RelativePath=".\GraphicsPath.cpp"
>
</File>
<File
RelativePath=".\GraphicsRenderer.cpp"
>
</File>
<File
RelativePath=".\Image.cpp"
>
</File>
<File
RelativePath=".\Matrix.cpp"
>
</File>
<File
RelativePath=".\TemporaryCS.cpp"
>
</File>
</Filter>
<Filter
Name="Header Files"
Filter="h;hpp;hxx;hm;inl"
>
<File
RelativePath=".\ArrowHead.h"
>
</File>
<File
RelativePath=".\BaseThread.h"
>
</File>
<File
RelativePath=".\Brush.h"
>
</File>
<File
RelativePath=".\Clip.h"
>
</File>
<File
RelativePath=".\Color.h"
>
</File>
<File
RelativePath=".\Graphics.h"
>
</File>
<File
RelativePath=".\GraphicsPath.h"
>
</File>
<File
RelativePath=".\GraphicsRenderer.h"
>
</File>
<File
RelativePath=".\Image.h"
>
</File>
<File
RelativePath=".\ImageFilesCache.h"
>
</File>
<File
RelativePath=".\Matrix.h"
>
</File>
<File
RelativePath=".\TemporaryCS.h"
>
</File>
<File
RelativePath=".\Timer.h"
>
</File>
</Filter>
</Files>
<Globals>
</Globals>
</VisualStudioProject>
<?xml version="1.0" encoding="windows-1251"?>
<VisualStudioProject
ProjectType="Visual C++"
Version="8,00"
Name="graphics"
ProjectGUID="{37CA072A-5BDE-498B-B3A7-5E404F5F9BF2}"
RootNamespace="graphics"
>
<Platforms>
<Platform
Name="Win32"
/>
<Platform
Name="x64"
/>
</Platforms>
<ToolFiles>
</ToolFiles>
<Configurations>
<Configuration
Name="Release|Win32"
OutputDirectory="$(ConfigurationName)"
IntermediateDirectory="$(ConfigurationName)"
ConfigurationType="4"
InheritedPropertySheets="$(VCInstallDir)VCProjectDefaults\UpgradeFromVC71.vsprops"
UseOfMFC="0"
ATLMinimizesCRunTimeLibraryUsage="false"
CharacterSet="2"
DeleteExtensionsOnClean="*.obj;*.ilk;*.tlb;*.tli;*.tlh;*.tmp;*.rsp;*.pgc;*.pgd;*.meta;$(TargetPath)"
>
<Tool
Name="VCPreBuildEventTool"
/>
<Tool
Name="VCCustomBuildTool"
/>
<Tool
Name="VCXMLDataGeneratorTool"
/>
<Tool
Name="VCWebServiceProxyGeneratorTool"
/>
<Tool
Name="VCMIDLTool"
/>
<Tool
Name="VCCLCompilerTool"
Optimization="2"
InlineFunctionExpansion="1"
EnableIntrinsicFunctions="false"
FavorSizeOrSpeed="0"
AdditionalIncludeDirectories="&quot;../agg-2.4/include&quot;;&quot;../freetype-2.5.2/include&quot;"
PreprocessorDefinitions="WIN32;NDEBUG;_LIB;_CRT_SECURE_NO_DEPRECATE;$(NOINHERIT)"
StringPooling="true"
RuntimeLibrary="2"
BufferSecurityCheck="true"
EnableFunctionLevelLinking="true"
DisableLanguageExtensions="false"
PrecompiledHeaderFile=""
AssemblerListingLocation="$(ConfigurationName)\"
ObjectFile="$(ConfigurationName)\"
ProgramDataBaseFileName="$(ConfigurationName)\"
WarningLevel="3"
SuppressStartupBanner="true"
DebugInformationFormat="0"
/>
<Tool
Name="VCManagedResourceCompilerTool"
/>
<Tool
Name="VCResourceCompilerTool"
PreprocessorDefinitions="NDEBUG"
Culture="1033"
/>
<Tool
Name="VCPreLinkEventTool"
/>
<Tool
Name="VCLibrarianTool"
AdditionalDependencies=""
OutputFile="$(OutDir)\$(ProjectName).lib"
AdditionalLibraryDirectories=""
SuppressStartupBanner="true"
/>
<Tool
Name="VCALinkTool"
/>
<Tool
Name="VCXDCMakeTool"
/>
<Tool
Name="VCBscMakeTool"
/>
<Tool
Name="VCFxCopTool"
/>
<Tool
Name="VCPostBuildEventTool"
/>
</Configuration>
<Configuration
Name="Release|x64"
OutputDirectory="$(PlatformName)\$(ConfigurationName)"
IntermediateDirectory="$(PlatformName)\$(ConfigurationName)"
ConfigurationType="4"
InheritedPropertySheets="$(VCInstallDir)VCProjectDefaults\UpgradeFromVC71.vsprops"
UseOfMFC="0"
ATLMinimizesCRunTimeLibraryUsage="false"
CharacterSet="2"
DeleteExtensionsOnClean="*.obj;*.ilk;*.tlb;*.tli;*.tlh;*.tmp;*.rsp;*.pgc;*.pgd;*.meta;$(TargetPath)"
>
<Tool
Name="VCPreBuildEventTool"
/>
<Tool
Name="VCCustomBuildTool"
/>
<Tool
Name="VCXMLDataGeneratorTool"
/>
<Tool
Name="VCWebServiceProxyGeneratorTool"
/>
<Tool
Name="VCMIDLTool"
TargetEnvironment="3"
/>
<Tool
Name="VCCLCompilerTool"
Optimization="2"
InlineFunctionExpansion="1"
EnableIntrinsicFunctions="false"
FavorSizeOrSpeed="0"
AdditionalIncludeDirectories="&quot;../agg-2.4/include&quot;;&quot;../freetype-2.5.2/include&quot;"
PreprocessorDefinitions="WIN32;NDEBUG;_LIB;_CRT_SECURE_NO_DEPRECATE;$(NOINHERIT)"
StringPooling="true"
RuntimeLibrary="2"
BufferSecurityCheck="true"
EnableFunctionLevelLinking="true"
DisableLanguageExtensions="false"
PrecompiledHeaderFile=""
AssemblerListingLocation="$(PlatformName)\$(ConfigurationName)\"
ObjectFile="$(PlatformName)\$(ConfigurationName)\"
ProgramDataBaseFileName="$(PlatformName)\$(ConfigurationName)\"
WarningLevel="3"
SuppressStartupBanner="true"
DebugInformationFormat="0"
/>
<Tool
Name="VCManagedResourceCompilerTool"
/>
<Tool
Name="VCResourceCompilerTool"
PreprocessorDefinitions="NDEBUG"
Culture="1033"
/>
<Tool
Name="VCPreLinkEventTool"
/>
<Tool
Name="VCLibrarianTool"
AdditionalDependencies=""
OutputFile="$(OutDir)\$(ProjectName).lib"
AdditionalLibraryDirectories=""
SuppressStartupBanner="true"
/>
<Tool
Name="VCALinkTool"
/>
<Tool
Name="VCXDCMakeTool"
/>
<Tool
Name="VCBscMakeTool"
/>
<Tool
Name="VCFxCopTool"
/>
<Tool
Name="VCPostBuildEventTool"
/>
</Configuration>
<Configuration
Name="Debug|Win32"
OutputDirectory="$(ConfigurationName)"
IntermediateDirectory="$(ConfigurationName)"
ConfigurationType="4"
InheritedPropertySheets="$(VCInstallDir)VCProjectDefaults\UpgradeFromVC71.vsprops"
UseOfMFC="0"
UseOfATL="0"
ATLMinimizesCRunTimeLibraryUsage="false"
CharacterSet="2"
DeleteExtensionsOnClean=""
>
<Tool
Name="VCPreBuildEventTool"
/>
<Tool
Name="VCCustomBuildTool"
/>
<Tool
Name="VCXMLDataGeneratorTool"
/>
<Tool
Name="VCWebServiceProxyGeneratorTool"
/>
<Tool
Name="VCMIDLTool"
/>
<Tool
Name="VCCLCompilerTool"
Optimization="0"
AdditionalIncludeDirectories="&quot;../agg-2.4/include&quot;;&quot;../freetype-2.5.2/include&quot;"
PreprocessorDefinitions="WIN32;_DEBUG;_LIB;_CRT_SECURE_NO_DEPRECATE;$(NOINHERIT)"
MinimalRebuild="false"
BasicRuntimeChecks="3"
RuntimeLibrary="3"
StructMemberAlignment="0"
DisableLanguageExtensions="false"
PrecompiledHeaderFile=""
AssemblerListingLocation="$(ConfigurationName)\"
ObjectFile="$(ConfigurationName)\"
ProgramDataBaseFileName="$(ConfigurationName)\"
BrowseInformation="0"
WarningLevel="3"
SuppressStartupBanner="true"
DebugInformationFormat="3"
/>
<Tool
Name="VCManagedResourceCompilerTool"
/>
<Tool
Name="VCResourceCompilerTool"
PreprocessorDefinitions="_DEBUG"
Culture="1033"
/>
<Tool
Name="VCPreLinkEventTool"
/>
<Tool
Name="VCLibrarianTool"
OutputFile="$(OutDir)\$(ProjectName).lib"
AdditionalLibraryDirectories=""
SuppressStartupBanner="true"
IgnoreAllDefaultLibraries="true"
/>
<Tool
Name="VCALinkTool"
/>
<Tool
Name="VCXDCMakeTool"
/>
<Tool
Name="VCBscMakeTool"
/>
<Tool
Name="VCFxCopTool"
/>
<Tool
Name="VCPostBuildEventTool"
/>
</Configuration>
<Configuration
Name="Debug|x64"
OutputDirectory="$(PlatformName)\$(ConfigurationName)"
IntermediateDirectory="$(PlatformName)\$(ConfigurationName)"
ConfigurationType="4"
InheritedPropertySheets="$(VCInstallDir)VCProjectDefaults\UpgradeFromVC71.vsprops"
UseOfMFC="0"
UseOfATL="0"
ATLMinimizesCRunTimeLibraryUsage="false"
CharacterSet="1"
DeleteExtensionsOnClean=""
>
<Tool
Name="VCPreBuildEventTool"
/>
<Tool
Name="VCCustomBuildTool"
/>
<Tool
Name="VCXMLDataGeneratorTool"
/>
<Tool
Name="VCWebServiceProxyGeneratorTool"
/>
<Tool
Name="VCMIDLTool"
TargetEnvironment="3"
/>
<Tool
Name="VCCLCompilerTool"
Optimization="0"
AdditionalIncludeDirectories="&quot;../agg-2.4/include&quot;;&quot;../freetype-2.5.2/include&quot;"
PreprocessorDefinitions="WIN32;_DEBUG;_LIB;_CRT_SECURE_NO_DEPRECATE;$(NOINHERIT)"
MinimalRebuild="false"
BasicRuntimeChecks="3"
RuntimeLibrary="3"
StructMemberAlignment="0"
DisableLanguageExtensions="false"
PrecompiledHeaderFile=""
AssemblerListingLocation="$(PlatformName)\$(ConfigurationName)\"
ObjectFile="$(PlatformName)\$(ConfigurationName)\"
ProgramDataBaseFileName="$(PlatformName)\$(ConfigurationName)\"
BrowseInformation="0"
WarningLevel="3"
SuppressStartupBanner="true"
DebugInformationFormat="3"
/>
<Tool
Name="VCManagedResourceCompilerTool"
/>
<Tool
Name="VCResourceCompilerTool"
PreprocessorDefinitions="_DEBUG"
Culture="1033"
/>
<Tool
Name="VCPreLinkEventTool"
/>
<Tool
Name="VCLibrarianTool"
OutputFile="$(OutDir)\$(ProjectName).lib"
AdditionalLibraryDirectories=""
SuppressStartupBanner="true"
IgnoreAllDefaultLibraries="true"
/>
<Tool
Name="VCALinkTool"
/>
<Tool
Name="VCXDCMakeTool"
/>
<Tool
Name="VCBscMakeTool"
/>
<Tool
Name="VCFxCopTool"
/>
<Tool
Name="VCPostBuildEventTool"
/>
</Configuration>
</Configurations>
<References>
</References>
<Files>
<Filter
Name="Source Files"
Filter="cpp;c;cxx;rc;def;r;odl;idl;hpj;bat"
>
<File
RelativePath=".\ArrowHead.cpp"
>
</File>
<File
RelativePath=".\Brush.cpp"
>
</File>
<File
RelativePath=".\Clip.cpp"
>
</File>
<File
RelativePath=".\Graphics.cpp"
>
</File>
<File
RelativePath=".\GraphicsPath.cpp"
>
</File>
<File
RelativePath=".\GraphicsRenderer.cpp"
>
</File>
<File
RelativePath=".\Image.cpp"
>
</File>
<File
RelativePath=".\Matrix.cpp"
>
</File>
<File
RelativePath=".\TemporaryCS.cpp"
>
</File>
</Filter>
<Filter
Name="Header Files"
Filter="h;hpp;hxx;hm;inl"
>
<File
RelativePath=".\ArrowHead.h"
>
</File>
<File
RelativePath=".\BaseThread.h"
>
</File>
<File
RelativePath=".\Brush.h"
>
</File>
<File
RelativePath=".\Clip.h"
>
</File>
<File
RelativePath=".\Color.h"
>
</File>
<File
RelativePath=".\Graphics.h"
>
</File>
<File
RelativePath=".\GraphicsPath.h"
>
</File>
<File
RelativePath=".\GraphicsRenderer.h"
>
</File>
<File
RelativePath=".\Image.h"
>
</File>
<File
RelativePath=".\ImageFilesCache.h"
>
</File>
<File
RelativePath=".\Matrix.h"
>
</File>
<File
RelativePath=".\TemporaryCS.h"
>
</File>
<File
RelativePath=".\Timer.h"
>
</File>
</Filter>
</Files>
<Globals>
</Globals>
</VisualStudioProject>
#ifndef _BUILD_GRAPHICS_STRUCTURES_H_
#define _BUILD_GRAPHICS_STRUCTURES_H_
#include "../common/Array.h"
#include "../graphics/aggplustypes.h"
#include <string>
#include <string.h>
#include <stdlib.h>
// pen -----------------------------------------------------------
const long c_ag_LineCapFlat = 0;
const long c_ag_LineCapSquare = 1;
const long c_ag_LineCapTriangle = 3;
const long c_ag_LineCapNoAnchor = 16;
const long c_ag_LineCapSquareAnchor = 17;
const long c_ag_LineCapRoundAnchor = 18;
const long c_ag_LineCapDiamondAnchor = 19;
const long c_ag_LineCapArrowAnchor = 20;
const long c_ag_LineCapAnchorMask = 240;
const long c_ag_LineCapCustom = 255;
const long c_ag_DashCapFlat = 0;
const long c_ag_DashCapRound = 2;
const long c_ag_DashCapTriangle = 3;
const long c_ag_LineJoinMiter = 0;
const long c_ag_LineJoinBevel = 1;
const long c_ag_LineJoinRound = 2;
const long c_ag_LineJoinMiterClipped = 3;
const long c_ag_PenAlignmentCenter = 0;
const long c_ag_PenAlignmentInset = 1;
const long c_ag_PenAlignmentOutset = 2;
const long c_ag_PenAlignmentLeft = 3;
const long c_ag_PenAlignmentRight = 4;
// --------------------------------------------------------------
// brush --------------------------------------------------------
// old constants for brush type
const long c_BrushTypeSolid_ = 0;
const long c_BrushTypeHorizontal_ = 1;
const long c_BrushTypeVertical_ = 2;
const long c_BrushTypeDiagonal1_ = 3;
const long c_BrushTypeDiagonal2_ = 4;
const long c_BrushTypeCenter_ = 5;
const long c_BrushTypePathGradient1_ = 6;
const long c_BrushTypePathGradient2_ = 7;
const long c_BrushTypeTexture_ = 8;
const long c_BrushTypeHatch1_ = 9;
const long c_BrushTypeHatch53_ = 61;
const long c_BrushTypeGradient1_ = 62;
const long c_BrushTypeGradient6_ = 70;
const long c_BrushTypeSolid = 1000;
const long c_BrushTypeHorizontal = 2001;
const long c_BrushTypeVertical = 2002;
const long c_BrushTypeDiagonal1 = 2003;
const long c_BrushTypeDiagonal2 = 2004;
const long c_BrushTypeCenter = 2005;
const long c_BrushTypePathGradient1 = 2006;
const long c_BrushTypePathGradient2 = 2007;
const long c_BrushTypeCylinderHor = 2008;
const long c_BrushTypeCylinderVer = 2009;
const long c_BrushTypeTexture = 3008;
const long c_BrushTypePattern = 3009;
const long c_BrushTypeHatch1 = 4009;
const long c_BrushTypeHatch53 = 4061;
const long c_BrushTextureModeStretch = 0;
const long c_BrushTextureModeTile = 1;
const long c_BrushTextureModeTileCenter = 2;
// --------------------------------------------------------------
namespace NSStructures
{
class CPen
{
public:
long Color;
long Alpha;
double Size;
unsigned char DashStyle;
unsigned char LineStartCap;
unsigned char LineEndCap;
unsigned char LineJoin;
double* DashPattern;
long Count;
double DashOffset;
long Align;
double MiterLimit;
public:
void GetDashPattern(double* arrDashPattern, long& nCount) const
{
if (nCount == Count)
{
for (int i = 0; i < Count; ++i)
{
arrDashPattern[i] = DashPattern[i];
}
}
}
void SetDashPattern(double* arrDashPattern, long nCount)
{
if ((arrDashPattern == NULL) || (nCount == 0))
{
Count = 0;
RELEASEARRAYOBJECTS(DashPattern);
}
else
{
if (Count != nCount)
{
Count = nCount;
RELEASEARRAYOBJECTS(DashPattern);
DashPattern = new double[Count];
}
for (int i = 0; i < Count; ++i)
{
DashPattern[i] = arrDashPattern[i];
}
}
}
void ScaleAlpha( double dScale )
{
long dNewAlpha = long(Alpha * dScale + 0.5);
if( dNewAlpha > 255 ) dNewAlpha = 255;
else if( dNewAlpha < 0 ) dNewAlpha = 0;
Alpha = dNewAlpha;
}
INT IsEqual(CPen* pPen)
{
if (NULL == pPen)
return FALSE;
return ((Color == pPen->Color) && (Alpha == pPen->Alpha) && (Size == pPen->Size) &&
(DashStyle == pPen->DashStyle) && (LineStartCap == pPen->LineStartCap) &&
(LineEndCap == pPen->LineEndCap) && (LineJoin == pPen->LineJoin));
}
void SetDefaultParams()
{
Color = 0;
Alpha = 255;
Size = 1;
DashStyle = 0;
LineStartCap = 0;
LineEndCap = 0;
LineJoin = 0;
DashPattern = NULL;
Count = 0;
DashOffset = 0;
Align = Aggplus::PenAlignmentCenter;
MiterLimit = 0.5;
}
public:
CPen()
{
SetDefaultParams();
}
CPen( const CPen& other )
{
SetDefaultParams();
*this = other;
}
CPen& operator=(const CPen& other)
{
Color = other.Color;
Alpha = other.Alpha;
Size = other.Size;
DashStyle = other.DashStyle;
LineStartCap = other.LineStartCap;
LineEndCap = other.LineEndCap;
LineJoin = other.LineJoin;
RELEASEARRAYOBJECTS(DashPattern);
Count = other.Count;
if (Count != 0)
{
DashPattern = new double[Count];
memcpy(DashPattern, other.DashPattern, Count * sizeof(double));
}
DashOffset = other.DashOffset;
Align = other.Align;
MiterLimit = other.MiterLimit;
return *this;
}
virtual ~CPen()
{
RELEASEARRAYOBJECTS(DashPattern);
}
};
class CBrush
{
public:
struct TSubColor
{
long color;
long position; // [0..65536]
};
public:
long Type;
long Color1;
long Color2;
long Alpha1;
long Alpha2;
std::wstring TexturePath;
long TextureAlpha;
long TextureMode;
int Rectable;
Aggplus::RectF Rect;
Aggplus::CDoubleRect Bounds;
double LinearAngle;
CArray<TSubColor> m_arrSubColors;
public:
void LoadSubColors( const std::string& str )
{
m_arrSubColors.RemoveAll();
if( str.empty() )
return;
TSubColor subcolor;
int start = 0;
for(;;)
{
int pos = (int)str.find( (wchar_t)',', start );
if( pos < 0 )
break;
subcolor.color = ::atoi( str.substr( start, pos - start ).c_str() );
start = pos + 1;
pos = (int)str.find( (wchar_t)';', start );
if( pos < 0 )
break;
subcolor.position = ::atoi( str.substr( start, pos - start ).c_str() );
start = pos + 1;
m_arrSubColors.Add( subcolor );
}
}
inline long ConstantCompatible(long nConstant)
{
if( c_BrushTypeDiagonal1_ == nConstant )
nConstant = c_BrushTypeDiagonal2_;
else if( c_BrushTypeDiagonal2_ == nConstant )
nConstant = c_BrushTypeDiagonal1_;
if (1000 <= nConstant)
return nConstant;
if (c_BrushTypeSolid_ == nConstant)
return nConstant + 1000;
if (c_BrushTypeHorizontal_ <= nConstant && c_BrushTypePathGradient2_ >= nConstant)
return nConstant + 2000;
if (c_BrushTypeTexture_ == nConstant)
return nConstant + 3000;
if (c_BrushTypeHatch1_ <= nConstant && c_BrushTypeHatch53_ >= nConstant)
return nConstant + 4000;
if (c_BrushTypeGradient1_ <= nConstant && c_BrushTypeGradient6_ >= nConstant)
return nConstant + 2000 - 61;
return 1000;
}
void ScaleAlpha1( double dScale )
{
long dNewAlpha = long(Alpha1 * dScale + 0.5);
if( dNewAlpha > 255 ) dNewAlpha = 255;
else if( dNewAlpha < 0 ) dNewAlpha = 0;
Alpha1 = dNewAlpha;
}
void ScaleAlpha2( double dScale )
{
long dNewAlpha = long(Alpha2 * dScale + 0.5);
if( dNewAlpha > 255 ) dNewAlpha = 255;
else if( dNewAlpha < 0 ) dNewAlpha = 0;
Alpha2 = dNewAlpha;
}
void ScaleTextureAlpha( double dScale )
{
long dNewAlpha = long(TextureAlpha * dScale + 0.5);
if( dNewAlpha > 255 ) dNewAlpha = 255;
else if( dNewAlpha < 0 ) dNewAlpha = 0;
TextureAlpha = dNewAlpha;
}
INT IsEqual(CBrush* pBrush)
{
if (NULL == pBrush)
return FALSE;
return ((Type == pBrush->Type) &&
(Color1 == pBrush->Color1) && (Color2 == pBrush->Color2) &&
(Alpha1 == pBrush->Alpha1) && (Alpha2 == pBrush->Alpha2) && (LinearAngle == pBrush->LinearAngle) &&
(TexturePath == pBrush->TexturePath) && (TextureAlpha == pBrush->TextureAlpha) && (TextureMode == pBrush->TextureMode) &&
(Rectable == pBrush->Rectable) && (Rect.Equals(pBrush->Rect)));
}
void SetDefaultParams()
{
Type = c_BrushTypeSolid;
Color1 = 0;
Alpha1 = 255;
Color2 = 0;
Alpha2 = 255;
TextureAlpha = 255;
TextureMode = c_BrushTextureModeStretch;
LinearAngle = 0;
TexturePath = L"";
Rectable = FALSE;
Rect.X = 0.0F;
Rect.Y = 0.0F;
Rect.Width = 0.0F;
Rect.Height = 0.0F;
Bounds.left = 0;
Bounds.top = 0;
Bounds.right = 0;
Bounds.bottom = 0;
m_arrSubColors.RemoveAll();
}
public:
CBrush()
{
SetDefaultParams();
}
CBrush( const CBrush& other )
{
Type = other.Type;
Color1 = other.Color1;
Alpha1 = other.Alpha1;
Color2 = other.Color2;
Alpha2 = other.Alpha2;
TexturePath = other.TexturePath;
TextureAlpha = other.TextureAlpha;
TextureMode = other.TextureMode;
Rectable = other.Rectable;
Rect = other.Rect;
Bounds = other.Bounds;
LinearAngle = other.LinearAngle;
m_arrSubColors = other.m_arrSubColors;
}
CBrush& operator=(const CBrush& other)
{
Type = other.Type;
Color1 = other.Color1;
Alpha1 = other.Alpha1;
Color2 = other.Color2;
Alpha2 = other.Alpha2;
TexturePath = other.TexturePath;
TextureAlpha = other.TextureAlpha;
TextureMode = other.TextureMode;
Rectable = other.Rectable;
Rect = other.Rect;
Bounds = other.Bounds;
LinearAngle = other.LinearAngle;
m_arrSubColors = other.m_arrSubColors;
return *this;
}
virtual ~CBrush()
{
}
int IsTexture()
{
return (c_BrushTypeTexture == Type || c_BrushTypePattern == Type);
}
int IsOneColor()
{
return (c_BrushTypeSolid == Type);
}
int IsTwoColor()
{
return ((c_BrushTypeHorizontal <= Type && c_BrushTypeCylinderVer >= Type) ||
(c_BrushTypeHatch1 <= Type && c_BrushTypeHatch53 >= Type));
}
};
class CFont
{
public:
std::wstring Path;
std::wstring Name;
double Size;
int Bold;
int Italic;
unsigned char Underline;
unsigned char Strikeout;
int StringGID;
double CharSpace;
int FaceIndex;
public:
int IsEqual(CFont* pFont)
{
if (NULL == pFont)
return FALSE;
return ((Name == pFont->Name) && (Path == pFont->Path) && (FaceIndex == pFont->FaceIndex) && (StringGID == pFont->StringGID) && (Size == pFont->Size) &&
(Bold == pFont->Bold) && (Italic == pFont->Italic) &&
(Underline == pFont->Underline) && (Strikeout == pFont->Strikeout));
}
long GetStyle() const
{
long lStyle = 0;
if (Bold)
lStyle |= 0x01;
if (Italic)
lStyle |= 0x02;
lStyle |= Underline << 2;
lStyle |= Strikeout << 7;
return lStyle;
}
void SetStyle(long const& lStyle)
{
Bold = (0x01 == (0x01 & lStyle));
Italic = (0x02 == (0x02 & lStyle));
Underline = (unsigned char)(0x7C & lStyle) >> 2;
Strikeout = (unsigned char)(0x0180 & lStyle) >> 7;
}
void SetDefaultParams()
{
Name = L"Arial";
Path = L"";
Size = 0;
Bold = FALSE;
Italic = FALSE;
Underline = 0;
Strikeout = 0;
StringGID = FALSE;
CharSpace = 0.0;
FaceIndex = 0;
}
public:
CFont()
{
SetDefaultParams();
}
CFont( const CFont& other )
{
*this = other;
}
CFont& operator=(const CFont& other)
{
Name = other.Name;
Path = other.Path;
Size = other.Size;
Bold = other.Bold;
Italic = other.Italic;
Underline = other.Underline;
Strikeout = other.Strikeout;
StringGID = other.StringGID;
CharSpace = other.CharSpace;
FaceIndex = other.FaceIndex;
return *this;
}
virtual ~CFont()
{
}
};
class CShadow
{
public:
INT Visible;
double DistanceX;
double DistanceY;
double BlurSize;
long Color;
long Alpha;
public:
void SetDefaultParams()
{
Visible = FALSE;
DistanceX = 15;
DistanceY = 15;
BlurSize = 0;
Color = 0;
Alpha = 120;
}
public:
CShadow()
{
SetDefaultParams();
}
CShadow( const CShadow& other )
{
Visible = other.Visible;
DistanceX = other.DistanceX;
DistanceY = other.DistanceY;
BlurSize = other.BlurSize;
Color = other.Color;
Alpha = other.Alpha;
}
CShadow& operator=(const CShadow& other)
{
Visible = other.Visible;
DistanceX = other.DistanceX;
DistanceY = other.DistanceY;
BlurSize = other.BlurSize;
Color = other.Color;
Alpha = other.Alpha;
return *this;
}
virtual ~CShadow()
{
}
};
class CEdgeText
{
public:
long Visible;
double Dist;
long Color;
long Alpha;
public:
void SetDefaultParams()
{
Visible = 0;
Dist = 5;
Color = 0;
Alpha = 255;
}
public:
CEdgeText()
{
SetDefaultParams();
}
CEdgeText( const CEdgeText& other )
{
Visible = other.Visible;
Dist = other.Dist;
Color = other.Color;
Alpha = other.Alpha;
}
CEdgeText& operator=(const CEdgeText& other)
{
Visible = other.Visible;
Dist = other.Dist;
Color = other.Color;
Alpha = other.Alpha;
return *this;
}
virtual ~CEdgeText()
{
}
};
}
#endif // _BUILD_GRAPHICS_STRUCTURES_H_
Markdown is supported
0%
or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment