注:本文使用的是云信duilib
1 绘图功能基本接口 抽象类
不负责具体实现功能,而是定义绘图时,应该具有的功能,由纯虚函数定义
在duilib中,将与绘制相关的功能,定义成了抽象类纯虚函数接口,定义了绘图使用的渲染上下文环境
在IRender.h中,定义了各种接口 抽象类
其中,最重要的就是IRenderContext ,渲染上下文接口类,此抽象类中定义了绘图所应该有的常用功能
class UILIB_API IRenderContext : public nbase::SupportWeakCallback
{
public:
virtual HDC GetDC() = 0;
virtual bool Resize(int width, int height, bool flipBItmap = true) = 0;
virtual void Clear() = 0;
virtual std::unique_ptr<IRenderContext> Clone() = 0;
virtual HBITMAP DetachBitmap() = 0;
virtual BYTE* GetBits() = 0;
virtual int GetWidth() = 0;
virtual int GetHeight() = 0;
virtual void ClearAlpha(const UiRect& rcDirty, int alpha = 0) = 0;
virtual void RestoreAlpha(const UiRect& rcDirty, const UiRect& rcShadowPadding = UiRect(), int alpha = 0) = 0;
virtual bool IsRenderTransparent() const = 0;
virtual bool SetRenderTransparent(bool bTransparent) = 0;
virtual void Save() = 0;
virtual void Restore() = 0;
virtual CPoint OffsetWindowOrg(CPoint ptOffset) = 0;
virtual CPoint SetWindowOrg(CPoint ptOffset) = 0;
virtual CPoint GetWindowOrg() const = 0;
virtual void SetClip(const UiRect& rc) = 0;
virtual void SetRoundClip(const UiRect& rcItem, int width, int height) = 0;
virtual void ClearClip() = 0;
virtual HRESULT BitBlt(int x, int y, int cx, int cy, HDC hdcSrc, int xSrc = 0, int yScr = 0, DWORD rop = SRCCOPY) = 0;
virtual bool AlphaBlend(int xDest, int yDest, int widthDest, int heightDest, HDC hdcSrc, int xSrc, int yScr, int widthSrc, int heightSrc, BYTE uFade = 255) = 0;
virtual void DrawImage(const UiRect& rcPaint, HBITMAP hBitmap, bool bAlphaChannel,
const UiRect& rcImageDest, const UiRect& rcImageSource, const UiRect& rcCorners, BYTE uFade = 255, bool xtiled = false, bool ytiled = false) = 0;
virtual void DrawColor(const UiRect& rc, DWORD dwColor, BYTE uFade = 255) = 0;
virtual void DrawColor(const UiRect& rc, const std::wstring& colorStr, BYTE uFade = 255) = 0;
virtual void DrawLine(const UiRect& rc, int nSize, DWORD dwPenColor) = 0;
virtual void DrawLine(const IPen* pen, int x1, int y1, int x2, int y2) = 0;
virtual void DrawBezier(const IPen* pen, int x1, int y1, int x2, int y2, int x3, int y3, int x4, int y4) = 0;
virtual void DrawRect(const UiRect& rc, int nSize, DWORD dwPenColor) = 0;
virtual void DrawText(const UiRect& rc, const std::wstring& strText, DWORD dwTextColor, int iFont, UINT uStyle, BYTE uFade = 255, bool bLineLimit = false) = 0;
virtual void DrawEllipse(const UiRect& rc, int nSize, DWORD dwColor) = 0;
virtual void FillEllipse(const UiRect& rc, DWORD dwColor) = 0;
virtual UiRect MeasureText(const std::wstring& strText, int iFont, UINT uStyle, int width = DUI_NOSET_VALUE) = 0;
virtual void DrawPath(const IPath* path, const IPen* pen) = 0;
virtual void FillPath(const IPath* path, const IBrush* brush) = 0;
};
类似的还有 IPen IBrush IBitmap IMatrix等
class UILIB_API IPen : public nbase::SupportWeakCallback
{
public:
IPen(DWORD color, int width = 1) : color_(color) {};
IPen(const IPen& r) : color_(r.color_) {};
IPen& operator=(const IPen& r) = delete;
virtual IPen* Clone() = 0;
virtual void SetWidth(int width) = 0;
virtual int GetWidth() = 0;
virtual void SetColor(DWORD color) = 0;
virtual DWORD GetColor() { return color_; };
enum LineCap
{
LineCapFlat = 0,
LineCapSquare = 1,
LineCapRound = 2,
LineCapTriangle = 3
};
virtual void SetStartCap(LineCap cap) = 0;
virtual void SetEndCap(LineCap cap) = 0;
virtual void SetDashCap(LineCap cap) = 0;
virtual LineCap GetStartCap() = 0;
virtual LineCap GetEndCap() = 0;
virtual LineCap GetDashCap() = 0;
enum LineJoin
{
LineJoinMiter = 0,
LineJoinBevel = 1,
LineJoinRound = 2,
LineJoinMiterClipped = 3
};
virtual void SetLineJoin(LineJoin join) = 0;
virtual LineJoin GetLineJoin() = 0;
enum DashStyle
{
DashStyleSolid, // 0
DashStyleDash, // 1
DashStyleDot, // 2
DashStyleDashDot, // 3
DashStyleDashDotDot, // 4
DashStyleCustom // 5
};
virtual void SetDashStyle(DashStyle style) = 0;
virtual DashStyle GetDashStyle() = 0;
protected:
DWORD color_ = 0;
};
class UILIB_API IBrush : public nbase::SupportWeakCallback
{
public:
IBrush(DWORD color) : color_(color){};
IBrush(HBITMAP bitmap) {};
IBrush(const IBrush& r) : color_(r.color_) {};
IBrush& operator=(const IBrush& r) = delete;
virtual IBrush* Clone() = 0;
virtual DWORD GetColor() { return color_; };
virtual IBitmap* GetBitmap() { return bitmap_.get(); };
protected:
DWORD color_ = 0;
std::unique_ptr<IBitmap> bitmap_;
};
class UILIB_API IBitmap : public nbase::SupportWeakCallback
{
virtual bool Init(HDC hSrcDC, int width, int height, bool flipBItmap) = 0;
virtual void Clear() = 0;
virtual HBITMAP DetachBitmap() = 0;
virtual HBITMAP GetBitmap() = 0;
virtual BYTE* GetBits() = 0;
virtual int GetWidth() = 0;
virtual int GetHeight() = 0;
virtual void ClearAlpha(const UiRect& rcDirty, int alpha) = 0;
virtual void RestoreAlpha(const UiRect& rcDirty, const UiRect& rcShadowPadding, int alpha) = 0;
};
class UILIB_API IMatrix : public nbase::SupportWeakCallback
{
public:
virtual void Translate(int offsetX, int offsetY) = 0;
virtual void Scale(int scaleX, int scaleY) = 0;
virtual void Rotate(float angle) = 0;
virtual void RotateAt(float angle, const CPoint& center) = 0;
};
2 使用工厂模式, 定义抽象工厂类,来生产创建各种具体的绘图实例
class UILIB_API IRenderFactory
{
public:
virtual ui::IPen* CreatePen(DWORD color, int width = 1) = 0;
virtual ui::IBrush* CreateBrush(DWORD corlor) = 0;
virtual ui::IBrush* CreateBrush(HBITMAP bitmap) = 0;
virtual ui::IMatrix* CreateMatrix() = 0;
virtual ui::IPath* CreatePath() = 0;
virtual ui::IBitmap* CreateBitmap() = 0;
virtual ui::IRenderContext* CreateRenderContext() = 0;
};
3 负责具体绘制功能的子类 使用gdiplus进行渲染的 实现抽象类定义的各种功能
比如:
class UILIB_API RenderContext_GdiPlus : public IRenderContext
{
public:
RenderContext_GdiPlus();
virtual ~RenderContext_GdiPlus();
virtual HDC GetDC() override;
virtual bool Resize(int width, int height, bool flipBItmap = true) override;
virtual void Clear() override;
virtual std::unique_ptr<IRenderContext> Clone() override;
virtual HBITMAP DetachBitmap() override;
virtual BYTE* GetBits() override;
virtual int GetWidth() override;
virtual int GetHeight() override;
virtual void ClearAlpha(const UiRect& rcDirty, int alpha = 0) override;
virtual void RestoreAlpha(const UiRect& rcDirty, const UiRect& rcShadowPadding = UiRect(), int alpha = 0) override;
virtual bool IsRenderTransparent() const override;
virtual bool SetRenderTransparent(bool bTransparent) override;
virtual void Save() override;
virtual void Restore() override;
virtual CPoint OffsetWindowOrg(CPoint ptOffset) override;
virtual CPoint SetWindowOrg(CPoint ptOffset) override;
virtual CPoint GetWindowOrg() const override;
virtual void SetClip(const UiRect& rc) override;
virtual void SetRoundClip(const UiRect& rc, int width, int height) override;
virtual void ClearClip() override;
virtual HRESULT BitBlt(int x, int y, int cx, int cy, HDC hdcSrc, int xSrc = 0, int yScr = 0, DWORD rop = SRCCOPY) override;
virtual bool AlphaBlend(int xDest, int yDest, int widthDest, int heightDest, HDC hdcSrc, int xSrc, int yScr, int widthSrc, int heightSrc, BYTE uFade = 255) override;
virtual void DrawImage(const UiRect& rcPaint, HBITMAP hBitmap, bool bAlphaChannel,
const UiRect& rcImageDest, const UiRect& rcImageSource, const UiRect& rcCorners, BYTE uFade = 255, bool xtiled = false, bool ytiled = false) override;
virtual void DrawColor(const UiRect& rc, DWORD dwColor, BYTE uFade = 255) override;
virtual void DrawColor(const UiRect& rc, const std::wstring& colorStr, BYTE uFade = 255) override;
virtual void DrawLine(const UiRect& rc, int nSize, DWORD dwPenColor) override;
virtual void DrawLine(const IPen* pen, int x1, int y1, int x2, int y2) override;
virtual void DrawBezier(const IPen* pen, int x1, int y1, int x2, int y2, int x3, int y3, int x4, int y4) override;
virtual void DrawRect(const UiRect& rc, int nSize, DWORD dwPenColor) override;
virtual void DrawText(const UiRect& rc, const std::wstring& strText, DWORD dwTextColor, int iFont, UINT uStyle, BYTE uFade = 255, bool bLineLimit = false) override;
virtual void DrawEllipse(const UiRect& rc, int nSize, DWORD dwColor) override;
virtual void FillEllipse(const UiRect& rc, DWORD dwColor) override;
virtual UiRect MeasureText(const std::wstring& strText, int iFont, UINT uStyle, int width = DUI_NOSET_VALUE) override;
virtual void DrawPath(const IPath* path, const IPen* pen) override;
virtual void FillPath(const IPath* path, const IBrush* brush) override;
private:
HDC m_hDC;
int m_saveDC;
HBITMAP m_hOldBitmap;
bool m_bTransparent;
GdiClip m_clip;
GdiBitmap m_bitmap;
};
class UILIB_API Brush_Gdiplus : public IBrush
{
public:
Brush_Gdiplus(DWORD color);
Brush_Gdiplus(HBITMAP bitmap);
Brush_Gdiplus(const Brush_Gdiplus& r);
Brush_Gdiplus& operator=(const Brush_Gdiplus& r) = delete;
virtual IBrush* Clone() override;
Gdiplus::Brush* GetBrush() { return brush_ ? brush_.get() : bitmap_brush_.get(); };
private:
std::unique_ptr<Gdiplus::Brush> brush_;
std::unique_ptr<Gdiplus::Brush> bitmap_brush_;
};
using namespace Gdiplus;
Brush_Gdiplus::Brush_Gdiplus(DWORD color)
: IBrush(color)
{
brush_.reset(new SolidBrush(color));
}
Brush_Gdiplus::Brush_Gdiplus(HBITMAP bitmap)
: IBrush(bitmap)
{
Gdiplus::Bitmap image(bitmap, NULL);
bitmap_brush_.reset(new TextureBrush(&image));
}
Brush_Gdiplus::Brush_Gdiplus(const Brush_Gdiplus& r)
: IBrush(r)
{
if (r.brush_)
brush_.reset(r.brush_->Clone());
if (r.bitmap_brush_)
bitmap_brush_.reset(r.bitmap_brush_->Clone());
}
ui::IBrush* Brush_Gdiplus::Clone()
{
return new Brush_Gdiplus(*this);
}
GDI+工厂派生类的实现
class UILIB_API RenderFactory_GdiPlus : public IRenderFactory
{
public:
virtual ui::IPen* CreatePen(DWORD color, int width = 1) override;
virtual ui::IBrush* CreateBrush(DWORD corlor) override;
virtual ui::IBrush* CreateBrush(HBITMAP bitmap) override;
virtual ui::IMatrix* CreateMatrix() override;
virtual ui::IPath* CreatePath() override;
virtual ui::IBitmap* CreateBitmap() override;
virtual ui::IRenderContext* CreateRenderContext() override;
};
ui::IPen* RenderFactory_GdiPlus::CreatePen(DWORD color, int width /*= 1*/)
{
return new Pen_GdiPlus(color, width);
}
ui::IBrush* RenderFactory_GdiPlus::CreateBrush(DWORD color)
{
return new Brush_Gdiplus(color);
}
ui::IBrush* RenderFactory_GdiPlus::CreateBrush(HBITMAP bitmap)
{
return new Brush_Gdiplus(bitmap);
}
ui::IMatrix* RenderFactory_GdiPlus::CreateMatrix()
{
return new Matrix_Gdiplus();
}
ui::IPath* RenderFactory_GdiPlus::CreatePath()
{
return new Path_Gdiplus();
}
ui::IBitmap* RenderFactory_GdiPlus::CreateBitmap()
{
return new GdiBitmap();
}
ui::IRenderContext* RenderFactory_GdiPlus::CreateRenderContext()
{
return new RenderContext_GdiPlus();
}
实例
初始化duilib时,先创建具体实现gdiplus功能的工厂类
std::unique_ptr<IRenderFactory> GlobalManager::m_renderFactory;
void GlobalManager::Startup(const std::wstring& strResourcePath, const CreateControlCallback& callback, bool bAdaptDpi, const std::wstring& theme, const std::wstring& language)
{
m_renderFactory = std::make_unique<RenderFactory_GdiPlus>();
然后,由工厂类,创建各种具体的接口派生实现类
std::unique_ptr<ui::IRenderContext> GlobalManager::CreateRenderContext()
{
std::unique_ptr<ui::IRenderContext> p;
p.reset(m_renderFactory->CreateRenderContext());
return p;
}
std::unique_ptr<ui::IPen> GlobalManager::CreatePen(DWORD color, int width /*= 1*/)
{
std::unique_ptr<ui::IPen> p;
p.reset(m_renderFactory->CreatePen(color, width));
return p;
}
std::unique_ptr<ui::IBrush> GlobalManager::CreateBrush(DWORD color)
{
std::unique_ptr<ui::IBrush> p;
p.reset(m_renderFactory->CreateBrush(color));
return p;
}
std::unique_ptr<ui::IMatrix> GlobalManager::CreateMatrix()
{
std::unique_ptr<ui::IMatrix> p;
p.reset(m_renderFactory->CreateMatrix());
return p;
}
std::unique_ptr<ui::IPath> GlobalManager::CreatePath()
{
std::unique_ptr<ui::IPath> p;
p.reset(m_renderFactory->CreatePath());
return p;
}
void GlobalManager::Shutdown()
{
if (g_hzip)
{
CloseZip(g_hzip);
g_hzip = NULL;
}
m_renderFactory.reset();
RemoveAllFonts();
Gdiplus::GdiplusShutdown(g_gdiplusToken);
}
来源:oschina
链接:https://my.oschina.net/u/4406166/blog/4473526