#pragma once #include "..\stdafx.h" #include "..\Objects\Structures.h" #include "..\Interfaces\ASCRenderer.h" #include "..\Interfaces\IASCGraphicsRenderer.h" #include "TemporaryCS.h" #include "..\Objects\ASCImage.h" #include "..\agg\ASCWrapper\DIB.h" #include "..\agg\ASCWrapper\ArrowHead.h" #include "../../../Common/MediaFormatDefine.h" // IASCMetafile [object, uuid("8E19E616-F99C-46c9-B56D-BFF98241EB39"), dual, pointer_default(unique)] __interface IASCMetafile : IASCRenderer { [id(20000)] HRESULT Draw([in] IUnknown* punkRenderer, [in] BOOL* pBreak); [id(20001)] HRESULT Draw2([in] IUnknown* punkRenderer, [in] double dDPIX, [in] double dDPIY, [in] BOOL* pBreak); [id(20002)] HRESULT Save([in] BSTR bsFile, [in] DWORD dwType, [in] BSTR bsParams); [id(20003)] HRESULT SetPageInstance([in] IUnknown* punkInstance, [in] LONG lPage); [id(20005)] HRESULT SetAdditionalCommands([in] BSTR bsXml); }; class CImageExt { public: LONG GetImageType(CString strFile) { CFile oFile; if (S_OK != oFile.OpenFile(strFile)) { oFile.CloseFile(); return 0; } DWORD dwSize = (DWORD)oFile.GetFileSize(); if (44 > dwSize) { return 0; } DWORD dwKey = 0; oFile.ReadFile((BYTE*)(&dwKey), 4); if (0x9AC6CDD7 == dwKey) { // placeable meta oFile.CloseFile(); return 1; } if (0x00000001 == dwKey) { oFile.SetPosition(40); oFile.ReadFile((BYTE*)(&dwKey), 4); oFile.CloseFile(); if (0x464D4520 == dwKey) { // EMF/EMF+ return 2; } else { // return 0; } } oFile.CloseFile(); if (0x00090001 == dwKey) { return 1; } return 0; } void DrawOnRenderer(IASCRenderer* pRenderer, BSTR strFile, double dX, double dY, double dW, double dH, BOOL bIsFromFileUse = TRUE) { if (NULL == pRenderer) return; LONG lRendType = 0; pRenderer->get_Type(&lRendType); if (c_nPDFWriter == lRendType) { VARIANT var; var.vt = VT_BOOL; var.boolVal = VARIANT_TRUE; pRenderer->SetAdditionalParam(L"WhiteBackImage", var); } LONG lFileType = 0; if (c_nEbookWriter != lRendType) lFileType = GetImageType((CString)strFile); BOOL bIsGraphics = FALSE; IASCGraphicsRenderer* pGR = NULL; pRenderer->QueryInterface(__uuidof(IASCGraphicsRenderer), (void**)&pGR); if (NULL != pGR) { bIsGraphics = TRUE; } RELEASEINTERFACE(pGR); if (0 == lFileType) { // картинка if (bIsGraphics) { pRenderer->DrawImageFromFile(strFile, dX, dY, dW, dH); } else { IUnknown* pImage = ImageStudio::ISLoadImage(strFile); pRenderer->DrawImage(pImage, dX, dY, dW, dH); RELEASEINTERFACE(pImage); } } else if (1 == lFileType || 2 == lFileType) { // Запоминаем все настройки Brush, Font, Pen, Shadow и т.д. NSStructures::CBrush oBrush; BSTR bsBrushTexturePath = NULL; pRenderer->get_BrushAlpha1( &oBrush.Alpha1 ); pRenderer->get_BrushAlpha2( &oBrush.Alpha2 ); pRenderer->get_BrushColor1( &oBrush.Color1 ); pRenderer->get_BrushColor2( &oBrush.Color2 ); pRenderer->get_BrushLinearAngle( &oBrush.LinearAngle ); pRenderer->get_BrushTextureMode( &oBrush.TextureMode ); pRenderer->get_BrushTextureAlpha( &oBrush.TextureAlpha ); pRenderer->get_BrushTexturePath( &bsBrushTexturePath ); pRenderer->get_BrushType( &oBrush.Type ); NSStructures::CFont oFont; BSTR bsFontPath = NULL, bsFontName = NULL; pRenderer->get_FontName( &bsFontName ); pRenderer->get_FontPath( &bsFontPath ); pRenderer->get_FontSize( &oFont.Size ); LONG lStyle; pRenderer->get_FontStyle( &lStyle ); oFont.Bold = lStyle & FontConstants::FontStyleBold; oFont.Italic = lStyle & FontConstants::FontStyleItalic; oFont.Strikeout = lStyle & FontConstants::FontStyleStrikeout; oFont.Underline = lStyle & FontConstants::FontStyleUnderline; pRenderer->get_FontStringGID( &oFont.StringGID ); NSStructures::CPen oPen; pRenderer->get_PenAlign( &oPen.Align ); pRenderer->get_PenAlpha( &oPen.Alpha ); pRenderer->get_PenColor( &oPen.Color ); IAVSImage *pImage = NULL; CoCreateInstance( __uuidof(CAVSImage), NULL, CLSCTX_ALL, __uuidof(IAVSImage), (void**)(&pImage) ); pImage->put_FontManager(NULL); pImage->LoadFromFile( strFile ); pImage->DrawOnRenderer( pRenderer, dX, dY, dW, dH ); RELEASEINTERFACE( pImage ); // Восстанавливаем параметры pRenderer->put_BrushAlpha1( oBrush.Alpha1 ); pRenderer->put_BrushAlpha2( oBrush.Alpha2 ); pRenderer->put_BrushColor1( oBrush.Color1 ); pRenderer->put_BrushColor2( oBrush.Color2 ); pRenderer->put_BrushLinearAngle( oBrush.LinearAngle ); pRenderer->put_BrushTextureMode( oBrush.TextureMode ); pRenderer->put_BrushTextureAlpha( oBrush.TextureAlpha ); pRenderer->put_BrushTexturePath( bsBrushTexturePath ); if ( bsBrushTexturePath ) ::SysFreeString( bsBrushTexturePath ); pRenderer->put_BrushType( oBrush.Type ); pRenderer->put_FontName( bsFontName ); if ( bsFontName ) ::SysFreeString( bsFontName ); pRenderer->put_FontPath( bsFontPath ); if ( bsFontPath ) ::SysFreeString( bsFontPath ); pRenderer->put_FontSize( oFont.Size ); pRenderer->put_FontStyle( oFont.GetStyle() ); pRenderer->put_FontStringGID( oFont.StringGID ); pRenderer->put_PenAlign( oPen.Align ); pRenderer->put_PenAlpha( oPen.Alpha ); pRenderer->put_PenColor( oPen.Color ); // на всякий случай скидываем path pRenderer->PathCommandEnd(); } else if (2 == lFileType) { if (bIsGraphics) { pRenderer->DrawImageFromFile(strFile, dX, dY, dW, dH); return; } NSDocumentViewer::CDIB oSection; double dDpiX = 0; double dDpiY = 0; pRenderer->get_DpiX(&dDpiX); pRenderer->get_DpiY(&dDpiY); LONG lPixW = (LONG)dW * dDpiX / NSDocumentViewer::c_dInch_to_MM; LONG lPixH = (LONG)dH * dDpiX / NSDocumentViewer::c_dInch_to_MM; oSection.Create(lPixW, lPixH, dDpiX, dDpiY); LONG lCount = lPixW * lPixH; memset(oSection.m_pBits, 0xFF, 4 * lCount); HDC hDC = GetDC(NULL); HDC memDC = CreateCompatibleDC(hDC); ReleaseDC(0, hDC); HBITMAP hOldBitmap = (HBITMAP)SelectObject(memDC, oSection.m_hBitmap); RECT oRectPlay; oRectPlay.left = 0; oRectPlay.top = 0; oRectPlay.right = lPixW; oRectPlay.bottom = lPixH; HENHMETAFILE hMeta = GetEnhMetaFile(strFile); PlayEnhMetaFile(memDC, hMeta, &oRectPlay); DeleteEnhMetaFile(hMeta); MediaCore::IAVSUncompressedVideoFrame* pMediaData = NULL; CoCreateInstance(MediaCore::CLSID_CAVSUncompressedVideoFrame, NULL, CLSCTX_INPROC, MediaCore::IID_IAVSUncompressedVideoFrame, (void**)&pMediaData); pMediaData->put_ColorSpace(CSP_VFLIP | CSP_BGRA); pMediaData->put_Width(lPixW); pMediaData->put_Height(lPixH); pMediaData->SetDefaultStrides(); pMediaData->AllocateBuffer(-1); BYTE* pPixels = NULL; pMediaData->get_Buffer(&pPixels); memcpy(pPixels, oSection.m_pBits, 4 * lPixW * lPixH); DeleteObject(hOldBitmap); DeleteDC(memDC); IUnknown* punkImage = NULL; pMediaData->QueryInterface(IID_IUnknown, (void**)&punkImage); RELEASEINTERFACE(pMediaData); pRenderer->DrawImage(punkImage, dX, dY, dW, dH); RELEASEINTERFACE(punkImage); } } }; class CMetafile { private: inline LONG __strlen(const char* str) { const char* s = str; for (; *s != 0; ++s); return (LONG)(s - str); } inline LONG __wstrlen(const wchar_t* str) { const wchar_t* s = str; for (; *s != 0; ++s); return (LONG)(s - str); } private: enum CommandType { // pen ctPenXML = 0, ctPenColor = 1, ctPenAlpha = 2, ctPenSize = 3, ctPenDashStyle = 4, ctPenLineStartCap = 5, ctPenLineEndCap = 6, ctPenLineJoin = 7, ctPenDashPatern = 8, ctPenDashPatternCount = 9, ctPenDashOffset = 10, ctPenAlign = 11, ctPenMiterLimit = 12, // brush ctBrushXML = 20, ctBrushType = 21, ctBrushColor1 = 22, ctBrushColor2 = 23, ctBrushAlpha1 = 24, ctBrushAlpha2 = 25, ctBrushTexturePath = 26, ctBrushTextureAlpha = 27, ctBrushTextureMode = 28, ctBrushRectable = 29, ctBrushAngle = 30, ctBrushSubColors = 31, // font ctFontXML = 40, ctFontName = 41, ctFontSize = 42, ctFontStyle = 43, ctFontPath = 44, ctFontGID = 45, ctFontCharSpace = 46, // shadow ctShadowXML = 50, ctShadowVisible = 51, ctShadowDistanceX = 52, ctShadowDistanceY = 53, ctShadowBlurSize = 54, ctShadowColor = 55, ctShadowAlpha = 56, // edge ctEdgeXML = 70, ctEdgeVisible = 71, ctEdgeDistance = 72, ctEdgeColor = 73, ctEdgeAlpha = 74, // text ctDrawText = 80, ctDrawTextEx = 81, // pathcommands ctPathCommandMoveTo = 91, ctPathCommandLineTo = 92, ctPathCommandLinesTo = 93, ctPathCommandCurveTo = 94, ctPathCommandCurvesTo = 95, ctPathCommandArcTo = 96, ctPathCommandClose = 97, ctPathCommandEnd = 98, ctDrawPath = 99, ctPathCommandStart = 100, ctPathCommandGetCurrentPoint = 101, ctPathCommandText = 102, ctPathCommandTextEx = 103, // image ctDrawImage = 110, ctDrawImageFromFile = 111, ctSetParams = 120, ctBeginCommand = 121, ctEndCommand = 122, ctSetTransform = 130, ctResetTransform = 131, ctClipMode = 140, ctCommandLong1 = 150, ctCommandDouble1 = 151, ctCommandString1 = 152, ctCommandLong2 = 153, ctCommandDouble2 = 154, ctCommandString2 = 155, ctError = 255 }; public: // состояние NSStructures::CPen m_oPen; NSStructures::CBrush m_oBrush; NSStructures::CFont m_oFont; NSStructures::CShadow m_oShadow; NSStructures::CEdgeText m_oEdge; private: // сам метафайл BYTE* m_pBuffer; BYTE* m_pBufferMem; size_t m_lPosition; size_t m_lSize; CAtlArray m_arStrings; CAtlArray m_arImages; LONG m_lSizeofDouble; LONG m_lSizeofFloat; LONG m_lSizeofLONG; LONG m_lSizeofBYTE; // окончание пена Aggplus::CArrowHead m_oArrowHead; CRITICAL_SECTION m_oCS; IASCMetafile* m_pAdditionalCommands; public: double m_fWidth; double m_fHeight; public: CMetafile() { InitializeCriticalSection(&m_oCS); m_pAdditionalCommands = NULL; Clear(); m_lSizeofDouble = sizeof(double); m_lSizeofFloat = sizeof(float); m_lSizeofLONG = sizeof(long); m_lSizeofBYTE = sizeof(BYTE); } ~CMetafile() { RELEASEARRAYOBJECTS(m_pBuffer); size_t nCount = m_arImages.GetCount(); for (size_t nIndex = 0; nIndex < nCount; ++nIndex) { IUnknown* punkImage = m_arImages[nIndex]; RELEASEINTERFACE(punkImage); } m_arImages.RemoveAll(); RELEASEINTERFACE(m_pAdditionalCommands); DeleteCriticalSection(&m_oCS); } protected: inline void Clear() { m_lSize = 0; m_lPosition = 0; m_pBuffer = NULL; m_arImages.RemoveAll(); } inline void CheckBufferSize(size_t lPlus) { if (NULL != m_pBuffer) { size_t nNewSize = m_lPosition + lPlus; if (nNewSize >= m_lSize) { while (nNewSize >= m_lSize) { m_lSize *= 2; } BYTE* pNew = new BYTE[m_lSize]; memcpy(pNew, m_pBuffer, m_lPosition); RELEASEARRAYOBJECTS(m_pBuffer); m_pBuffer = pNew; } } else { m_lSize = 1000; m_pBuffer = new BYTE[m_lSize]; CheckBufferSize(lPlus); } } inline void WriteCommandType(const CommandType& eType) { CheckBufferSize(m_lSizeofBYTE); *(m_pBuffer + m_lPosition) = (BYTE)eType; m_lPosition += m_lSizeofBYTE; } inline void WriteBYTE(const BYTE& lValue) { CheckBufferSize(m_lSizeofBYTE); *(m_pBuffer + m_lPosition) = lValue; m_lPosition += m_lSizeofBYTE; } inline void WriteLONG(const LONG& lValue) { CheckBufferSize(m_lSizeofLONG); *((LONG*)(m_pBuffer + m_lPosition)) = lValue; m_lPosition += m_lSizeofLONG; } inline void WriteDouble(const double& dValue) { CheckBufferSize(m_lSizeofDouble); *((double*)(m_pBuffer + m_lPosition)) = dValue; m_lPosition += m_lSizeofDouble; } inline void WriteFloat(const float& fValue) { CheckBufferSize(m_lSizeofFloat); *((float*)(m_pBuffer + m_lPosition)) = fValue; m_lPosition += m_lSizeofFloat; } inline void WriteBSTR(BSTR bstrValue) { LONG lSize = __wstrlen(bstrValue) + 1; LONG lSizeMem = lSize * sizeof(wchar_t); CheckBufferSize(m_lSizeofLONG + lSizeMem); *((LONG*)(m_pBuffer + m_lPosition)) = lSizeMem; m_lPosition += m_lSizeofLONG; memcpy(m_pBuffer + m_lPosition, bstrValue, lSizeMem); m_lPosition += lSizeMem; } inline void WriteBYTE(const CommandType& eType, const BYTE& lValue) { CheckBufferSize(2 * m_lSizeofBYTE); *(m_pBuffer + m_lPosition) = (BYTE)eType; m_lPosition += m_lSizeofBYTE; *(m_pBuffer + m_lPosition) = lValue; m_lPosition += m_lSizeofBYTE; } inline void WriteLONG(const CommandType& eType, const LONG& lValue) { CheckBufferSize(m_lSizeofBYTE + m_lSizeofLONG); *(m_pBuffer + m_lPosition) = (BYTE)eType; m_lPosition += m_lSizeofBYTE; *((LONG*)(m_pBuffer + m_lPosition)) = lValue; m_lPosition += m_lSizeofLONG; } inline void WriteDouble(const CommandType& eType, const double& dValue) { CheckBufferSize(m_lSizeofBYTE + m_lSizeofDouble); *(m_pBuffer + m_lPosition) = (BYTE)eType; m_lPosition += m_lSizeofBYTE; *((double*)(m_pBuffer + m_lPosition)) = dValue; m_lPosition += m_lSizeofDouble; } inline void WriteFloat(const CommandType& eType, const float& fValue) { CheckBufferSize(m_lSizeofBYTE + m_lSizeofFloat); *(m_pBuffer + m_lPosition) = (BYTE)eType; m_lPosition += m_lSizeofBYTE; *((float*)(m_pBuffer + m_lPosition)) = fValue; m_lPosition += m_lSizeofFloat; } inline void WriteBSTR(const CommandType& eType, BSTR bstrValue) { LONG lSize = __wstrlen(bstrValue) + 1; LONG lSizeMem = lSize * sizeof(wchar_t); CheckBufferSize(m_lSizeofBYTE + m_lSizeofLONG + lSizeMem); *(m_pBuffer + m_lPosition) = (BYTE)eType; m_lPosition += m_lSizeofBYTE; *((LONG*)(m_pBuffer + m_lPosition)) = lSizeMem; m_lPosition += m_lSizeofLONG; memcpy(m_pBuffer + m_lPosition, bstrValue, lSizeMem); m_lPosition += lSizeMem; } inline void Write(const CommandType& eCommand, const double& f1, const double& f2) { size_t lMem = m_lSizeofBYTE + 2 * m_lSizeofDouble; CheckBufferSize(lMem); *(m_pBuffer + m_lPosition) = (BYTE)eCommand; m_lPosition += m_lSizeofBYTE; *((double*)(m_pBuffer + m_lPosition))= f1; m_lPosition += m_lSizeofDouble; *((double*)(m_pBuffer + m_lPosition))= f2; m_lPosition += m_lSizeofDouble; } inline void Write(const CommandType& eCommand, const double& f1, const double& f2, const double& f3, const double& f4, const double& f5, const double& f6) { size_t lMem = m_lSizeofBYTE + 6 * m_lSizeofDouble; CheckBufferSize(lMem); *(m_pBuffer + m_lPosition) = (BYTE)eCommand; m_lPosition += m_lSizeofBYTE; *((double*)(m_pBuffer + m_lPosition))= f1; m_lPosition += m_lSizeofDouble; *((double*)(m_pBuffer + m_lPosition))= f2; m_lPosition += m_lSizeofDouble; *((double*)(m_pBuffer + m_lPosition))= f3; m_lPosition += m_lSizeofDouble; *((double*)(m_pBuffer + m_lPosition))= f4; m_lPosition += m_lSizeofDouble; *((double*)(m_pBuffer + m_lPosition))= f5; m_lPosition += m_lSizeofDouble; *((double*)(m_pBuffer + m_lPosition))= f6; m_lPosition += m_lSizeofDouble; } inline void Write(const CommandType& eCommand, const LONG& lCount, float* pData) { size_t lFloats = lCount * m_lSizeofFloat; size_t lMem = m_lSizeofBYTE + m_lSizeofLONG + lFloats; CheckBufferSize(lMem); *(m_pBuffer + m_lPosition) = (BYTE)eCommand; m_lPosition += m_lSizeofBYTE; *((LONG*)(m_pBuffer + m_lPosition)) = lCount; m_lPosition += m_lSizeofLONG; memcpy(m_pBuffer + m_lPosition, pData, lFloats); m_lPosition += lFloats; } inline void Write(const CommandType& eCommand, const LONG& lCount, double* pData) { size_t lFloats = lCount * m_lSizeofDouble; size_t lMem = m_lSizeofBYTE + m_lSizeofLONG + lFloats; CheckBufferSize(lMem); *(m_pBuffer + m_lPosition) = (BYTE)eCommand; m_lPosition += m_lSizeofBYTE; *((LONG*)(m_pBuffer + m_lPosition)) = lCount; m_lPosition += m_lSizeofLONG; memcpy(m_pBuffer + m_lPosition, pData, lFloats); m_lPosition += lFloats; } public: // pen --------------------------------------------------------------------------------- inline void PenXML(BSTR bsXml) { NSStructures::CPen oNewPen; oNewPen.FromXmlString(CString(bsXml)); PenColor(oNewPen.Color); PenAlpha(oNewPen.Alpha); PenSize(oNewPen.Size); PenDashStyle(oNewPen.DashStyle); PenLineStartCap(oNewPen.LineStartCap); PenLineEndCap(oNewPen.LineEndCap); PenLineJoin(oNewPen.LineJoin); PenDashPatern(oNewPen.DashPattern, oNewPen.Count); PenDashOffset(oNewPen.DashOffset); PenAlign(oNewPen.Align); } inline void Pen(NSStructures::CPen* pNewPen) { PenColor(pNewPen->Color); PenAlpha(pNewPen->Alpha); PenSize(pNewPen->Size); PenDashStyle(pNewPen->DashStyle); PenLineStartCap(pNewPen->LineStartCap); PenLineEndCap(pNewPen->LineEndCap); PenLineJoin(pNewPen->LineJoin); PenDashPatern(pNewPen->DashPattern, pNewPen->Count); PenDashOffset(pNewPen->DashOffset); PenAlign(pNewPen->Align); } inline void PenXMLAttack(BSTR bsXml) { WriteBSTR(ctPenXML, bsXml); } inline void PenColor(const LONG& lColor) { if (m_oPen.Color != lColor) { m_oPen.Color = lColor; WriteLONG(ctPenColor, lColor); } } inline void PenAlpha(const LONG& lAlpha) { if (m_oPen.Alpha != lAlpha) { m_oPen.Alpha = lAlpha; WriteBYTE(ctPenAlpha, (BYTE)lAlpha); } } inline void PenSize(const double& dSize) { if (m_oPen.Size != dSize) { m_oPen.Size = dSize; WriteDouble(ctPenSize, dSize); } } inline void PenDashStyle(const BYTE& val) { if (m_oPen.DashStyle != val) { m_oPen.DashStyle = val; WriteBYTE(ctPenDashStyle, val); } } inline void PenLineStartCap(const BYTE& val) { if (m_oPen.LineStartCap != val) { m_oPen.LineStartCap = val; WriteBYTE(ctPenLineStartCap, val); } } inline void PenLineEndCap(const BYTE& val) { if (m_oPen.LineEndCap != val) { m_oPen.LineEndCap = val; m_oArrowHead.SetType(val); WriteBYTE(ctPenLineEndCap, val); } } inline void PenLineJoin(const BYTE& val) { if (m_oPen.LineJoin != val) { m_oPen.LineJoin = val; WriteBYTE(ctPenLineJoin, val); } } inline void PenDashPatern(double* pPattern, LONG lCount) { if ((NULL != pPattern) && (0 < lCount)) { m_oPen.SetDashPattern(pPattern, lCount); LONG lSizeMem = lCount * m_lSizeofDouble; LONG lMem = m_lSizeofBYTE + m_lSizeofLONG + lSizeMem; CheckBufferSize(lMem); *(m_pBuffer + m_lPosition) = (BYTE)ctPenDashPatern; m_lPosition += m_lSizeofBYTE; *((LONG*)(m_pBuffer + m_lPosition)) = lCount; m_lPosition += m_lSizeofLONG; memcpy(m_pBuffer + m_lPosition, pPattern, lSizeMem); m_lPosition += lSizeMem; } } inline void PenDashOffset(const double& fOffset) { if (m_oPen.DashOffset != fOffset) { m_oPen.DashOffset = fOffset; WriteDouble(ctPenDashOffset, fOffset); } } inline void PenAlign(const LONG& val) { if (m_oPen.Align != val) { m_oPen.Align = val; WriteLONG(ctPenAlign, val); } } inline void PenMiterLimit(const double& val) { if (m_oPen.MiterLimit != val) { m_oPen.MiterLimit = val; WriteDouble(ctPenMiterLimit, val); } } // ------------------------------------------------------------------------------------- // brush ------------------------------------------------------------------------------- inline void BrushXML(BSTR bsXml) { NSStructures::CBrush oNewBrush; oNewBrush.FromXmlString(CString(bsXml)); BrushType(oNewBrush.Type); if (m_oBrush.IsOneColor()) { BrushColor1(oNewBrush.Color1); BrushAlpha1(oNewBrush.Alpha1); } else if (m_oBrush.IsTexture()) { BrushTexturePath(oNewBrush.TexturePath); BrushTextureMode(oNewBrush.TextureMode); BrushTextureAlpha(oNewBrush.TextureAlpha); BrushRect(oNewBrush.Rectable, oNewBrush.Rect); if( oNewBrush.Type == c_BrushTypePattern ) { BrushColor1(oNewBrush.Color1); BrushAlpha1(oNewBrush.Alpha1); BrushColor2(oNewBrush.Color2); BrushAlpha2(oNewBrush.Alpha2); } } else if (m_oBrush.IsTwoColor()) { BrushColor1(oNewBrush.Color1); BrushAlpha1(oNewBrush.Alpha1); BrushColor2(oNewBrush.Color2); BrushAlpha2(oNewBrush.Alpha2); BrushLinearAngle( oNewBrush.LinearAngle ); BrushSubColors( oNewBrush.m_arrSubColors ); } } inline void Brush(NSStructures::CBrush* pBrush) { BrushType(pBrush->Type); if (m_oBrush.IsOneColor()) { BrushColor1(pBrush->Color1); BrushAlpha1(pBrush->Alpha1); } else if (m_oBrush.IsTexture()) { BrushTexturePath(pBrush->TexturePath); BrushTextureMode(pBrush->TextureMode); BrushTextureAlpha(pBrush->TextureAlpha); BrushRect(pBrush->Rectable, pBrush->Rect); } else if (m_oBrush.IsTwoColor()) { BrushColor1(pBrush->Color1); BrushAlpha1(pBrush->Alpha1); BrushColor2(pBrush->Color2); BrushAlpha2(pBrush->Alpha2); BrushLinearAngle( pBrush->LinearAngle ); } } inline void BrushXMLAttack(BSTR bsXml) { WriteBSTR(ctBrushXML, bsXml); } inline void BrushType(const LONG& val) { if (m_oBrush.Type != val) { m_oBrush.Type = val; WriteLONG(ctBrushType, val); } } inline void BrushColor1(const LONG& val) { if (m_oBrush.Color1 != val) { m_oBrush.Color1 = val; WriteLONG(ctBrushColor1, val); } } inline void BrushColor2(const LONG& val) { if (m_oBrush.Color2 != val) { m_oBrush.Color2 = val; WriteLONG(ctBrushColor2, val); } } inline void BrushAlpha1(const LONG& val) { if (m_oBrush.Alpha1 != val) { m_oBrush.Alpha1 = val; WriteBYTE(ctBrushAlpha1, (BYTE)val); } } inline void BrushAlpha2(const LONG& val) { if (m_oBrush.Alpha2 != val) { m_oBrush.Alpha2 = val; WriteBYTE(ctBrushAlpha2, (BYTE)val); } } inline void BrushTextureAlpha(const LONG& val) { if (m_oBrush.TextureAlpha != val) { m_oBrush.TextureAlpha = val; WriteBYTE(ctBrushTextureAlpha, (BYTE)val); } } inline void BrushTextureMode(const LONG& val) { if (m_oBrush.TextureMode != val) { m_oBrush.TextureMode = val; WriteLONG(ctBrushTextureMode, val); } } inline void BrushRect(const BOOL& bRectable, const Gdiplus::RectF& oRect) { WriteBYTE(ctBrushRectable, (BYTE)bRectable); if (bRectable) { WriteFloat(oRect.X); WriteFloat(oRect.Y); WriteFloat(oRect.Width); WriteFloat(oRect.Height); } } inline void BrushTexturePath(const CString& strPath) { if (m_oBrush.TexturePath != strPath) { m_oBrush.TexturePath = strPath; BSTR bsPath = strPath.AllocSysString(); WriteBSTR(ctBrushTexturePath, bsPath); SysFreeString(bsPath); } } inline void BrushLinearAngle(const double& val) { if (m_oBrush.LinearAngle != val) { m_oBrush.LinearAngle = val; WriteDouble(ctBrushAngle, val); } } inline void BrushSubColors( const ATL::CSimpleArray& arrSubColors ) { m_oBrush.m_arrSubColors = arrSubColors; int count = arrSubColors.GetSize(); if( count ) { int datasize = (count * 2 + 1) * m_lSizeofLONG + m_lSizeofBYTE; CheckBufferSize(datasize); BYTE* data = m_pBuffer + m_lPosition; m_lPosition += datasize; data[0] = ctBrushSubColors; long* buffer = (long*)(data + 1); buffer[0] = count; for( int i = 0; i < count; i++ ) { buffer[i * 2 + 1] = arrSubColors[i].color; buffer[i * 2 + 2] = arrSubColors[i].position; } } } // ------------------------------------------------------------------------------------- // font -------------------------------------------------------------------------------- inline void FontXML(BSTR bsXml) { NSStructures::CFont oNewFont; oNewFont.FromXmlString(CString(bsXml)); FontName(oNewFont.Name); FontPath(oNewFont.Path); FontSize(oNewFont.Size); FontStyle(oNewFont.GetStyle()); FontStringGID(oNewFont.StringGID); FontCharSpace(oNewFont.CharSpace); } inline void Font(NSStructures::CFont* pNewFont) { FontName(pNewFont->Name); FontPath(pNewFont->Path); FontSize(pNewFont->Size); FontStyle(pNewFont->GetStyle()); FontStringGID(pNewFont->StringGID); } inline void FontXMLAttack(BSTR bsXml) { WriteBSTR(ctFontXML, bsXml); } inline void FontName(CString strName) { if (m_oFont.Name != strName) { m_oFont.Name = strName; WriteBSTR(ctFontName, (BSTR)(strName.GetBuffer())); } } inline void FontPath(CString strName) { if (m_oFont.Path != strName) { m_oFont.Path = strName; WriteBSTR(ctFontPath, (BSTR)(strName.GetBuffer())); } } inline void FontSize(const double& dSize) { if (m_oFont.Size != dSize) { m_oFont.Size = dSize; WriteDouble(ctFontSize, dSize); } } inline void FontStyle(const LONG& lStyle) { if (m_oFont.GetStyle() != lStyle) { m_oFont.SetStyle(lStyle); WriteLONG(ctFontStyle, lStyle); } } inline void FontStringGID(const BOOL& bGID) { if (m_oFont.StringGID != bGID) { m_oFont.StringGID = bGID; WriteBYTE(ctFontGID, (BYTE)bGID); } } inline void FontCharSpace(const double& dSpace) { if (m_oFont.CharSpace != dSpace) { m_oFont.CharSpace = dSpace; WriteDouble(ctFontCharSpace, dSpace); } } // ------------------------------------------------------------------------------------- // shadow ------------------------------------------------------------------------------ inline void ShadowXML(BSTR bsXml) { NSStructures::CShadow oNewShadow; oNewShadow.FromXmlString(CString(bsXml)); ShadowVisible(oNewShadow.Visible); if (m_oShadow.Visible) { ShadowDistanceX(oNewShadow.DistanceX); ShadowDistanceY(oNewShadow.DistanceY); ShadowBlurSize(oNewShadow.BlurSize); ShadowColor(oNewShadow.Color); ShadowAlpha(oNewShadow.Alpha); } } inline void Shadow(NSStructures::CShadow* pNewShadow) { ShadowVisible(pNewShadow->Visible); if (m_oShadow.Visible) { ShadowDistanceX(pNewShadow->DistanceX); ShadowDistanceY(pNewShadow->DistanceY); ShadowBlurSize(pNewShadow->BlurSize); ShadowColor(pNewShadow->Color); ShadowAlpha(pNewShadow->Alpha); } } inline void ShadowXMLAttack(BSTR bsXml) { WriteBSTR(ctShadowXML, bsXml); } inline void ShadowVisible(const BOOL& bVis) { if (m_oShadow.Visible != bVis) { m_oShadow.Visible = bVis; WriteBYTE(ctShadowVisible, (BYTE)bVis); } } inline void ShadowDistanceX(const double& val) { if (m_oShadow.DistanceX != val) { m_oShadow.DistanceX = val; WriteDouble(ctShadowDistanceX, val); } } inline void ShadowDistanceY(const double& val) { if (m_oShadow.DistanceY != val) { m_oShadow.DistanceY = val; WriteDouble(ctShadowDistanceY, val); } } inline void ShadowBlurSize(const double& val) { if (m_oShadow.BlurSize != val) { m_oShadow.BlurSize = val; WriteDouble(ctShadowBlurSize, val); } } inline void ShadowColor(const LONG& val) { if (m_oShadow.Color != val) { m_oShadow.Color = val; WriteLONG(ctShadowColor, val); } } inline void ShadowAlpha(const LONG& val) { if (m_oShadow.Alpha != val) { m_oShadow.Alpha = val; WriteBYTE(ctShadowAlpha, (BYTE)val); } } // ------------------------------------------------------------------------------------- // edge -------------------------------------------------------------------------------- inline void EdgeXML(BSTR bsXml) { NSStructures::CEdgeText oNewEdge; oNewEdge.FromXmlString(CString(bsXml)); EdgeVisible(oNewEdge.Visible); if (0 != m_oEdge.Visible) { EdgeDist(oNewEdge.Dist); EdgeColor(oNewEdge.Color); EdgeAlpha(oNewEdge.Alpha); } } inline void Edge(NSStructures::CEdgeText* pNewEdge) { EdgeVisible(pNewEdge->Visible); if (0 != m_oEdge.Visible) { EdgeDist(pNewEdge->Dist); EdgeColor(pNewEdge->Color); EdgeAlpha(pNewEdge->Alpha); } } inline void EdgeXMLAttack(BSTR bsXml) { WriteBSTR(ctEdgeXML, bsXml); } inline void EdgeVisible(const LONG& val) { if (m_oEdge.Visible != val) { m_oEdge.Visible = val; WriteBYTE(ctEdgeVisible, (BYTE)val); } } inline void EdgeDist(const double& val) { if (m_oEdge.Dist != val) { m_oEdge.Dist = val; WriteDouble(ctEdgeDistance, val); } } inline void EdgeColor(const LONG& val) { if (m_oEdge.Color != val) { m_oEdge.Color = val; WriteLONG(ctEdgeColor, val); } } inline void EdgeAlpha(const LONG& val) { if (m_oEdge.Alpha != val) { m_oEdge.Alpha = val; WriteLONG(ctEdgeAlpha, val); } } // ------------------------------------------------------------------------------------- inline void PathCommandMoveTo(double fX, double fY) { Write(ctPathCommandMoveTo, fX, fY); } inline void PathCommandLineTo(double fX, double fY) { Write(ctPathCommandLineTo, fX, fY); m_oArrowHead.PathCommandLineTo(fX, fY); } inline void PathCommandLinesTo(SAFEARRAY* pPoints) { LONG lCount = pPoints->rgsabound[0].cElements; double* pData = (double*)pPoints->pvData; Write(ctPathCommandLinesTo, lCount, pData); m_oArrowHead.PathCommandLinesTo(pPoints); } inline void PathCommandCurveTo(double fX1, double fY1, double fX2, double fY2, double fX3, double fY3) { Write(ctPathCommandCurveTo, fX1, fY1, fX2, fY2, fX3, fY3); m_oArrowHead.PathCommandCurveTo(fX1, fY1, fX2, fY2, fX3, fY3); } inline void PathCommandCurvesTo(SAFEARRAY* pPoints) { LONG lCount = pPoints->rgsabound[0].cElements; double* pData = (double*)pPoints->pvData; Write(ctPathCommandCurvesTo, lCount, pData); m_oArrowHead.PathCommandCurvesTo(pPoints); } inline void PathCommandArcTo(double fX, double fY, double fWidth, double fHeight, double fStartAngle, double fSweepAngle) { Write(ctPathCommandArcTo, fX, fY, fWidth, fHeight, fStartAngle, fSweepAngle); m_oArrowHead.PathCommandArcTo(fX, fY, fWidth, fHeight, fStartAngle, fSweepAngle); } inline void PathCommandClose() { WriteCommandType(ctPathCommandClose); m_oArrowHead.PathCommandClose(); } inline void PathCommandEnd() { WriteCommandType(ctPathCommandEnd); m_oArrowHead.PathCommandEnd(); } inline void PathCommandStart() { WriteCommandType(ctPathCommandStart); m_oArrowHead.PathCommandStart(); } inline void PathCommandText(BSTR bsText, double fX, double fY, double fWidth, double fHeight, double fBaseOffset) { LONG lLen = __wstrlen(bsText) + 1; if (1 == lLen) return; lLen *= sizeof(wchar_t); size_t lMem = m_lSizeofBYTE + m_lSizeofLONG + 5 * m_lSizeofDouble + lLen; CheckBufferSize(lMem); *(m_pBuffer + m_lPosition) = (BYTE)ctPathCommandText; m_lPosition += m_lSizeofBYTE; *((LONG*)(m_pBuffer + m_lPosition)) = lLen; m_lPosition += m_lSizeofLONG; memcpy(m_pBuffer + m_lPosition, bsText, lLen); m_lPosition += lLen; *((double*)(m_pBuffer + m_lPosition))= fX; m_lPosition += m_lSizeofDouble; *((double*)(m_pBuffer + m_lPosition))= fY; m_lPosition += m_lSizeofDouble; *((double*)(m_pBuffer + m_lPosition))= fWidth; m_lPosition += m_lSizeofDouble; *((double*)(m_pBuffer + m_lPosition))= fHeight; m_lPosition += m_lSizeofDouble; *((double*)(m_pBuffer + m_lPosition))= fBaseOffset; m_lPosition += m_lSizeofDouble; } inline void DrawText(BSTR bsText, double fX, double fY, double fWidth, double fHeight, double fBaseOffset) { LONG lLen = __wstrlen(bsText) + 1; if (1 == lLen) return; lLen *= sizeof(wchar_t); size_t lMem = m_lSizeofBYTE + m_lSizeofLONG + 5 * m_lSizeofDouble + lLen; CheckBufferSize(lMem); *(m_pBuffer + m_lPosition) = (BYTE)ctDrawText; m_lPosition += m_lSizeofBYTE; *((LONG*)(m_pBuffer + m_lPosition)) = lLen; m_lPosition += m_lSizeofLONG; memcpy(m_pBuffer + m_lPosition, bsText, lLen); m_lPosition += lLen; *((double*)(m_pBuffer + m_lPosition))= fX; m_lPosition += m_lSizeofDouble; *((double*)(m_pBuffer + m_lPosition))= fY; m_lPosition += m_lSizeofDouble; *((double*)(m_pBuffer + m_lPosition))= fWidth; m_lPosition += m_lSizeofDouble; *((double*)(m_pBuffer + m_lPosition))= fHeight; m_lPosition += m_lSizeofDouble; *((double*)(m_pBuffer + m_lPosition))= fBaseOffset; m_lPosition += m_lSizeofDouble; } inline void DrawTextEx(BSTR bsText, BSTR bsGid, BSTR bsSource, double fX, double fY, double fWidth, double fHeight, double fBaseOffset, DWORD lFlags, BOOL bIsPath = FALSE) { LONG lLen1 = __wstrlen(bsText); LONG lLen2 = __wstrlen(bsGid); LONG lLen3 = __wstrlen(bsSource); if (0 == (lLen1 + lLen2 + lLen3)) return; LONG lSizeofWCHAR = sizeof(WCHAR); lLen1 = (lLen1 + 1) * lSizeofWCHAR; lLen2 = (lLen2 + 1) * lSizeofWCHAR; lLen3 = (lLen3 + 1) * lSizeofWCHAR; size_t lMem = m_lSizeofBYTE + 3 * m_lSizeofLONG + lLen1 + lLen2 + lLen3 + 5 * m_lSizeofDouble + m_lSizeofLONG; CheckBufferSize(lMem); if (!bIsPath) { *(m_pBuffer + m_lPosition) = (BYTE)ctDrawTextEx; m_lPosition += m_lSizeofBYTE; } else { *(m_pBuffer + m_lPosition) = (BYTE)ctPathCommandTextEx; m_lPosition += m_lSizeofBYTE; } *((LONG*)(m_pBuffer + m_lPosition)) = lLen1; m_lPosition += m_lSizeofLONG; if (1 != lLen1) { memcpy(m_pBuffer + m_lPosition, bsText, lLen1); m_lPosition += lLen1; } *((LONG*)(m_pBuffer + m_lPosition)) = lLen2; m_lPosition += m_lSizeofLONG; if (1 != lLen2) { memcpy(m_pBuffer + m_lPosition, bsGid, lLen2); m_lPosition += lLen2; } *((LONG*)(m_pBuffer + m_lPosition)) = lLen3; m_lPosition += m_lSizeofLONG; if (1 != lLen3) { memcpy(m_pBuffer + m_lPosition, bsSource, lLen3); m_lPosition += lLen3; } *((double*)(m_pBuffer + m_lPosition))= fX; m_lPosition += m_lSizeofDouble; *((double*)(m_pBuffer + m_lPosition))= fY; m_lPosition += m_lSizeofDouble; *((double*)(m_pBuffer + m_lPosition))= fWidth; m_lPosition += m_lSizeofDouble; *((double*)(m_pBuffer + m_lPosition))= fHeight; m_lPosition += m_lSizeofDouble; *((double*)(m_pBuffer + m_lPosition))= fBaseOffset; m_lPosition += m_lSizeofDouble; //*((DWORD*)(m_pBuffer + m_lPosition)) = lFlags; m_lPosition += m_lSizeofLONG; } inline void DrawPath(LONG lType) { WriteLONG(ctDrawPath, lType); if (m_oArrowHead.DrawPath(lType)) { LONG lColor1 = m_oBrush.Color1; LONG lAlpha1 = m_oBrush.Alpha1; LONG lType = m_oBrush.Type; BrushColor1(m_oPen.Color); BrushAlpha1(m_oPen.Alpha); BrushType(Aggplus::BrushTypeSolidColor); double lpredx = m_oArrowHead.m_dX1 - m_oArrowHead.m_dX2; double lpredy = m_oArrowHead.m_dY1 - m_oArrowHead.m_dY2; double length = sqrt(lpredx * lpredx + lpredy * lpredy); lpredx = lpredx / length; lpredy = lpredy / length; double sin30 = 0.5; double cos30 = sqrt(3.0) / 2.0; double lpredxp = cos30 * lpredx - sin30 * lpredy; double lpredyp = sin30 * lpredx + cos30 * lpredy; double lpredxn = cos30 * lpredx + sin30 * lpredy; double lpredyn = - sin30 * lpredx + cos30 * lpredy; //double lengthp = sqrt(lpredxp * lpredxp + lpredyp * lpredyp); //double lengthn = sqrt(lpredxn * lpredxn + lpredyn * lpredyn); lpredxp *= 2.0; lpredyp *= 2.0; lpredxn *= 2.0; lpredyn *= 2.0; WriteCommandType(ctPathCommandEnd); WriteCommandType(ctPathCommandStart); Write(ctPathCommandMoveTo, m_oArrowHead.m_dX2, m_oArrowHead.m_dY2); Write(ctPathCommandLineTo, m_oArrowHead.m_dX2 + lpredxp, m_oArrowHead.m_dY2 + lpredyp); Write(ctPathCommandLineTo, m_oArrowHead.m_dX2 + lpredxn, m_oArrowHead.m_dY2 + lpredyn); WriteCommandType(ctPathCommandClose); WriteLONG(ctDrawPath, 0x100); BrushColor1(lColor1); BrushAlpha1(lAlpha1); BrushType(lType); } } // ------------------------------------------------------------------------------------- inline void DrawImage(IUnknown* punkImage, double fX, double fY, double fWidth, double fHeight) { size_t lMem = m_lSizeofBYTE + m_lSizeofLONG + 4 * m_lSizeofDouble; CheckBufferSize(lMem); *(m_pBuffer + m_lPosition) = (BYTE)ctDrawImage; m_lPosition += m_lSizeofBYTE; *((LONG*)(m_pBuffer + m_lPosition)) = (LONG)m_arImages.GetCount(); m_lPosition += m_lSizeofLONG; *((double*)(m_pBuffer + m_lPosition))= fX; m_lPosition += m_lSizeofDouble; *((double*)(m_pBuffer + m_lPosition))= fY; m_lPosition += m_lSizeofDouble; *((double*)(m_pBuffer + m_lPosition))= fWidth; m_lPosition += m_lSizeofDouble; *((double*)(m_pBuffer + m_lPosition))= fHeight; m_lPosition += m_lSizeofDouble; ADDREFINTERFACE(punkImage); m_arImages.Add(punkImage); } // --------------------------------------------- inline void DrawImageFromFile(BSTR bstrPath, double fX, double fY, double fWidth, double fHeight) { LONG lLen = __wstrlen(bstrPath) + 1; if (1 == lLen) return; lLen *= sizeof(wchar_t); size_t lMem = m_lSizeofBYTE + m_lSizeofLONG + 4 * m_lSizeofDouble + lLen; CheckBufferSize(lMem); *(m_pBuffer + m_lPosition) = (BYTE)ctDrawImageFromFile; m_lPosition += m_lSizeofBYTE; *((LONG*)(m_pBuffer + m_lPosition)) = lLen; m_lPosition += m_lSizeofLONG; memcpy(m_pBuffer + m_lPosition, bstrPath, lLen); m_lPosition += lLen; *((double*)(m_pBuffer + m_lPosition))= fX; m_lPosition += m_lSizeofDouble; *((double*)(m_pBuffer + m_lPosition))= fY; m_lPosition += m_lSizeofDouble; *((double*)(m_pBuffer + m_lPosition))= fWidth; m_lPosition += m_lSizeofDouble; *((double*)(m_pBuffer + m_lPosition))= fHeight; m_lPosition += m_lSizeofDouble; } inline void SetCommandParams(double dAngle, double dLeft, double dTop, double dWidth, double dHeight, DWORD lFlags) { size_t lMem = m_lSizeofBYTE + m_lSizeofLONG + 5 * m_lSizeofDouble; CheckBufferSize(lMem); *(m_pBuffer + m_lPosition) = (BYTE)ctSetParams; m_lPosition += m_lSizeofBYTE; *((double*)(m_pBuffer + m_lPosition))= dAngle; m_lPosition += m_lSizeofDouble; *((double*)(m_pBuffer + m_lPosition))= dLeft; m_lPosition += m_lSizeofDouble; *((double*)(m_pBuffer + m_lPosition))= dTop; m_lPosition += m_lSizeofDouble; *((double*)(m_pBuffer + m_lPosition))= dWidth; m_lPosition += m_lSizeofDouble; *((double*)(m_pBuffer + m_lPosition))= dHeight; m_lPosition += m_lSizeofDouble; *((LONG*)(m_pBuffer + m_lPosition)) = lFlags; m_lPosition += m_lSizeofLONG; } inline void SetTransform(double dA, double dB, double dC, double dD, double dE, double dF) { size_t lMem = m_lSizeofBYTE + 6 * m_lSizeofDouble; CheckBufferSize(lMem); *(m_pBuffer + m_lPosition) = (BYTE)ctSetTransform; m_lPosition += m_lSizeofBYTE; *((double*)(m_pBuffer + m_lPosition))= dA; m_lPosition += m_lSizeofDouble; *((double*)(m_pBuffer + m_lPosition))= dB; m_lPosition += m_lSizeofDouble; *((double*)(m_pBuffer + m_lPosition))= dC; m_lPosition += m_lSizeofDouble; *((double*)(m_pBuffer + m_lPosition))= dD; m_lPosition += m_lSizeofDouble; *((double*)(m_pBuffer + m_lPosition))= dE; m_lPosition += m_lSizeofDouble; *((double*)(m_pBuffer + m_lPosition))= dF; m_lPosition += m_lSizeofDouble; } inline void ResetTransform() { WriteCommandType(ctResetTransform); } inline void WriteClipMode(LONG lMode) { WriteLONG(ctClipMode, lMode); } inline void BeginCommand(DWORD lType) { WriteLONG(ctBeginCommand, (LONG)lType); } inline void EndCommand(DWORD lType) { WriteLONG(ctEndCommand, lType); } inline void InitAdvancedCommands() { } inline void DestroyAdvancedCommands() { } inline void CommandLong(LONG lCommand) { WriteCommandType(ctCommandLong1); WriteLONG(lCommand); } inline void CommandDouble(double dCommand) { WriteCommandType(ctCommandDouble1); WriteDouble(dCommand); } inline void CommandString(BSTR bsCommand) { WriteCommandType(ctCommandString1); WriteBSTR(bsCommand); } inline void CommandLong2(LONG lType, LONG lCommand) { WriteCommandType(ctCommandLong2); WriteLONG(lType); WriteLONG(lCommand); } inline void CommandDouble2(LONG lType, double dCommand) { WriteCommandType(ctCommandDouble2); WriteLONG(lType); WriteDouble(dCommand); } inline void CommandString2(LONG lType, BSTR bsCommand) { WriteCommandType(ctCommandString2); WriteLONG(lType); WriteBSTR(bsCommand); } public: inline LONG ReadLONG() { LONG l = *((LONG*)m_pBufferMem); m_pBufferMem += m_lSizeofLONG; return l; } inline float ReadFloat() { float l = *((float*)m_pBufferMem); m_pBufferMem += m_lSizeofFloat; return l; } inline BYTE ReadByte() { BYTE l = *m_pBufferMem; ++m_pBufferMem; return l; } inline double ReadDouble() { double l = *((double*)m_pBufferMem); m_pBufferMem += m_lSizeofDouble; return l; } inline BSTR ReadBSTR() { LONG l = ReadLONG(); BSTR bs = (BSTR)m_pBufferMem; m_pBufferMem += l; return bs; } inline LONG ReadLONG(BYTE*& pBufferMem) { LONG l = *((LONG*)pBufferMem); pBufferMem += m_lSizeofLONG; return l; } inline float ReadFloat(BYTE*& pBufferMem) { float l = *((float*)pBufferMem); pBufferMem += m_lSizeofFloat; return l; } inline BYTE ReadByte(BYTE*& pBufferMem) { BYTE l = *pBufferMem; ++pBufferMem; return l; } inline double ReadDouble(BYTE*& pBufferMem) { double l = *((double*)pBufferMem); pBufferMem += m_lSizeofDouble; return l; } inline BSTR ReadBSTR(BYTE*& pBufferMem) { LONG l = ReadLONG(pBufferMem); BSTR bs = (BSTR)pBufferMem; pBufferMem += l; return bs; } inline BSTR ReadBSTR2(BYTE*& pBufferMem) { LONG l = ReadLONG(pBufferMem); if (1 == l) { pBufferMem += l; return NULL; } BSTR bs = (BSTR)pBufferMem; pBufferMem += l; return bs; } public: BOOL Draw(IASCRenderer* pRenderer, BOOL* pBreak) { if (NULL == pRenderer) return FALSE; // выставляем размеры страницы pRenderer->put_Width(m_fWidth); pRenderer->put_Height(m_fHeight); // отрисовываем все объекты... m_pBufferMem = m_pBuffer; // здесь старая команда нужна для того, чтобы не посылать подряд хмлки с пеном, брашем... // (например выставился цвет и альфа - а надо послать только один (!!!) раз) CommandType eOldCommand = ctError; CommandType eCurCommand = ctError; volatile BOOL* pCancel = pBreak; HRESULT hRes = S_OK; while (m_lPosition > ((size_t)(m_pBufferMem - m_pBuffer))) { eCurCommand = (CommandType)ReadByte(); switch (eCurCommand) { case ctPenXML: { hRes = pRenderer->SetPen(ReadBSTR()); break; } case ctBrushXML: { hRes = pRenderer->SetBrush(ReadBSTR()); break; } case ctFontXML: { hRes = pRenderer->SetFont(ReadBSTR()); break; } case ctShadowXML: { hRes = pRenderer->SetShadow(ReadBSTR()); break; } case ctEdgeXML: { hRes = pRenderer->SetEdgeText(ReadBSTR()); break; } case ctDrawText: case ctPathCommandText: { BSTR bsText = ReadBSTR(); double fX = ReadDouble(); double fY = ReadDouble(); double fWidth = ReadDouble(); double fHeight = ReadDouble(); double fBaseOffset = ReadDouble(); if (ctDrawText == eCurCommand) { hRes = pRenderer->CommandDrawText(bsText, fX, fY, fWidth, fHeight, fBaseOffset); } else { hRes = pRenderer->PathCommandText(bsText, fX, fY, fWidth, fHeight, fBaseOffset); } break; } case ctPathCommandMoveTo: { double fX = ReadDouble(); double fY = ReadDouble(); hRes = pRenderer->PathCommandMoveTo(fX, fY); break; } case ctPathCommandLineTo: { double fX = ReadDouble(); double fY = ReadDouble(); hRes = pRenderer->PathCommandLineTo(fX, fY); break; } case ctPathCommandLinesTo: { LONG lCount = ReadLONG(); ULONG lFloats = lCount * m_lSizeofDouble; SAFEARRAYBOUND rgsab; rgsab.lLbound = 0; rgsab.cElements = lCount; SAFEARRAY* pArray = SafeArrayCreate(VT_R8, 1, &rgsab); memcpy(pArray->pvData, m_pBufferMem, lFloats); m_pBufferMem += lFloats; hRes = pRenderer->PathCommandLinesTo(pArray); RELEASEARRAY(pArray); break; } case ctPathCommandCurveTo: { double fX1 = ReadDouble(); double fY1 = ReadDouble(); double fX2 = ReadDouble(); double fY2 = ReadDouble(); double fX3 = ReadDouble(); double fY3 = ReadDouble(); hRes = pRenderer->PathCommandCurveTo(fX1, fY1, fX2, fY2, fX3, fY3); break; } case ctPathCommandCurvesTo: { LONG lCount = ReadLONG(); ULONG lFloats = lCount * m_lSizeofDouble; SAFEARRAYBOUND rgsab; rgsab.lLbound = 0; rgsab.cElements = lCount; SAFEARRAY* pArray = SafeArrayCreate(VT_R8, 1, &rgsab); memcpy(pArray->pvData, m_pBufferMem, lFloats); m_pBufferMem += lFloats; hRes = pRenderer->PathCommandCurvesTo(pArray); RELEASEARRAY(pArray); break; } case ctPathCommandArcTo: { double fX1 = ReadDouble(); double fY1 = ReadDouble(); double fX2 = ReadDouble(); double fY2 = ReadDouble(); double fX3 = ReadDouble(); double fY3 = ReadDouble(); hRes = pRenderer->PathCommandArcTo(fX1, fY1, fX2, fY2, fX3, fY3); break; } case ctPathCommandClose: { hRes = pRenderer->PathCommandClose(); break; } case ctPathCommandEnd: { hRes = pRenderer->PathCommandEnd(); break; } case ctDrawPath: { LONG lType = ReadLONG(); hRes = pRenderer->DrawPath(lType); break; } case ctPathCommandStart: { hRes = pRenderer->PathCommandStart(); break; } case ctDrawImage: { LONG lIndex = ReadLONG(); double fX = ReadDouble(); double fY = ReadDouble(); double fWidth = ReadDouble(); double fHeight = ReadDouble(); hRes = pRenderer->DrawImage(m_arImages[lIndex], fX, fY, fWidth, fHeight); break; } case ctDrawImageFromFile: { BSTR bsPath = ReadBSTR(); double fX = ReadDouble(); double fY = ReadDouble(); double fWidth = ReadDouble(); double fHeight = ReadDouble(); pRenderer->DrawImageFromFile(bsPath, fX, fY, fWidth, fHeight); break; } case ctSetParams: { double angle = ReadDouble(); double left = ReadDouble(); double top = ReadDouble(); double width = ReadDouble(); double height = ReadDouble(); LONG flags = ReadLONG(); hRes = pRenderer->SetCommandParams(angle, left, top, width, height, flags); break; } case ctBeginCommand: { LONG lType = ReadLONG(); hRes = pRenderer->BeginCommand(lType); break; } case ctEndCommand: { LONG lType = ReadLONG(); hRes = pRenderer->EndCommand(lType); break; } case ctSetTransform: { double d1 = ReadDouble(); double d2 = ReadDouble(); double d3 = ReadDouble(); double d4 = ReadDouble(); double d5 = ReadDouble(); double d6 = ReadDouble(); pRenderer->SetTransform(d1, d2, d3, d4, d5, d6); break; } case ctResetTransform: { pRenderer->ResetTransform(); break; } case ctClipMode: { LONG lMode = ReadLONG(); pRenderer->put_ClipMode(lMode); break; } default: { // мало ли что тут произошло, уж лучше выйдем return FALSE; } }; if (S_OK != hRes) break; if ((NULL != pCancel) && (TRUE == *pCancel)) { // отрисовщик остановлен break; } } return (S_OK == hRes); } BOOL Draw2(IASCRenderer* pRenderer, BOOL* pBreak) { if (NULL == pRenderer) return FALSE; // выставляем размеры страницы pRenderer->put_Width(m_fWidth); pRenderer->put_Height(m_fHeight); IASCRenderer2* pRenderer2 = NULL; pRenderer->QueryInterface(__uuidof(IASCRenderer2), (void**)&pRenderer2); // отрисовываем все объекты... m_pBufferMem = m_pBuffer; BYTE* pBufferMem = m_pBuffer; CommandType eOldCommand = ctError; CommandType eCurCommand = ctError; volatile BOOL* pCancel = pBreak; HRESULT hRes = S_OK; while (m_lPosition > ((size_t)(pBufferMem - m_pBuffer))) { eCurCommand = (CommandType)ReadByte(pBufferMem); switch (eCurCommand) { case ctPenXML: { pRenderer->SetPen(ReadBSTR(pBufferMem)); break; } case ctPenColor: { pRenderer->put_PenColor(ReadLONG(pBufferMem)); break; } case ctPenAlpha: { pRenderer->put_PenAlpha((LONG)ReadByte(pBufferMem)); break; } case ctPenSize: { pRenderer->put_PenSize(ReadDouble(pBufferMem)); break; } case ctPenDashStyle: { pRenderer->put_PenDashStyle(ReadByte(pBufferMem)); break; } case ctPenLineStartCap: { pRenderer->put_PenLineStartCap(ReadByte(pBufferMem)); break; } case ctPenLineEndCap: { pRenderer->put_PenLineEndCap(ReadByte(pBufferMem)); break; } case ctPenLineJoin: { pRenderer->put_PenLineJoin(ReadByte(pBufferMem)); break; } case ctPenDashPatern: { LONG lCount = ReadLONG(pBufferMem); ULONG lFloats = lCount * m_lSizeofDouble; SAFEARRAYBOUND rgsab; rgsab.lLbound = 0; rgsab.cElements = lCount; SAFEARRAY* pArray = SafeArrayCreate(VT_R8, 1, &rgsab); memcpy(pArray->pvData, pBufferMem, lFloats); pBufferMem += lFloats; hRes = pRenderer->PenDashPattern(pArray); RELEASEARRAY(pArray); break; } case ctPenDashOffset: { pRenderer->put_PenDashOffset(ReadDouble(pBufferMem)); break; } case ctPenAlign: { pRenderer->put_PenAlign(ReadLONG(pBufferMem)); break; } case ctPenMiterLimit: { pRenderer->put_PenMiterLimit(ReadDouble(pBufferMem)); break; } case ctBrushXML: { pRenderer->SetBrush(ReadBSTR(pBufferMem)); break; } case ctBrushType: { pRenderer->put_BrushType(ReadLONG(pBufferMem)); break; } case ctBrushColor1: { pRenderer->put_BrushColor1(ReadLONG(pBufferMem)); break; } case ctBrushColor2: { pRenderer->put_BrushColor2(ReadLONG(pBufferMem)); break; } case ctBrushAlpha1: { pRenderer->put_BrushAlpha1((LONG)ReadByte(pBufferMem)); break; } case ctBrushAlpha2: { pRenderer->put_BrushAlpha2((LONG)ReadByte(pBufferMem)); break; } case ctBrushTexturePath: { pRenderer->put_BrushTexturePath(ReadBSTR(pBufferMem)); break; } case ctBrushTextureAlpha: { pRenderer->put_BrushTextureAlpha((LONG)ReadByte()); break; } case ctBrushTextureMode: { pRenderer->put_BrushTextureMode(ReadLONG(pBufferMem)); break; } case ctBrushRectable: { BOOL bRect = (BOOL)ReadByte(pBufferMem); if (bRect) { pRenderer->BrushRect(bRect, (double)ReadFloat(pBufferMem), (double)ReadFloat(pBufferMem), (double)ReadFloat(pBufferMem), (double)ReadFloat(pBufferMem)); } else { pRenderer->BrushRect(bRect, 0, 0, 0, 0); } break; } case ctBrushAngle: { pRenderer->put_BrushLinearAngle( ReadDouble(pBufferMem)); break; } case ctBrushSubColors: { long* data = (long*)pBufferMem; pBufferMem += (data[0] * 2 + 1) * m_lSizeofLONG; VARIANT var; var.plVal = data; var.vt = VT_BYREF|VT_I4; pRenderer->SetAdditionalParam( _bstr_t(_T("subcolors")), var ); //pRenderer->SetSubColors( data + 1, data[0] ); break; } case ctFontXML: { hRes = pRenderer->SetFont(ReadBSTR(pBufferMem)); break; } case ctFontName: { pRenderer->put_FontName(ReadBSTR(pBufferMem)); break; } case ctFontPath: { pRenderer->put_FontPath(ReadBSTR(pBufferMem)); break; } case ctFontSize: { pRenderer->put_FontSize(ReadDouble(pBufferMem)); break; } case ctFontStyle: { pRenderer->put_FontStyle(ReadLONG(pBufferMem)); break; } case ctFontGID: { pRenderer->put_FontStringGID((BOOL)ReadByte(pBufferMem)); break; } case ctFontCharSpace: { pRenderer->put_FontCharSpace(ReadDouble(pBufferMem)); break; } case ctShadowXML: { hRes = pRenderer->SetShadow(ReadBSTR(pBufferMem)); break; } case ctShadowVisible: { pRenderer->put_ShadowVisible((BOOL)ReadByte(pBufferMem)); break; } case ctShadowDistanceX: { pRenderer->put_ShadowDistanceX(ReadDouble(pBufferMem)); break; } case ctShadowDistanceY: { pRenderer->put_ShadowDistanceY(ReadDouble(pBufferMem)); break; } case ctShadowBlurSize: { pRenderer->put_ShadowBlurSize(ReadDouble(pBufferMem)); break; } case ctShadowColor: { pRenderer->put_ShadowColor(ReadLONG(pBufferMem)); break; } case ctShadowAlpha: { pRenderer->put_ShadowAlpha((LONG)ReadByte(pBufferMem)); break; } case ctEdgeXML: { hRes = pRenderer->SetEdgeText(ReadBSTR(pBufferMem)); break; } case ctEdgeVisible: { pRenderer->put_EdgeVisible(ReadLONG(pBufferMem)); break; } case ctEdgeDistance: { pRenderer->put_EdgeDist(ReadDouble(pBufferMem)); break; } case ctEdgeColor: { pRenderer->put_EdgeColor(ReadLONG(pBufferMem)); break; } case ctEdgeAlpha: { pRenderer->put_EdgeAlpha((LONG)ReadByte(pBufferMem)); break; } case ctDrawText: case ctPathCommandText: { BSTR bsText = ReadBSTR(pBufferMem); double fX = ReadDouble(pBufferMem); double fY = ReadDouble(pBufferMem); double fWidth = ReadDouble(pBufferMem); double fHeight = ReadDouble(pBufferMem); double fBaseOffset = ReadDouble(pBufferMem); if (ctDrawText == eCurCommand) { hRes = pRenderer->CommandDrawText(bsText, fX, fY, fWidth, fHeight, fBaseOffset); } else { hRes = pRenderer->PathCommandText(bsText, fX, fY, fWidth, fHeight, fBaseOffset); } break; } case ctDrawTextEx: case ctPathCommandTextEx: { BSTR bsText = ReadBSTR2(pBufferMem); BSTR bsGid = ReadBSTR2(pBufferMem); BSTR bsSource = ReadBSTR2(pBufferMem); double fX = ReadDouble(pBufferMem); double fY = ReadDouble(pBufferMem); double fWidth = ReadDouble(pBufferMem); double fHeight = ReadDouble(pBufferMem); double fBaseOffset = ReadDouble(pBufferMem); DWORD dwFlags = 0; //DWORD dwFlags = ReadDWORD(pBufferMem); if (ctDrawTextEx == eCurCommand) { hRes = pRenderer->CommandDrawTextEx(bsText, bsGid, bsSource, fX, fY, fWidth, fHeight, fBaseOffset, dwFlags); } else { hRes = pRenderer->PathCommandTextEx(bsText, bsGid, bsSource, fX, fY, fWidth, fHeight, fBaseOffset, dwFlags); } break; } case ctPathCommandMoveTo: { double fX = ReadDouble(pBufferMem); double fY = ReadDouble(pBufferMem); hRes = pRenderer->PathCommandMoveTo(fX, fY); break; } case ctPathCommandLineTo: { double fX = ReadDouble(pBufferMem); double fY = ReadDouble(pBufferMem); hRes = pRenderer->PathCommandLineTo(fX, fY); break; } case ctPathCommandLinesTo: { LONG lCount = ReadLONG(pBufferMem); ULONG lFloats = lCount * m_lSizeofDouble; SAFEARRAYBOUND rgsab; rgsab.lLbound = 0; rgsab.cElements = lCount; SAFEARRAY* pArray = SafeArrayCreate(VT_R8, 1, &rgsab); memcpy(pArray->pvData, pBufferMem, lFloats); pBufferMem += lFloats; hRes = pRenderer->PathCommandLinesTo(pArray); RELEASEARRAY(pArray); break; } case ctPathCommandCurveTo: { double fX1 = ReadDouble(pBufferMem); double fY1 = ReadDouble(pBufferMem); double fX2 = ReadDouble(pBufferMem); double fY2 = ReadDouble(pBufferMem); double fX3 = ReadDouble(pBufferMem); double fY3 = ReadDouble(pBufferMem); hRes = pRenderer->PathCommandCurveTo(fX1, fY1, fX2, fY2, fX3, fY3); break; } case ctPathCommandCurvesTo: { LONG lCount = ReadLONG(pBufferMem); ULONG lFloats = lCount * m_lSizeofDouble; SAFEARRAYBOUND rgsab; rgsab.lLbound = 0; rgsab.cElements = lCount; SAFEARRAY* pArray = SafeArrayCreate(VT_R8, 1, &rgsab); memcpy(pArray->pvData, pBufferMem, lFloats); pBufferMem += lFloats; hRes = pRenderer->PathCommandCurvesTo(pArray); RELEASEARRAY(pArray); break; } case ctPathCommandArcTo: { double fX1 = ReadDouble(pBufferMem); double fY1 = ReadDouble(pBufferMem); double fX2 = ReadDouble(pBufferMem); double fY2 = ReadDouble(pBufferMem); double fX3 = ReadDouble(pBufferMem); double fY3 = ReadDouble(pBufferMem); hRes = pRenderer->PathCommandArcTo(fX1, fY1, fX2, fY2, fX3, fY3); break; } case ctPathCommandClose: { hRes = pRenderer->PathCommandClose(); break; } case ctPathCommandEnd: { hRes = pRenderer->PathCommandEnd(); break; } case ctDrawPath: { LONG lType = ReadLONG(pBufferMem); hRes = pRenderer->DrawPath(lType); break; } case ctPathCommandStart: { hRes = pRenderer->PathCommandStart(); break; } case ctDrawImage: { LONG lIndex = ReadLONG(pBufferMem); double fX = ReadDouble(pBufferMem); double fY = ReadDouble(pBufferMem); double fWidth = ReadDouble(pBufferMem); double fHeight = ReadDouble(pBufferMem); hRes = pRenderer->DrawImage(m_arImages[lIndex], fX, fY, fWidth, fHeight); break; } case ctDrawImageFromFile: { BSTR bsPath = ReadBSTR(pBufferMem); double fX = ReadDouble(pBufferMem); double fY = ReadDouble(pBufferMem); double fWidth = ReadDouble(pBufferMem); double fHeight = ReadDouble(pBufferMem); CImageExt oImage; oImage.DrawOnRenderer(pRenderer, bsPath, fX, fY, fWidth, fHeight, TRUE); //pRenderer->DrawImageFromFile(bsPath, fX, fY, fWidth, fHeight); break; } case ctSetParams: { double angle = ReadDouble(pBufferMem); double left = ReadDouble(pBufferMem); double top = ReadDouble(pBufferMem); double width = ReadDouble(pBufferMem); double height = ReadDouble(pBufferMem); LONG flags = ReadLONG(pBufferMem); hRes = pRenderer->SetCommandParams(angle, left, top, width, height, flags); break; } case ctBeginCommand: { LONG lType = ReadLONG(pBufferMem); hRes = pRenderer->BeginCommand(lType); break; } case ctEndCommand: { LONG lType = ReadLONG(pBufferMem); hRes = pRenderer->EndCommand(lType); break; } case ctSetTransform: { double d1 = ReadDouble(pBufferMem); double d2 = ReadDouble(pBufferMem); double d3 = ReadDouble(pBufferMem); double d4 = ReadDouble(pBufferMem); double d5 = ReadDouble(pBufferMem); double d6 = ReadDouble(pBufferMem); pRenderer->SetTransform(d1, d2, d3, d4, d5, d6); break; } case ctResetTransform: { pRenderer->ResetTransform(); break; } case ctClipMode: { LONG lMode = ReadLONG(pBufferMem); pRenderer->put_ClipMode(lMode); break; } case ctCommandLong1: { LONG lValue = ReadLONG(pBufferMem); if (NULL != pRenderer2) pRenderer2->CommandLong(lValue); break; } case ctCommandDouble1: { double dValue = ReadDouble(pBufferMem); if (NULL != pRenderer2) pRenderer2->CommandDouble(dValue); break; } case ctCommandString1: { BSTR bsVal = ReadBSTR(pBufferMem); if (NULL != pRenderer2) pRenderer2->CommandString(bsVal); break; } case ctCommandLong2: { LONG _Type = ReadLONG(pBufferMem); LONG lValue = ReadLONG(pBufferMem); if (NULL != pRenderer2) pRenderer2->CommandLong2(_Type, lValue); break; } case ctCommandDouble2: { LONG _Type = ReadLONG(pBufferMem); double dValue = ReadDouble(pBufferMem); if (NULL != pRenderer2) pRenderer2->CommandDouble2(_Type, dValue); break; } case ctCommandString2: { LONG _Type = ReadLONG(pBufferMem); BSTR bsVal = ReadBSTR(pBufferMem); if (NULL != pRenderer2) pRenderer2->CommandString2(_Type, bsVal); break; } default: { // мало ли что тут произошло, уж лучше выйдем return FALSE; } }; if (S_OK != hRes) break; if ((NULL != pCancel) && (TRUE == *pCancel)) { // отрисовщик остановлен break; } } //if (NULL != m_pAdditionalCommands) //{ // m_pAdditionalCommands->Draw2(pRenderer, -1, -1, pBreak); //} return (S_OK == hRes); } };