You cannot select more than 25 topics Topics must start with a letter or number, can include dashes ('-') and can be up to 35 characters long.

266 lines
8.3 KiB
C

1 month ago
#pragma once
#define USED_Direct2D 1
#if USED_Direct2D
#ifndef UI_EXPORT
#define UI_EXPORT
#endif
// Windows Header Files:
#include <windows.h>
// C RunTime Header Files:
#include <stdlib.h>
#include <malloc.h>
#include <memory.h>
#include <wchar.h>
#include <math.h>
#include <d2d1.h>
#include <d2d1helper.h>
#include <dwrite.h>
#include <wincodec.h>
#include <string>
#include <list>
#include <map>
#include "RenderType.h"
namespace EzUI {
namespace D2D {
extern ID2D1Factory* g_Direct2dFactory;
extern IDWriteFactory* g_WriteFactory;
extern IWICImagingFactory* g_ImageFactory;
}
class Font {
private:
Font() = delete;
std::wstring fontFamily;
int fontSize = 0;
IDWriteTextFormat* value = NULL;
void Copy(const Font& _copy);
public:
bool Ref = false;
Font(const Font& _copy);
Font(const std::wstring& fontFamily, int fontSize);
Font(const std::string &fontFamily, int fontSize);
const int& GetFontSize()const;
const std::wstring& GetFontFamily()const;
IDWriteTextFormat* Get() const;
Font& operator=(const Font& _copy);
bool operator==(const Font& _right);
virtual ~Font();
};
class TextLayout {
private:
TextLayout() = delete;
TextLayout(const TextLayout& _copy) = delete;
TextLayout& operator=(const TextLayout& _copy) = delete;
IDWriteTextLayout* value = NULL;
public:
TextLayout(const std::wstring& text, const Font& pTextFormat, TextAlign textAlgin = TextAlign::TopLeft, __Size maxSize = __Size{ 16777216,16777216 });
TextLayout(const std::string& text, const Font& pTextFormat, TextAlign textAlgin = TextAlign::TopLeft, __Size maxSize = __Size{ 16777216,16777216 });
__Point HitTestPoint(const __Point& pt, int& textPos, BOOL& isTrailingHit);
__Point HitTestTextPosition(int textPos, BOOL isTrailingHit);
__Size GetFontBox();
void SetTextAlign(TextAlign textAlign);
IDWriteTextLayout* Get() const;
void SetUnderline(size_t pos = 0, size_t count = 0);
virtual ~TextLayout();
};
class Geometry
{
public:
bool Ref = false;
ID2D1Geometry* rgn = NULL;
protected:
void Copy(const Geometry& _copy) {
((Geometry&)(_copy)).Ref = true;
this->rgn = ((Geometry&)(_copy)).rgn;
}
public:
Geometry() {}
Geometry(const Geometry& _copy) {
Copy(_copy);
}
Geometry& operator =(const Geometry& _right) {
Copy(_right);
return *this;
}
Geometry(int x, int y, int width, int height) {
D2D_RECT_F rectF{ (FLOAT)x,(FLOAT)y,(FLOAT)(x + width),(FLOAT)(y + height) };
D2D::g_Direct2dFactory->CreateRectangleGeometry(rectF, (ID2D1RectangleGeometry**)&rgn);
}
/* Geometry(const __Rect& rect) :Geometry(rect.X, rect.Y, rect.Width, rect.Height) {};*/
Geometry(int x, int y, int width, int height, int _radius) {
float radius = _radius / 2.0f;
D2D1_ROUNDED_RECT rectF{ (FLOAT)x,(FLOAT)y,(FLOAT)(x + width),(FLOAT)(y + height) ,radius ,radius };
D2D::g_Direct2dFactory->CreateRoundedRectangleGeometry(rectF, (ID2D1RoundedRectangleGeometry**)&rgn);
}
virtual ~Geometry() {
if (rgn && !Ref) {
rgn->Release();
}
}
public:
static void Combine(Geometry& out, const Geometry& a, const Geometry& b, D2D1_COMBINE_MODE COMBINE_MODE)
{
ID2D1PathGeometry* outPathGeometry = NULL;
D2D::g_Direct2dFactory->CreatePathGeometry(&outPathGeometry);
ID2D1GeometrySink* geometrySink = NULL;
outPathGeometry->Open(&geometrySink);
HRESULT ret = a.rgn->CombineWithGeometry(b.rgn, COMBINE_MODE, NULL, geometrySink);
geometrySink->Close();
if (out.rgn) {
out.rgn->Release();
}
out.rgn = outPathGeometry;
geometrySink->Release();
}
//<2F><><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD>ȡ<EFBFBD><C8A1><EFBFBD><EFBFBD><EFBFBD>߽<EFBFBD>
static void Union(Geometry& out, const Geometry& a, const Geometry& b) {
Combine(out, a, b, D2D1_COMBINE_MODE::D2D1_COMBINE_MODE_UNION);
}
//<2F><><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD>н<EFBFBD><D0BD><EFBFBD><EFBFBD>IJ<EFBFBD><C4B2><EFBFBD>
static void Intersect(Geometry& out, const Geometry& a, const Geometry& b) {
Combine(out, a, b, D2D1_COMBINE_MODE::D2D1_COMBINE_MODE_INTERSECT);
}
static void Xor(Geometry& out, const Geometry& a, const Geometry& b) {
Combine(out, a, b, D2D1_COMBINE_MODE::D2D1_COMBINE_MODE_XOR);
}
static void Exclude(Geometry& out, const Geometry& a, const Geometry& b) {
Combine(out, a, b, D2D1_COMBINE_MODE::D2D1_COMBINE_MODE_EXCLUDE);
}
};
class D2DPath {
private:
ID2D1GeometrySink* pSink = NULL;
ID2D1PathGeometry* pathGeometry = NULL;
bool isBegin = false;
public:
D2DPath() {
D2D::g_Direct2dFactory->CreatePathGeometry(&pathGeometry);
pathGeometry->Open(&pSink);
}
void AddRectangle(const __Rect& rect) {
if (!isBegin) {
pSink->BeginFigure({ (FLOAT)rect.GetLeft(),(FLOAT)rect.GetTop() }, D2D1_FIGURE_BEGIN_FILLED);
isBegin = true;
}
else {
pSink->AddLine({ (FLOAT)rect.GetLeft(),(FLOAT)rect.GetTop() });
}
pSink->AddLine({ (FLOAT)rect.GetRight(),(FLOAT)rect.GetTop() });
pSink->AddLine({ (FLOAT)rect.GetRight(),(FLOAT)rect.GetBottom() });
pSink->AddLine({ (FLOAT)rect.GetLeft(),(FLOAT)rect.GetBottom() });
}
void AddArc(const __Rect& rect, int startAngle, int sweepAngle) {
}
void AddLine(const __Rect& rect) {
}
void CloseFigure() {
pSink->EndFigure(D2D1_FIGURE_END_OPEN);
pSink->Close();
}
virtual ~D2DPath() {
if (pathGeometry) {
pathGeometry->Release();
}
if (pSink) {
pSink->Release();
}
}
ID2D1PathGeometry* Get()const {
return pathGeometry;
}
ID2D1GeometrySink* operator ->() {
return pSink;
}
ID2D1PathGeometry* operator *() {
return pathGeometry;
}
};
class UI_EXPORT DXImage : public IImage {
protected:
IWICBitmapDecoder* bitmapdecoder = NULL;
IWICBitmapFrameDecode* pframe = NULL;
IWICFormatConverter* fmtcovter = NULL;//<2F><><EFBFBD>ļ<EFBFBD><C4BC><EFBFBD><EFBFBD><EFBFBD>
IWICBitmap* bitMap = NULL;//<2F><>HBITMAP<41>м<EFBFBD><D0BC><EFBFBD>
UINT Width = 0;
UINT Height = 0;
public:
ID2D1Bitmap* d2dBitmap = NULL;
public:
void CreateFormStream(IStream* istram);
void CreateFromFile(const std::wstring& file);
void Init();
public:
void DecodeOfRender(ID2D1RenderTarget* render);
DXImage(HBITMAP hBitmap);
DXImage(IStream* istram);
DXImage(const std::wstring& file);
UINT GetWidth();
UINT GetHeight();
virtual size_t NextFrame()override;
DXImage() {}
virtual ~DXImage();
public:
static DXImage* FromFile() {
return NULL;
}
};
class Bezier {
public:
__Point point1;
__Point point2;
__Point point3;
};
};
namespace EzUI {
UI_EXPORT void RenderInitialize();//ȫ<>ֳ<EFBFBD>ʼ<EFBFBD><CABC>direct2d
UI_EXPORT void RenderUnInitialize();//<2F>ͷ<EFBFBD>direct2d
enum class StrokeStyle
{
Solid,//ʵ<><CAB5>
Dash//<2F><><EFBFBD><EFBFBD>
};
class UI_EXPORT D2DRender {
private:
std::list<bool> layers;
ID2D1DCRenderTarget* render = NULL;
ID2D1SolidColorBrush* brush = NULL;
Font* font = NULL;
ID2D1StrokeStyle* pStrokeStyle = NULL;
public:
ID2D1SolidColorBrush* GetBrush();
ID2D1StrokeStyle* GetStrokeStyle();
public:
D2DRender(HDC dc, int x, int y, int width, int height);//<2F><><EFBFBD><EFBFBD>dx<64><78>ͼ<EFBFBD><CDBC><EFBFBD><EFBFBD>
virtual ~D2DRender();
void SetFont(const std::wstring& fontFamily, int fontSize);//<2F><><EFBFBD><EFBFBD><EFBFBD>ȵ<EFBFBD><C8B5><EFBFBD>
void SetFont(const Font& _copy_font);//<2F><><EFBFBD><EFBFBD><EFBFBD>ȵ<EFBFBD><C8B5><EFBFBD>
void SetColor(const __Color& color);//<2F><>֮ǰ<D6AE><C7B0><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD>
void SetStrokeStyle(StrokeStyle strokeStyle = StrokeStyle::Solid, int dashWidth = 3);//<2F><><EFBFBD><EFBFBD><EFBFBD><EFBFBD>ʽ <20><><EFBFBD><EFBFBD><><CAB5>
void DrawString(const TextLayout& textLayout, __Point = { 0,0 });//<2F><><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD>еIJ<D0B5><C4B2>ֻ<EFBFBD><D6BB><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD>
void DrawString(const std::wstring& text, const __Rect& _rect, EzUI::TextAlign textAlign);//<2F><><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD>
void DrawString(const std::string& text, const __Rect& _rect, EzUI::TextAlign textAlign);//<2F><><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD>
void DrawLine(const __Point& _A, const __Point& _B, int width);//<2F><><EFBFBD><EFBFBD>һ<EFBFBD><D2BB><EFBFBD><EFBFBD>
void DrawRectangle(const __Rect& _rect, int _radius = 0, int width = 1);//<2F><><EFBFBD>ƾ<EFBFBD><C6BE><EFBFBD>
void FillRectangle(const __Rect& _rect, int _radius = 0);//<2F><><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD>
void PushLayer(const __Rect& rectBounds);//<2F>ٶȽϿ<C8BD>
void PushLayer(const Geometry& dxGeometry);//<2F>ȽϺ<C8BD><CFBA><EFBFBD><EFBFBD><EFBFBD>,<2C><><EFBFBD>ǿ<EFBFBD><C7BF><EFBFBD><EFBFBD><EFBFBD><EFBFBD>ο<EFBFBD><CEBF><EFBFBD><EFBFBD>ݲü<DDB2>
void PopLayer();//<2F><><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD>һ<EFBFBD><D2BB><EFBFBD>ü<EFBFBD>
void DrawImage(IImage* _image, const __Rect& _rect, const ImageSizeMode& imageSizeMode, const EzUI::Margin& margin = 0);//<2F><><EFBFBD><EFBFBD>ͼ<EFBFBD><CDBC>
void SetTransform(int xOffset, int yOffset, int angle = 0);//<2F>Ի<EFBFBD><D4BB><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD>ת<EFBFBD><D7AA>ƫ<EFBFBD><C6AB>
void DrawBezier(const __Point& startPoint, const Bezier& points, int width = 1);//<2F><><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD>
void DrawBezier(const __Point& startPoint, std::list<Bezier>& points, int width = 1);//<2F><><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD>
void DrawEllipse(const __Point&& point, int radiusX, int radiusY, int width = 1);
void FillEllipse(const __Point&& point, int radiusX, int radiusY);
ID2D1DCRenderTarget* Get();//<2F><>ȡԭ<C8A1><D4AD>DX<44><58><EFBFBD><EFBFBD>
};
using Painter = D2DRender;
};
#endif