Files
core/ASCImageStudio3/ASCGraphics/Objects/ASCImage.h

479 lines
11 KiB
C++

// CAVSBrush.h : Declaration of the CAVSPen
#pragma once
#include "..\stdafx.h"
#include "..\resource.h" // main symbols
#include "Registration.h"
#include "Image\Wmf\WmfFile.h"
#include "Image\Wmf\RendererOutput.h"
#include "..\Interfaces\IAVSImage.h"
#include "..\Interfaces\AVSRenderer.h"
#include "GdiplusEx.h"
#include "Image\EmfFile.h"
#include "Image\SVG\SVGTransformer.h"
const long c_lImageTypeUnknown = 0x0000;
const long c_lImageTypeMetafile = 0x1000;
const long c_lImageTypeBitmap = 0x2000;
const long c_lMetaWmf = 0x01;
const long c_lMetaEmf = 0x02;
const long c_lMetaSVG = 0x04;
// CAVSImage
[coclass, uuid("196FFB80-B601-453d-B757-00EFDC60676C"), threading(apartment), vi_progid("AVSGraphics.Pen"), progid("AVSGraphics.Pen"), version(1.0), support_error_info(IAVSImage), registration_script("control.rgs")]
class ATL_NO_VTABLE CAVSImage
: public IAVSImage
{
protected:
private:
CWmfFile m_oWmfFile;
CEMFFile m_oEmfFile;
ISVGTransformer* m_pSVGFile;
TWmfRectF m_oRect;
CStringW m_wsTempFilePath;
long m_lImageType; // 0 - BMP, 1 - WMF, 2 - EFM
double m_dDpiX;
double m_dDpiY;
IUnknown* m_pMediaData;
BOOL m_bLoadOnlyMeta; // Çàãðóæàåì òîëüêî ìåòàôàéë
public:
CAVSImage()
{
m_pMediaData = NULL;
m_pSVGFile = NULL;
}
DECLARE_PROTECT_FINAL_CONSTRUCT()
HRESULT FinalConstruct()
{
m_bLoadOnlyMeta = FALSE;
m_lImageType = c_lImageTypeUnknown;
m_dDpiX = 72;
m_dDpiY = 72;
m_wsTempFilePath.Empty();
m_pMediaData = NULL;
m_pSVGFile = NULL;
return S_OK;
}
void FinalRelease()
{
Close();
}
private:
void Open(BSTR bsFilePath)
{
// Çàêðîåì ðàííåå îòêðûòûé ôàéë (åñëè îí áûë îòêðûò)
Close();
// Ñíà÷àëà ïîïûòàåìÿ îòêðûòü ôàéë êàê WMF
m_oWmfFile.OpenFromFile( bsFilePath );
m_oWmfFile.Scan( &m_oRect );
// Ôàéë îòêðûëñÿ íîðìàëüíî
if ( !m_oWmfFile.CheckError() )
{
m_lImageType = c_lImageTypeMetafile | c_lMetaWmf;
return;
}
// Ýòî íå Wmf, ïîïðîáóåì îòêðûòü åãî êàê Emf
m_oWmfFile.Close();
Gdiplus::Metafile *pMetaFile = new Gdiplus::Metafile( bsFilePath );
if ( NULL != pMetaFile )
{
// Ïîõîæå ýòî ìåòàôàéë, êîíâåðòèðóåì åãî â Wmf ñ ïîìîùüþ Gdi
HENHMETAFILE hEmf = pMetaFile->GetHENHMETAFILE();
if ( NULL != hEmf )
{
UINT unSize = Gdiplus::Metafile::EmfToWmfBits( hEmf, 0, NULL, MM_ANISOTROPIC, Gdiplus::EmfToWmfBitsFlagsEmbedEmf);
BYTE *pBuffer = new BYTE[unSize];
INT nConvertedSize = Gdiplus::Metafile::EmfToWmfBits( hEmf, unSize, pBuffer, MM_ANISOTROPIC, Gdiplus::EmfToWmfBitsFlagsEmbedEmf );
HMETAFILE hWmf = SetMetaFileBitsEx( unSize, pBuffer );
FILE *pFile = NULL;
WmfOpenTempFile( &m_wsTempFilePath, &pFile, _T("wb+"), _T(".wmf"), NULL );
if ( !pFile )
{
DeleteMetaFile( hWmf );
DeleteEnhMetaFile( hEmf );
delete[] pBuffer;
delete pMetaFile;
m_lImageType = c_lImageTypeUnknown;
return;
}
::fclose( pFile );
// Ñîõðàíÿåì Wmf
HMETAFILE hTempWmf = CopyMetaFile( hWmf, m_wsTempFilePath.GetBuffer() );
DeleteMetaFile( hTempWmf );
// Îòêðûâàåì Wmf
m_oWmfFile.OpenFromFile( m_wsTempFilePath.GetBuffer() );
m_oWmfFile.Scan( &m_oRect );
if ( !m_oWmfFile.CheckError() )
{
// Wmf íîðìàëüíî îòêðûëñÿ
m_lImageType = c_lImageTypeMetafile | c_lMetaEmf;
DeleteMetaFile( hWmf );
DeleteEnhMetaFile( hEmf );
delete[] pBuffer;
delete pMetaFile;
return;
}
else if ( m_oWmfFile.UnSupportedWmf() )
{
// Èñõîäíûé ôàéë Emf, íî ïîñëå êîíâåðòàöèè â Wmf îí íå îòêðûëñÿ
m_lImageType = c_lImageTypeMetafile | c_lMetaEmf;
}
else
{
// Ñêîíâåðòèðîâàííûé ôàéë íå ïðî÷èòàëñÿ
m_oWmfFile.Close();
m_lImageType = c_lImageTypeUnknown;
}
DeleteMetaFile( hWmf );
DeleteEnhMetaFile( hEmf );
delete[] pBuffer;
delete pMetaFile;
}
}
if ( (c_lImageTypeMetafile | c_lMetaEmf) == m_lImageType )
{
m_oEmfFile.Open(bsFilePath);
}
else // if ( c_lImageTypeUnknown == m_lImageType )
{
// ïîïðîáóåì çà÷èòàòü SVG
CoCreateInstance( __uuidof(SVGTransformer), NULL, CLSCTX_ALL, __uuidof(ISVGTransformer), (void**)(&m_pSVGFile) );
if (NULL != m_pSVGFile)
{
if ( AVS_ERROR_FILEFORMAT == m_pSVGFile->LoadFile( bsFilePath ) )
{
RELEASEINTERFACE( m_pSVGFile );
}
else
{
m_lImageType = c_lImageTypeMetafile | c_lMetaSVG;
return;
}
}
if ( m_bLoadOnlyMeta )
return;
// Èñõîäíûé ôàéë íå ÿâëåòñÿ ìåòàôàéëîì (Wmf/Emf)
// TODO: Ñäåëàòü ÷òåíèå Bitmap
ImageStudio::IImageTransforms* pTransforms = NULL;
CoCreateInstance(ImageStudio::CLSID_ImageTransforms, NULL, CLSCTX_INPROC, ImageStudio::IID_IImageTransforms, (void**)&pTransforms);
if (NULL == pTransforms)
return;
CStringW strXml = L"<ImageFile-LoadImage sourcepath='";
strXml += CStringW(bsFilePath);
strXml += L"'/>";
VARIANT_BOOL vbRes = VARIANT_FALSE;
BSTR bsXml = strXml.AllocSysString();
pTransforms->SetXml(bsXml, &vbRes);
if (VARIANT_TRUE == vbRes)
{
pTransforms->Transform(&vbRes);
}
if (VARIANT_TRUE == vbRes)
{
VARIANT var;
pTransforms->GetResult(0, &var);
m_pMediaData = var.punkVal;
var.punkVal = NULL;
}
RELEASEINTERFACE(pTransforms);
m_lImageType = c_lImageTypeBitmap;
}
return;
}
void Close()
{
if ( m_lImageType & c_lImageTypeMetafile )
{
m_oWmfFile.Close();
if ( m_lImageType & c_lMetaEmf )
{
// Óäàëÿåì âðåìåííûé ôàéë
::_wunlink( m_wsTempFilePath.GetBuffer() );
}
}
RELEASEINTERFACE(m_pSVGFile);
m_lImageType = c_lImageTypeUnknown;
m_wsTempFilePath = _T("");
RELEASEINTERFACE(m_pMediaData);
}
public:
//-------------------------------------------------------------------------------------------
// IAVSImage
//-------------------------------------------------------------------------------------------
STDMETHOD(get_Type)(LONG* lType)
{
if (NULL != lType)
*lType = m_lImageType;
return S_OK;
}
STDMETHOD(get_Width)(LONG* lWidth)
{
if ( NULL != lWidth )
{
if ( (c_lImageTypeMetafile | c_lMetaWmf) == m_lImageType || (c_lImageTypeMetafile | c_lMetaEmf) == m_lImageType )
{
float fWidth, fHeight;
m_oWmfFile.GetSize( &fWidth, &fHeight );
*lWidth = (LONG)fWidth;
}
else if (((c_lImageTypeMetafile | c_lMetaSVG) == m_lImageType) && (NULL != m_pSVGFile))
{
m_pSVGFile->get_Width(lWidth);
}
else
{
*lWidth = 0;
}
}
return S_OK;
}
STDMETHOD(put_Width)(LONG lWidth)
{
return S_OK;
}
STDMETHOD(get_Height)(LONG* lHeight)
{
if ( NULL != lHeight )
{
if ( (c_lImageTypeMetafile | c_lMetaWmf) == m_lImageType || (c_lImageTypeMetafile | c_lMetaEmf) == m_lImageType )
{
float fWidth, fHeight;
m_oWmfFile.GetSize( &fWidth, &fHeight );
*lHeight = (LONG)fHeight;
}
else if (((c_lImageTypeMetafile | c_lMetaSVG) == m_lImageType) && (NULL != m_pSVGFile))
{
m_pSVGFile->get_Height(lHeight);
}
else
{
*lHeight = 0;
}
}
return S_OK;
}
STDMETHOD(put_Height)(LONG lHeight)
{
return S_OK;
}
STDMETHOD(get_DpiX)(double* dDpiX)
{
*dDpiX = m_dDpiX;
return S_OK;
}
STDMETHOD(put_DpiX)(double dDpiX)
{
m_dDpiX = dDpiX;
return S_OK;
}
STDMETHOD(get_DpiY)(double* dDpiY)
{
*dDpiY = m_dDpiY;
return S_OK;
}
STDMETHOD(put_DpiY)(double dDpiY)
{
m_dDpiY = dDpiY;
return S_OK;
}
STDMETHOD(Draw)(IAVSGraphicsBase* pGraphics)
{
return S_OK;
}
STDMETHOD(LoadFromFile)(BSTR bsFilePath)
{
// Âíóòðè êîììàíäû Open âûïîëíÿåòñÿ êîìàíäà Close
Open( bsFilePath );
return S_OK;
}
STDMETHOD(DrawOnRenderer)(IAVSRenderer* pRenderer, double dX, double dY, double dWidth, double dHeight)
{
if (NULL == pRenderer)
return S_FALSE;
pRenderer->BeginCommand(c_nImageType);
if ( (c_lImageTypeMetafile | c_lMetaWmf) == m_lImageType || (c_lImageTypeMetafile | c_lMetaEmf) == m_lImageType )
{
pRenderer->get_DpiX(&m_dDpiX);
pRenderer->get_DpiY(&m_dDpiY);
CRendererOutput oWmfOut( &m_oWmfFile, pRenderer, dX, dY, dWidth, dHeight );
double fSrcWidth, fSrcHeight;
float fW, fH;
m_oWmfFile.GetSize( &fW, &fH );
m_oWmfFile.GetDisplaySize( &fSrcWidth, &fSrcHeight,m_dDpiX, m_dDpiY );
//m_oWmfFile.GetDisplaySize( &fSrcWidth, &fSrcHeight, 25.4, 25.4 );
TWmfRectF oRectB = m_oWmfFile.GetBounds( );
//double dW = m_oRect.oBR.fX - m_oRect.oTL.fX;
//double dH = m_oRect.oBR.fY - m_oRect.oTL.fY;
double dW = oRectB.oBR.fX - oRectB.oTL.fX;
double dH = oRectB.oBR.fY - oRectB.oTL.fY;
double dScaleX = dWidth / dW;//fSrcWidth;
double dScaleY = dHeight / dH;//fSrcHeight;
//double dScaleX = dWidth / fSrcWidth;
//double dScaleY = dHeight / fSrcHeight;
double dSrcDpiX, dSrcDpiY;
m_oWmfFile.GetDpi( &dSrcDpiX, &dSrcDpiY );
double dDpiKoefX = m_dDpiX / dSrcDpiX;
double dDpiKoefY = m_dDpiY / dSrcDpiY;
double dDpi = dSrcDpiY * fSrcHeight / fH;
oWmfOut.SetDpi( m_dDpiX, dDpi );
oWmfOut.SetWmfRect( oRectB );
oWmfOut.SetScales( dScaleX, dScaleY );
m_oWmfFile.SetOutputDevice( &oWmfOut );
TWmfRectF oRect;
m_oWmfFile.Play( &oRect );
}
else if ( (c_lImageTypeMetafile | c_lMetaEmf) == m_lImageType )
{
m_oEmfFile.DrawOnRenderer(pRenderer, dX, dY, dWidth, dHeight);
}
else if ( (c_lImageTypeMetafile | c_lMetaSVG) == m_lImageType )
{
if (NULL != m_pSVGFile)
{
m_pSVGFile->Draw(pRenderer, dX, dY, dWidth, dHeight);
}
}
else if ( m_lImageType & c_lImageTypeBitmap )
{
pRenderer->DrawImage(m_pMediaData, dX, dY, dWidth, dHeight);
}
pRenderer->EndCommand(c_nImageType);
return S_OK;
}
//-------------------------------------------------------------------------------------------
// IAVSGraphicsBase
//-------------------------------------------------------------------------------------------
STDMETHOD(SetAdditionalParam)(BSTR ParamName, VARIANT ParamValue)
{
CString sParamName = ParamName;
if ( _T("LoadOnlyMeta") == sParamName && VT_BOOL == ParamValue.vt )
{
m_bLoadOnlyMeta = ( ParamValue.boolVal == -1 ? TRUE : FALSE );
}
if ( _T("LoadSVG") == sParamName && VT_BSTR == ParamValue.vt )
{
Close();
CoCreateInstance( __uuidof(SVGTransformer), NULL, CLSCTX_ALL, __uuidof(ISVGTransformer), (void**)(&m_pSVGFile) );
if (NULL != m_pSVGFile)
{
if ( AVS_ERROR_FILEFORMAT == m_pSVGFile->Load( ParamValue.bstrVal ) )
{
RELEASEINTERFACE( m_pSVGFile );
return S_FALSE;
}
else
{
m_lImageType = c_lImageTypeMetafile | c_lMetaSVG;
}
}
}
return S_OK;
}
STDMETHOD(GetAdditionalParam)(BSTR ParamName, VARIANT* ParamValue)
{
return S_OK;
}
STDMETHOD(CreateDublicate)(IAVSGraphicsBase** ppGraphicsBase)
{
return S_OK;
}
STDMETHOD(get_FontManager)(IAVSFontManager** ppManager)
{
if (NULL == ppManager)
return S_FALSE;
*ppManager = m_oWmfFile.GetFontManager();
ADDREFINTERFACE((*ppManager));
return S_OK;
}
STDMETHOD(put_FontManager)(IAVSFontManager* pManager)
{
m_oWmfFile.SetFontManager(pManager);
m_oEmfFile.SetFontManager(pManager);
return S_OK;
}
};