Files
core/ASCImageStudio3/ASCGraphics/Interfaces/GraphicsRenderer.h

1216 lines
31 KiB
C++

#pragma once
#include "..\stdafx.h"
#include "..\..\..\..\Common\mediaformatdefine.h"
#include "..\agg\ASCWrapper\Graphics.h"
#include "StructuresASC.h"
#include "ImageFilesCache.h"
#include "Metafile.h"
class CGraphicsRenderer
{
friend class CAVSMetafile;
friend class CASCGraphicsRenderer;
protected:
inline BOOL COM_GetBGRAImageFromInterface(IUnknown* pSource, BYTE*& pBGRA, int& nWidth, int& nHeight, int* pStride = NULL, long* pAspectX = NULL, long* pAspectY = NULL)
{
/* @desc:
int COM_GetBGRAImageFromInterface(IUnknown* pSource, BYTE*& pBGRA, int& nWidth, int& nHeight)
{
èç óêàçàííîãî èíòåðôåéñà (pSource) âûòàñêèâàåòñÿ êàðòèíêà (pBGRA, nWidth, nHeight)
â ôîðìàòå BGRA; åñëè ôîðìàò èíòåðôåéñà íå CSP_BGRA - êîíâåðòàöèÿ ôîðìàòà íå ïðîèçâîäèòñÿ
}
*/
if (NULL == pSource)
return FALSE;
// âûòàñêèâàåì èç èíòåðôåéñà uncompressed frame
MediaCore::IAVSUncompressedVideoFrame* pUncompressedFrame = NULL;
pSource->QueryInterface(MediaCore::IID_IAVSUncompressedVideoFrame, (void**)(&pUncompressedFrame));
if (NULL == pUncompressedFrame)
return FALSE;
// çàïðàøèâàåì íàñòðîéêè êàðòèíêè
long lWidth = 0; pUncompressedFrame->get_Width(&lWidth);
long lHeight = 0; pUncompressedFrame->get_Height(&lHeight);
long lColorSpace = 0; pUncompressedFrame->get_ColorSpace(&lColorSpace);
long lStride = 0; pUncompressedFrame->get_Stride(0, &lStride);
long lBufferSize = 0; pUncompressedFrame->get_BufferSize(&lBufferSize);
BYTE* pSourceBuffer = NULL; pUncompressedFrame->get_Buffer(&pSourceBuffer);
// ïðîâåðÿåì ñîâìåñòèìîñòü êàäðà è ôîðìàòà
if (CSP_BGRA != (CSP_COLOR_MASK & lColorSpace) || 4*lWidth != lStride || lWidth < 1 || lHeight < 1 || lBufferSize != 4*lWidth*lHeight || !pSourceBuffer)
{
pUncompressedFrame->Release();
return FALSE;
}
if( pStride )
*pStride = (lColorSpace & CSP_VFLIP) ? -lStride : lStride;
if( pAspectX ) pUncompressedFrame->get_AspectRatioX( pAspectX );
if( pAspectY ) pUncompressedFrame->get_AspectRatioY( pAspectY );
// âñå õîðîøî, îçâðàùàåì íàâåðõ íóæíûå ïàðàìåòðû
pBGRA = pSourceBuffer;
nWidth = lWidth;
nHeight = lHeight;
pUncompressedFrame->Release();
return TRUE;
}
protected:
IASCFontManager* m_pFontManager;
IASCRenderer* m_pASCRenderer;
Aggplus::CGraphics* m_pRenderer;
Aggplus::CGraphicsPath* m_pPath;
public:
NSStructuresASC::CPen m_oPen;
NSStructuresASC::CBrush m_oBrush;
NSStructuresASC::CFont m_oFont;
NSStructuresASC::CShadow m_oShadow;
NSStructuresASC::CEdgeText m_oEdge;
protected:
double m_dWidth;
double m_dHeight;
double m_dPixelsWidth;
double m_dPixelsHeight;
DWORD m_lCurrentCommandType;
LONG m_lCurrentClipMode;
BOOL m_bIsSetupClip;
// îáëàñòü îòñå÷åíèÿ
LONG m_lClipLeft;
LONG m_lClipTop;
LONG m_lClipWidth;
LONG m_lClipHeight;
// ïèêñåëû
BYTE* m_pPixels;
NSStructures::CFont m_oInstalledFont;
NSDocumentViewer::CDIB* m_pDIB;
NSDocumentViewer::CDoubleRect m_oRectBlt;
double m_dBltAngle;
CImageFilesCache* m_pCache;
public:
CGraphicsRenderer(IASCFontManager* pManager = NULL)
{
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 = _T("");
m_pDIB = NULL;
m_dBltAngle = 0.0;
m_pCache = NULL;
m_pASCRenderer = NULL;
}
void SetFontManager(IASCFontManager* pManager = NULL)
{
RELEASEINTERFACE(m_pFontManager);
if (NULL == pManager)
{
CoCreateInstance(__uuidof(CASCFontManager), NULL, CLSCTX_INPROC, __uuidof(IASCFontManager), (void**)&m_pFontManager);
m_pFontManager->Initialize(L"");
m_pFontManager->SetDefaultFont( L"Arial" );
}
else
{
m_pFontManager = pManager;
ADDREFINTERFACE(m_pFontManager);
}
}
void CheckFontManager()
{
if (NULL == m_pFontManager)
{
SetFontManager(NULL);
}
}
void SetImageCache(CImageFilesCache* pCache)
{
RELEASEINTERFACE(m_pCache);
m_pCache = pCache;
ADDREFINTERFACE(m_pCache);
}
inline IASCFontManager* GetFontManager()
{
return m_pFontManager;
}
BYTE* GetPixels(LONG& lWidth, LONG& lHeight)
{
lWidth = (LONG)m_dPixelsWidth;
lHeight = (LONG)m_dPixelsHeight;
return m_pPixels;
}
~CGraphicsRenderer()
{
Clear();
RELEASEOBJECT(m_pDIB);
RELEASEINTERFACE(m_pFontManager);
}
inline void SetRenderer(IASCRenderer* pRenderer)
{
m_pASCRenderer = pRenderer;
}
inline void ClearInstallFont()
{
m_oInstalledFont.Name = _T("");
m_oInstalledFont.Path = _T("");
}
inline void SetClipRect(double x, double y, double w, double h)
{
m_pRenderer->SetClipRect3(x, y, w, h);
}
protected:
BOOL CheckValidate(BOOL bOnlyGraphics = FALSE)
{
if (NULL == m_pRenderer)
return FALSE;
if (!bOnlyGraphics)
{
return (NULL != m_pPath);
}
return TRUE;
}
void Clear()
{
RELEASEOBJECT(m_pPath);
RELEASEOBJECT(m_pRenderer);
}
inline void 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);
}
public:
// ñîçäàíèå ðåíäåðåðà èç ïèêñåëîâ
inline LONG GetCurrentType()
{
return m_lCurrentCommandType;
}
void CreateFromMediaData(IUnknown* punkData)
{
BYTE* pPixels = NULL;
int nWidth = 0;
int nHeight = 0;
int nStride = 0;
if (COM_GetBGRAImageFromInterface(punkData, pPixels, nWidth, nHeight, &nStride))
{
NSDocumentViewer::CDoubleRect oRect;
oRect.left = 0;
oRect.top = 0;
oRect.right = nWidth;
oRect.bottom = nHeight;
if (nStride > 0)
{
CreateFlip(pPixels, oRect, nWidth, nHeight);
}
else
{
Create(pPixels, oRect, nWidth, nHeight);
}
}
}
BOOL CreateFromHDC(HDC hDC, IASCFontManager* pManager, double dWidthMM, double dHeightMM, double dLeft, double dTop, double dWidth, double dHeight, double dAngle)
{
RELEASEOBJECT(m_pDIB);
m_oRectBlt.left = dLeft;
m_oRectBlt.top = dTop;
m_oRectBlt.right = dLeft + dWidth;
m_oRectBlt.bottom = dTop + dHeight;
LONG l1 = GetDeviceCaps(hDC, HORZRES);
LONG l2 = GetDeviceCaps(hDC, VERTRES);
m_dBltAngle = dAngle;
LONG lPixWidthDIB = (LONG)(m_oRectBlt.GetWidth());
LONG lPixHeightDIB = (LONG)(m_oRectBlt.GetHeight());
m_pDIB = new NSDocumentViewer::CDIB();
BOOL bRes = FALSE;
int nCount = 20;
while (!bRes && (nCount > 0))
{
bRes = m_pDIB->Create(lPixWidthDIB, lPixHeightDIB);
--nCount;
}
if (!bRes)
{
RELEASEOBJECT(m_pDIB);
return FALSE;
}
SetFontManager(pManager);
NSDocumentViewer::CDoubleRect _oRect;
_oRect.left = 0;
_oRect.top = 0;
_oRect.right = lPixWidthDIB;
_oRect.bottom = lPixHeightDIB;
memset(m_pDIB->m_pBits, 0xFF, 4 * lPixWidthDIB * lPixHeightDIB);
Create(m_pDIB->m_pBits, _oRect, lPixWidthDIB, lPixHeightDIB);
return TRUE;
}
BOOL BitBlt(HDC hDC)
{
if (NULL != m_pDIB)
{
double dAngle = m_dBltAngle * 180.0 / M_PI;
if ((abs(dAngle - 90) < 1.0) || (abs(dAngle - 270) < 1.0))
{
Gdiplus::Graphics oRender(hDC);
Gdiplus::Bitmap oImage(m_pDIB->m_lWidth, m_pDIB->m_lHeight, -4 * m_pDIB->m_lWidth, PixelFormat32bppARGB,
m_pDIB->m_pBits + 4 * ((m_pDIB->m_lHeight - 1) * m_pDIB->m_lWidth));
Gdiplus::PointF pointCentre((float)m_oRectBlt.GetCentreX(), (float)m_oRectBlt.GetCentreY());
oRender.SetPageUnit(Gdiplus::UnitPixel);
oRender.TranslateTransform(-pointCentre.X, -pointCentre.Y, Gdiplus::MatrixOrderAppend);
oRender.RotateTransform(-90, Gdiplus::MatrixOrderAppend);
oRender.TranslateTransform(pointCentre.X, pointCentre.Y, Gdiplus::MatrixOrderAppend);
oRender.DrawImage(&oImage, (float)m_oRectBlt.left, (float)m_oRectBlt.top, (float)m_oRectBlt.GetWidth(), (float)m_oRectBlt.GetHeight());
return TRUE;
}
NSDocumentViewer::CPainter oPainter;
oPainter.m_hDC = hDC;
m_pDIB->Draw3(&oPainter, m_oRectBlt);
return TRUE;
}
return FALSE;
}
void Create(BYTE* pPixels, const NSDocumentViewer::CDoubleRect& oRect, LONG lWidthControl, LONG lHeightControl, NSDocumentViewer::CDIB* pDib = NULL)
{
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 = max(0, lRectLeft);
m_lClipTop = max(0, lRectTop);
//LONG lClipRight = min(lWidth, -lRectLeft + lWidthControl);
//LONG lClipBottom = min(lHeight, -lRectTop + lHeightControl);
LONG lClipRight = min((LONG)oRect.right, lWidthControl);
LONG lClipBottom = 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);
//m_pRenderer->SetClipRect3(m_lClipLeft, m_lClipTop, m_lClipWidth, m_lClipHeight);
//m_pRenderer->SetClipRect3(0, 0, lWidthControl, lHeightControl);
}
void CreateFlip(BYTE* pPixels, const NSDocumentViewer::CDoubleRect& oRect, LONG lWidthControl, LONG lHeightControl, NSDocumentViewer::CDIB* pDib = NULL)
{
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 = max(0, lRectLeft);
m_lClipTop = max(0, lRectTop);
//LONG lClipRight = min(lWidth, -lRectLeft + lWidthControl);
//LONG lClipBottom = min(lHeight, -lRectTop + lHeightControl);
LONG lClipRight = min((LONG)oRect.right, lWidthControl);
LONG lClipBottom = 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);
//m_pRenderer->SetClipRect3(m_lClipLeft, m_lClipTop, m_lClipWidth, m_lClipHeight);
//m_pRenderer->SetClipRect3(0, 0, lWidthControl, lHeightControl);
}
// ---------------------------------------------
// ôóíêöèè äëÿ ðàáîòû ñî ñòðàíèöåé (çäåñü - òîëüêî ëèøü äëÿ âû÷èñëåíèÿ dpi)
inline STDMETHOD(NewPage)()
{
// íó íå âëåçëî òàê íå âëåçëî
return S_OK;
}
inline STDMETHOD(put_Height)(double dHeight)
{
m_dHeight = dHeight;
if (NULL != m_pRenderer)
{
m_pRenderer->SetPageHeight(m_dHeight, Aggplus::UnitMillimeter);
m_pRenderer->SetPageUnit(Aggplus::UnitMillimeter);
}
return S_OK;
}
inline STDMETHOD(get_Height)(double* dHeight)
{
if (NULL == dHeight)
return S_FALSE;
*dHeight = m_dHeight;
return S_OK;
}
inline STDMETHOD(put_Width)(double dWidth)
{
m_dWidth = dWidth;
if (NULL != m_pRenderer)
{
m_pRenderer->SetPageWidth(m_dWidth, Aggplus::UnitMillimeter);
m_pRenderer->SetPageUnit(Aggplus::UnitMillimeter);
}
return S_OK;
}
inline STDMETHOD(get_Width)(double* dWidth)
{
if (NULL == dWidth)
return S_FALSE;
*dWidth = m_dWidth;
return S_OK;
}
inline STDMETHOD(get_DpiX)(double* dDpiX)
{
if (NULL == dDpiX)
return S_FALSE;
*dDpiX = 25.4 * m_dPixelsWidth / m_dWidth;
return S_OK;
}
inline STDMETHOD(get_DpiY)(double* dDpiY)
{
if (NULL == dDpiY)
return S_FALSE;
*dDpiY = 25.4 * m_dPixelsHeight / m_dHeight;
return S_OK;
}
// ---------------------------------------------
// ôóíêöèè ñîñòîÿíèÿ îòêèñîâùèêà ---------------
inline STDMETHOD(SetPen)(BSTR bsXML)
{
CString str = (CString)bsXML;
m_oPen.FromXmlString(str);
return S_OK;
}
PROPERTY_RENDERER(Pen, Color, LONG)
PROPERTY_RENDERER(Pen, Alpha, LONG)
PROPERTY_RENDERER(Pen, Size, double)
PROPERTY_RENDERER(Pen, DashStyle, BYTE)
PROPERTY_RENDERER(Pen, LineStartCap, BYTE)
PROPERTY_RENDERER(Pen, LineEndCap, BYTE)
PROPERTY_RENDERER(Pen, LineJoin, BYTE)
PROPERTY_RENDERER(Pen, DashOffset, double)
PROPERTY_RENDERER(Pen, Align, LONG)
PROPERTY_RENDERER(Pen, MiterLimit, double)
STDMETHOD(PenDashPattern)(SAFEARRAY* pPattern)
{
if (NULL == pPattern)
return NULL;
m_oPen.SetDashPattern((double*)pPattern->pvData, pPattern->rgsabound[0].cElements);
return S_OK;
}
STDMETHOD(SetBrush)(BSTR bsXML)
{
CString str = (CString)bsXML;
m_oBrush.FromXmlString(str);
return S_OK;
}
PROPERTY_RENDERER(Brush, Type, LONG)
PROPERTY_RENDERER(Brush, Color1, LONG)
PROPERTY_RENDERER(Brush, Color2, LONG)
PROPERTY_RENDERER(Brush, Alpha1, LONG)
PROPERTY_RENDERER(Brush, Alpha2, LONG)
PROPERTY_RENDERER(Brush, TextureMode, LONG)
PROPERTY_RENDERER(Brush, TextureAlpha, LONG)
PROPERTY_RENDERER(Brush, LinearAngle, double)
STDMETHOD(get_BrushTexturePath)(BSTR* bsPath)
{
*bsPath = m_oBrush.TexturePath.AllocSysString();
return S_OK;
}
STDMETHOD(put_BrushTexturePath)(BSTR bsPath)
{
m_oBrush.TexturePath = (CString)bsPath;
return S_OK;
}
STDMETHOD(BrushRect)(BOOL val, double left, double top, double width, 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;
}
STDMETHOD(SetFont)(BSTR bsXML)
{
CString str = (CString)bsXML;
m_oFont.FromXmlString(str);
return S_OK;
}
STDMETHOD(get_FontName)(BSTR* bsName)
{
*bsName = m_oFont.Name.AllocSysString();
return S_OK;
}
STDMETHOD(put_FontName)(BSTR bsName)
{
m_oFont.Name = (CString)bsName;
return S_OK;
}
STDMETHOD(get_FontPath)(BSTR* bsPath)
{
*bsPath = m_oFont.Path.AllocSysString();
return S_OK;
}
STDMETHOD(put_FontPath)(BSTR bsPath)
{
m_oFont.Path = (CString)bsPath;
return S_OK;
}
PROPERTY_RENDERER(Font, Size, double)
STDMETHOD(get_FontStyle)(LONG* val)
{
*val = m_oFont.GetStyle();
return S_OK;
}
STDMETHOD(put_FontStyle)(LONG val)
{
m_oFont.SetStyle(val);
return S_OK;
}
PROPERTY_RENDERER(Font, StringGID, BOOL)
PROPERTY_RENDERER(Font, CharSpace, double)
STDMETHOD(SetShadow)(BSTR bsXML)
{
CString str = (CString)bsXML;
m_oShadow.FromXmlString(str);
return S_OK;
}
PROPERTY_RENDERER(Shadow, DistanceX, double)
PROPERTY_RENDERER(Shadow, DistanceY, double)
PROPERTY_RENDERER(Shadow, BlurSize, double)
PROPERTY_RENDERER(Shadow, Color, LONG)
PROPERTY_RENDERER(Shadow, Alpha, LONG)
PROPERTY_RENDERER(Shadow, Visible, BOOL)
STDMETHOD(SetEdgeText)(BSTR bsXML)
{
CString str = (CString)bsXML;
m_oEdge.FromXmlString(str);
return S_OK;
}
PROPERTY_RENDERER(Edge, Visible, LONG)
PROPERTY_RENDERER(Edge, Color, LONG)
PROPERTY_RENDERER(Edge, Alpha, LONG)
PROPERTY_RENDERER(Edge, Dist, double)
// ---------------------------------------------
// îòðèñîâêà òåêñòà
STDMETHOD(CommandDrawText)(BSTR bsText, double dX, double dY, double dWidth, double dHeight, double dBaseLineOffset)
{
if (c_nHyperlinkType == m_lCurrentCommandType)
return S_OK;
_SetFont();
Aggplus::CBrush* pBrush = Aggplus::CreateBrush(&m_oBrush);
m_pRenderer->DrawString(bsText, m_pFontManager, pBrush, dX, dY + dBaseLineOffset);
RELEASEOBJECT(pBrush);
return S_OK;
}
// ---------------------------------------------
// GraphicPath Methods
STDMETHOD(PathCommandMoveTo)(double fX, double fY)
{
if (!CheckValidate())
return S_FALSE;
m_pPath->MoveTo((double)fX, (double)fY);
return S_OK;
}
STDMETHOD(PathCommandLineTo)(double fX, double fY)
{
if (!CheckValidate())
return S_FALSE;
m_pPath->LineTo((double)fX, (double)fY);
return S_OK;
}
STDMETHOD(PathCommandLinesTo)(SAFEARRAY* pPoints)
{
if (!CheckValidate() || (NULL == pPoints))
return S_FALSE;
LONG lCount = pPoints->rgsabound[0].cElements;
m_pPath->AddLines((double*)pPoints->pvData, lCount);
return S_OK;
}
STDMETHOD(PathCommandCurveTo)(double fX1, double fY1, double fX2, double fY2, double fX3, double fY3)
{
if (!CheckValidate())
return S_FALSE;
m_pPath->CurveTo(fX1, fY1, fX2, fY2, fX3, fY3);
return S_OK;
}
STDMETHOD(PathCommandCurvesTo)(SAFEARRAY* pPoints)
{
if (!CheckValidate())
return S_FALSE;
LONG lCount = pPoints->rgsabound[0].cElements;
m_pPath->AddBeziers((double*)pPoints->pvData, lCount);
return S_OK;
}
STDMETHOD(PathCommandArcTo)(double fX, double fY, double fWidth, double fHeight, double fStartAngle, double fSweepAngle)
{
if (!CheckValidate())
return S_FALSE;
m_pPath->AddArc2(fX, fY, fWidth, fHeight, -fStartAngle, -fSweepAngle);
return S_OK;
}
STDMETHOD(PathCommandClose)()
{
if (!CheckValidate())
return S_FALSE;
m_pPath->CloseFigure();
return S_OK;
}
STDMETHOD(PathCommandEnd)()
{
m_pPath->Reset();
return S_OK;
}
STDMETHOD(PathCommandStart)()
{
if (!CheckValidate())
return S_FALSE;
m_pPath->StartFigure();
return S_OK;
}
STDMETHOD(PathCommandGetCurrentPoint)(double* fX, double* fY)
{
m_pPath->GetLastPoint(*fX, *fY);
return S_OK;
}
STDMETHOD(DrawPath)(long nType)
{
if (!CheckValidate(TRUE))
return S_FALSE;
LONG lFillType = (nType & 0xFF00);
BOOL bIsStroke = (0x01 == (nType & 0x01));
if ((lFillType != 0) && (m_oBrush.Type == c_BrushTypeTexture || m_oBrush.Type == c_BrushTypePattern) && (NULL != m_pASCRenderer))
{
CImageExt oExt;
LONG lType = oExt.GetImageType(m_oBrush.TexturePath);
if (0 != lType)
{
double x = 0;
double y = 0;
double w = 0;
double h = 0;
m_pPath->GetBounds(x, y, w, h);
BSTR bsPath = m_oBrush.TexturePath.AllocSysString();
oExt.DrawOnRenderer(m_pASCRenderer, bsPath, x, y, w, h);
SysFreeString(bsPath);
if (bIsStroke)
{
m_pRenderer->DrawPath(&m_oPen, m_pPath);
}
return S_OK;
}
}
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);
}
}
pBrush = pTextureBrush;
}
else
{
pBrush = m_oBrush.GetBrush();
}
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 = m_oBrush.GetBrush();
}
//Aggplus::CBrush* pBrush = m_oBrush.GetBrush();
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;
}
// ---------------------------------------------
STDMETHOD(DrawImage)(IUnknown* pInterface, double fX, double fY, double fWidth, double fHeight)
{
if (!CheckValidate(TRUE) || NULL == pInterface)
return S_FALSE;
BYTE* pBGRA = NULL;
int nWidth = 0;
int nHeight = 0;
int lStride = 0;
BOOL bRes = COM_GetBGRAImageFromInterface(pInterface, pBGRA, nWidth, nHeight, &lStride);
if (!bRes)
return S_FALSE;
if (m_pRenderer->IsClip())
{
Aggplus::CBitmap oImage( nWidth, nHeight, lStride, PixelFormat32bppARGB, pBGRA );
m_pRenderer->DrawImage(&oImage, fX, fY, fWidth, fHeight);
return S_OK;
}
// çäåñü ìû âíóòðè êàðòèíêè ïåðåâåðíåì
if (0 > lStride)
{
// ïåðåâîðà÷èâàåì èçîáðàæåíèå äëÿ GDI+
pBGRA += 4 * nWidth * (nHeight - 1);
}
Gdiplus::Bitmap oImageGP( nWidth, nHeight, lStride, PixelFormat32bppARGB, pBGRA );
m_pRenderer->DrawGdiplusImage(&oImageGP, fX, fY, fWidth, fHeight);
return S_OK;
}
//----------------------------------------------
STDMETHOD(SetAdditionalParam)(BSTR ParamName, VARIANT ParamValue)
{
return S_OK;
}
STDMETHOD(GetAdditionalParam)(BSTR ParamName, VARIANT* ParamValue)
{
return S_OK;
}
// new
STDMETHOD(BeginCommand)(DWORD lType)
{
m_lCurrentCommandType = lType;
switch (lType)
{
case c_nPageType:
{
return NewPage();
}
default:
break;
};
return S_OK;
}
STDMETHOD(EndCommand)(DWORD lType)
{
switch (lType)
{
case c_nClipType:
{
BOOL bIsIn = (c_nClipRegionTypeWinding == (0x0001 & m_lCurrentClipMode));
m_pPath->SetRuler(bIsIn ? false : true);
BOOL 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;
}
STDMETHOD(CommandDrawTextEx)(BSTR bsText, BSTR bsGidText, BSTR bsSourceCodeText, double fX, double fY, double fWidth, double fHeight, double fBaseLineOffset, DWORD lFlags)
{
if (NULL != bsGidText)
{
m_oFont.StringGID = TRUE;
return CommandDrawText(bsGidText, fX, fY, fWidth, fHeight, fBaseLineOffset);
}
m_oFont.StringGID = FALSE;
return CommandDrawText(bsText, fX, fY, fWidth, fHeight, fBaseLineOffset);
}
STDMETHOD(DrawImageFromFile)(BSTR bstrVal, double fX, double fY, double fWidth, double fHeight)
{
if (m_pRenderer->IsDib())
{
CImageExt oImageExt;
LONG lType = oImageExt.GetImageType((CString)bstrVal);
if (0 != lType)
{
if (NULL != m_pASCRenderer)
{
oImageExt.DrawOnRenderer(m_pASCRenderer, bstrVal, fX, fY, fWidth, fHeight);
}
else
{
m_pRenderer->DrawMeta(bstrVal, fX, fY, fWidth, fHeight);
}
return S_OK;
}
}
CCacheImage* pCacheImage = NULL;
if (NULL != m_pCache)
{
pCacheImage = m_pCache->Lock((CString)bstrVal);
}
if (NULL != pCacheImage)
{
Aggplus::CImage* pImage = pCacheImage->GetImage();
//m_pRenderer->DrawImage(&oImage, fX, fY, fWidth, fHeight);
BYTE* pBGRA = pImage->m_pImgData;
if (0 > pImage->m_nStride)
{
// ïåðåâîðà÷èâàåì èçîáðàæåíèå äëÿ GDI+
pBGRA += 4 * pImage->m_dwWidth * (pImage->m_dwHeight - 1);
}
Gdiplus::Bitmap oImageGdi( pImage->m_dwWidth, pImage->m_dwHeight, pImage->m_nStride, PixelFormat32bppARGB, pBGRA );
m_pRenderer->DrawGdiplusImage(&oImageGdi, fX, fY, fWidth, fHeight);
RELEASEINTERFACE(pCacheImage);
}
else
{
Aggplus::CBitmap oImage(bstrVal);
//m_pRenderer->DrawImage(&oImage, fX, fY, fWidth, fHeight);
BYTE* pBGRA = oImage.m_pImgData;
if (0 > oImage.m_nStride)
{
// ïåðåâîðà÷èâàåì èçîáðàæåíèå äëÿ GDI+
pBGRA += 4 * oImage.m_dwWidth * (oImage.m_dwHeight - 1);
}
Gdiplus::Bitmap oImageGdi( oImage.m_dwWidth, oImage.m_dwHeight, oImage.m_nStride, PixelFormat32bppARGB, pBGRA );
m_pRenderer->DrawGdiplusImage(&oImageGdi, fX, fY, fWidth, fHeight);
}
return S_OK;
}
STDMETHOD(GetCommandParams)(double* dAngle, double* dLeft, double* dTop, double* dWidth, double* dHeight, DWORD* lFlags)
{
return S_OK;
}
STDMETHOD(SetCommandParams)(double dAngle, double dLeft, double dTop, double dWidth, double dHeight, DWORD lFlags)
{
ApplyTransform2(dAngle, dLeft, dTop, dWidth, dHeight, lFlags);
return S_OK;
}
STDMETHOD(SetTransform)(double dA, double dB, double dC, double dD, double dE, double dF)
{
if (!CheckValidate())
return S_FALSE;
ApplyTransform(dA, dB, dC, dD, dE, dF);
return S_OK;
}
STDMETHOD(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;
}
STDMETHOD(ResetTransform)(void)
{
_ResetTransform();
return S_OK;
}
STDMETHOD(get_ClipMode)(LONG* plMode)
{
if ((!CheckValidate()) || (NULL == plMode))
return S_FALSE;
*plMode = m_lCurrentClipMode;
return S_OK;
}
STDMETHOD(put_ClipMode)(LONG lMode)
{
if (!CheckValidate())
return S_FALSE;
m_lCurrentClipMode = lMode;
return S_OK;
}
STDMETHOD(PathCommandText)(BSTR bsText, double fX, double fY, double fWidth, double fHeight, double fBaseLineOffset)
{
if (!CheckValidate())
return S_FALSE;
_SetFont();
// òàê êàê ïàò ðèñóåòñÿ â ìèëëèìåòðàõ - íàäî ïåðåâåñòè ïóíêòû â ìèëëèìåòðû
float fSize = (float)(0.3528 * m_oFont.Size);
m_pPath->AddString(bsText, m_pFontManager, fX, fY);
return S_OK;
}
STDMETHOD(PathCommandTextEx)(BSTR bsText, BSTR bsGidText, BSTR bsSourceCodeText, double fX, double fY, double fWidth, double fHeight, double fBaseLineOffset, DWORD lFlags)
{
if (NULL != bsGidText)
{
m_oFont.StringGID = TRUE;
return PathCommandText(bsGidText, fX, fY, fWidth, fHeight, fBaseLineOffset);
}
m_oFont.StringGID = FALSE;
return PathCommandText(bsText, fX, fY, fWidth, fHeight, fBaseLineOffset);
}
protected:
void _SetFont()
{
if (m_oInstalledFont.IsEqual(&m_oFont))
{
if (1 < m_dWidth)
{
double dPix = m_oFont.CharSpace * m_dPixelsWidth / m_dWidth;
m_pFontManager->SetCharSpacing(dPix);
}
return;
}
m_pFontManager->SetStringGID(m_oFont.StringGID);
if (1 < m_dWidth)
{
double dPix = m_oFont.CharSpace * m_dPixelsWidth / m_dWidth;
m_pFontManager->SetCharSpacing(dPix);
}
if (_T("") == m_oFont.Path)
{
BSTR bsName = m_oFont.Name.AllocSysString();
m_pFontManager->LoadFontByName(bsName, (float)m_oFont.Size, m_oFont.GetStyle(), m_pRenderer->GetDpiX(), m_pRenderer->GetDpiY());
SysFreeString(bsName);
}
else
{
BSTR bsName = m_oFont.Path.AllocSysString();
m_pFontManager->LoadFontFromFile(bsName, (float)m_oFont.Size, m_pRenderer->GetDpiX(), m_pRenderer->GetDpiY());
SysFreeString(bsName);
}
m_oInstalledFont = m_oFont;
}
void ApplyTransform(double d1, double d2, double d3, double d4, double d5, double d6)
{
Aggplus::CMatrix oMatrix(d1, d2, d3, d4, d5, d6);
ApplyTransform(&oMatrix);
}
void ApplyTransform2(double dAngle, double dLeft, double dTop, double dWidth, double dHeight, DWORD lFlags)
{
if ((dWidth <= 1) || (dHeight <= 1))
lFlags = 0;
BOOL bFlipX = (0 != (c_nParamFlipX & lFlags));
BOOL bFlipY = (0 != (c_nParamFlipY & lFlags));
double m11 = bFlipX ? -1.0 : 1.0;
double m22 = bFlipY ? -1.0 : 1.0;
Aggplus::CMatrix oMatrix(1, 0, 0, 1, 0, 0);
if ((0 != dAngle) || (0 != lFlags))
{
double dCentreX = (dLeft + dWidth / 2.0);
double dCentreY = (dTop + dHeight / 2.0);
oMatrix.Translate(-dCentreX, -dCentreY , Aggplus::MatrixOrderAppend);
oMatrix.Rotate(dAngle , Aggplus::MatrixOrderAppend);
oMatrix.Scale(m11, m22 , Aggplus::MatrixOrderAppend);
oMatrix.Translate(dCentreX, dCentreY , Aggplus::MatrixOrderAppend);
}
ApplyTransform(&oMatrix);
}
inline void ApplyTransform(Aggplus::CMatrix* pMatrix)
{
if (!CheckValidate())
return;
m_pRenderer->SetTransform(pMatrix);
m_pRenderer->CalculateFullTransform();
}
inline void _ResetTransform()
{
if (!CheckValidate())
return;
ApplyTransform(1, 0, 0, 1, 0, 0);
}
};