#pragma once #include "../ap_AggPlusEnums.h" #include "../ap_AggPlusTypes.h" #include "../svg/agg_svg_exception.h" #include "../svg/agg_svg_parser.h" #include "../svg/agg_svg_indexation_interpreter.h" #include "../svg/agg_svg_rendering_interpreter.h" #include "../svg/agg_svg_attributes_map.h" #include "../svg/agg_svg_rasterizer.h" //#include "../X__CacheFile.h" #include "../ap_Mem.h" #include "../../stdafx.h" namespace Aggplus { class CImage { public: friend class CGraphics; friend class CBrushTexture; public: CImage() : m_dwWidth(0), m_dwHeight(0), m_nStride(0), m_pImgData(NULL), m_bExternalBuffer(false), m_Status(WrongState), m_pFrame(NULL) { } CImage(const WCHAR *filename) : m_dwWidth(0), m_dwHeight(0), m_nStride(0), m_pImgData(NULL), m_bExternalBuffer(false), m_pFrame(NULL) { //Create(filename); CreateFromImageStudio(filename); } virtual ~CImage() { Destroy(); } inline DWORD GetWidth() const { return(m_dwWidth); } inline DWORD GetHeight() const { return(m_dwHeight); } inline Status GetLastStatus() const { return(m_Status); } public: Status m_Status; DWORD m_dwWidth; DWORD m_dwHeight; long m_nStride; BYTE* m_pImgData; bool m_bExternalBuffer; public: MediaCore::IAVSUncompressedVideoFrame* m_pFrame; CImage* Clone() const { CImage* pRet = new CImage(); pRet->CopyFrom(this); return pRet; } void Create(const WCHAR *filename); void CreateFromImageStudio(const WCHAR* filename); void CopyFrom(const CImage *pSource); void Destroy(); }; //--------------------------------------------------------------------------- // Information about image pixel data //--------------------------------------------------------------------------- class CBitmapData { public: UINT Width; UINT Height; LONG Stride; PixelFormat PixelFormat; void* Scan0; UINT_PTR Reserved; }; class CBitmap : public CImage { public: CBitmap(LONG width, LONG height, PixelFormat format = PixelFormat32bppARGB) : CImage() { assert(format == PixelFormat32bppARGB); if(width <= 0 || height <= 0) { m_Status=InvalidParameter; return; } LONG lSize = 4 * width * height; m_pImgData = (BYTE*)ap_malloc16(lSize); assert(m_pImgData); if (m_pImgData) { memset(m_pImgData, 0, lSize); m_dwWidth = width; m_dwHeight = height; m_nStride = 4 * m_dwWidth; m_Status = Ok; } } CBitmap(LONG width, LONG height, LONG stride, PixelFormat format, BYTE* scan0) : CImage() { assert(format == PixelFormat32bppARGB); assert(scan0); //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(HBITMAP hbm, HPALETTE hpal) : CImage() { Create(hbm, hpal); } CBitmap(HINSTANCE hInstance, const WCHAR* bitmapName) : CImage() { HBITMAP hBMRes = ::LoadBitmapW(hInstance, bitmapName); if (hBMRes) { Create(hBMRes, NULL); ::DeleteObject(hBMRes); } } CBitmap(const WCHAR *filename) : CImage(filename) { } ~CBitmap() { } static inline CBitmap* FromHBITMAP(HBITMAP hbm, HPALETTE hpal) { return new CBitmap(hbm, hpal); } void LockBits(const RectF* rect, PixelFormat format, CBitmapData* lockedBitmapData) { // надо реализовать return; } protected: CBitmap() : CImage(NULL) { assert(FALSE); } void Create(HBITMAP hbm, HPALETTE hpal) { Destroy(); BITMAPINFO bi; bool b32bitImg = false; //Step 1 memset(&bi, 0, sizeof(BITMAPINFO)); bi.bmiHeader.biSize=sizeof(BITMAPINFOHEADER); HDC hdc=::GetDC(NULL); int nChk=GetDIBits(hdc, // handle to device context hbm, // handle to bitmap 0, // first scan line to set in destination bitmap 1, // number of scan lines to copy NULL, // address of array for bitmap bits &bi, // address of structure with bitmap data DIB_RGB_COLORS // RGB or palette index ); if (!nChk || bi.bmiHeader.biWidth <= 0 || bi.bmiHeader.biHeight <=0 ) return; if(bi.bmiHeader.biBitCount == 32 && bi.bmiHeader.biCompression == BI_RGB) b32bitImg = true; //Step 2 m_dwWidth = bi.bmiHeader.biWidth; m_dwHeight = bi.bmiHeader.biHeight; m_bExternalBuffer = false; m_pImgData = (BYTE*)ap_malloc16(4 * m_dwWidth * m_dwHeight); memset(&bi, 0, sizeof(BITMAPINFO)); bi.bmiHeader.biSize=sizeof(BITMAPINFOHEADER); bi.bmiHeader.biWidth = m_dwWidth; // fill in width from parameter bi.bmiHeader.biHeight = -int(m_dwHeight); // fill in height from parameter bi.bmiHeader.biPlanes = 1; // must be 1 bi.bmiHeader.biBitCount = 32; // from parameter bi.bmiHeader.biCompression = BI_RGB; bi.bmiHeader.biSizeImage = m_dwWidth * m_dwHeight * 4; //bi.bmiHeader.biXPelsPerMeter = 0; //bi.bmiHeader.biYPelsPerMeter = 0; //bi.bmiHeader.biClrUsed = 0; //bi.bmiHeader.biClrImportant = 0; nChk=GetDIBits(hdc, // handle to device context hbm, // handle to bitmap 0, // first scan line to set in destination bitmap m_dwHeight, // number of scan lines to copy m_pImgData, // address of array for bitmap bits &bi, // address of structure with bitmap data DIB_RGB_COLORS // RGB or palette index ); //Opaque Alpha! if(!b32bitImg) { DWORD dwSize = m_dwWidth * m_dwHeight; DWORD* pData = (DWORD*)m_pImgData; for (DWORD i = 0; i < dwSize; i++) { pData[i] |= 0xFF000000; } } m_Status=Ok; ::ReleaseDC(NULL, hdc); } }; class CSVGImage { friend class CGraphics; agg::svg::dom_storage m_storage; agg::svg::dom_storage::map_type m_id2elem_map; agg::svg::global_settings m_settings; agg::svg::attributes m_attributes; agg::svg::attributes_map m_attr_map; agg::svg::pipeline m_pipeline; agg::svg::gradient_lut_cache m_gradient_lut_cache; void indexation() { agg::svg::indexation_interpreter consumer(m_id2elem_map); m_storage.traverse(consumer); m_id2elem_map.sort_state(agg::svg::on); } void reset() { m_id2elem_map.clear(); m_attributes.clear(); } public: CSVGImage() : m_attributes(m_settings) { } ~CSVGImage() { Clear(); } void Clear() { m_storage.clear(); reset(); } bool Open(const WCHAR *filename) { if(!filename) return false; m_attributes.initial_zoom(); m_storage.clear(); reset(); agg::svg::parser p(m_storage, m_attr_map); p.parse(filename); indexation(); return true; } }; }