新增ETexture、EFont、EText,删除了ERactangle

This commit is contained in:
Nomango 2017-10-18 22:13:20 +08:00
parent ecc1cbffce
commit 59e4004294
18 changed files with 1162 additions and 716 deletions

View File

@ -10,7 +10,7 @@ int main()
auto node = new ENode();
node->setPos(50, 80);
node->setSize(30, 180);
node->_setSize(30, 180);
scene->add(node);
/*auto listener = new EMouseListener([=] {

View File

@ -14,25 +14,16 @@ int WINAPI WinMain(
{
auto scene = new EScene();
auto sprite = new ESprite(L"test.png");
sprite->setAnchor(0.5f, 0.5f);
sprite->setPos(EApp::getWidth() / 2, sprite->getHeight() / 2);
auto text = new EText(L"中文测试中文测试中文测试中文测试中文测试中文测试中文测试", EColor::WHITE, L"Microsoft Yahei");
text->setPos(EApp::getWidth() / 2, EApp::getHeight() / 2);
//text->setWordWrapping(true);
//text->setWordWrappingWidth(130);
text->setRotation(40);
text->getFont()->setItalic(true);
text->setAnchor(0.5f, 0.5f);
text->setColor(EColor::WHITE);
scene->add(text);
auto sprite2 = new ESprite(L"test.png");
sprite2->setPos(30, 0);
sprite2->setScale(0.5);
sprite2->setRotation(45);
sprite->addChild(sprite2);
auto mlistener = new EMouseDoubleClickListener([=](EPoint p) {
//sprite->setRotation(sprite->getRotation() + 10);
EApp::setWindowSize(640, 480);
});
mlistener->bindWith(sprite);
scene->add(sprite);
app.enterScene(scene);
app.run();
}

View File

@ -13,16 +13,16 @@ using namespace std::chrono;
// 唯一实例指针
e2d::EApp * s_pInstance = nullptr;
static e2d::EApp * s_pInstance = nullptr;
// 场景栈
std::stack<e2d::EScene*> s_SceneStack;
static std::stack<e2d::EScene*> s_SceneStack;
// 游戏开始时间
static steady_clock::time_point s_tStart;
e2d::EApp::EApp()
: m_bRunning(false)
, nAnimationInterval(17LL)
, m_ClearColor(EColor::Black)
, m_ClearColor(EColor::BLACK)
, m_pCurrentScene(nullptr)
, m_pNextScene(nullptr)
{
@ -91,8 +91,12 @@ bool e2d::EApp::init(const EString &title, UINT32 width, UINT32 height, int wind
height = static_cast<UINT>(ceil(height * dpiY / 96.f));
// 获取屏幕分辨率
int screenWidth = GetSystemMetrics(SM_CXSCREEN);
int screenHeight = GetSystemMetrics(SM_CYSCREEN);
UINT screenWidth = static_cast<UINT>(GetSystemMetrics(SM_CXSCREEN));
UINT screenHeight = static_cast<UINT>(GetSystemMetrics(SM_CYSCREEN));
// 当输入的窗口大小比分辨率大时,给出警告
WARN_IF(screenWidth < width || screenHeight < height, "The window is larger than screen!");
width = min(width, screenWidth);
height = min(height, screenHeight);
// 创建屏幕居中的矩形
RECT rtWindow;
rtWindow.left = (screenWidth - width) / 2;
@ -230,8 +234,9 @@ void e2d::EApp::onActivate()
{
}
void e2d::EApp::onInactive()
bool e2d::EApp::onInactive()
{
return true;
}
bool e2d::EApp::onCloseWindow()
@ -310,7 +315,7 @@ bool e2d::EApp::_onRender()
{
GetRenderTarget()->BeginDraw();
// 使用背景色清空屏幕
GetRenderTarget()->Clear(D2D1::ColorF(m_ClearColor));
GetRenderTarget()->Clear(D2D1::ColorF(m_ClearColor.value));
// 绘制当前场景
m_pCurrentScene->_onRender();
@ -480,7 +485,7 @@ void e2d::EApp::free()
s_SceneStack.pop();
}
// 删除图片缓存
ESprite::clearCache();
ETexture::clearCache();
// 删除所有对象
EObjectManager::clearAllObjects();
}
@ -671,10 +676,12 @@ LRESULT e2d::EApp::WndProc(HWND hWnd, UINT message, WPARAM wParam, LPARAM lParam
{
if (LOWORD(wParam) == WA_INACTIVE)
{
pEApp->getCurrentScene()->onInactive();
pEApp->onInactive();
if (pEApp->getCurrentScene()->onInactive() &&
pEApp->onInactive())
{
pEApp->m_bPaused = true;
}
}
else
{
pEApp->onActivate();

View File

@ -30,8 +30,9 @@ void e2d::EScene::onActivate()
{
}
void e2d::EScene::onInactive()
bool e2d::EScene::onInactive()
{
return true;
}
bool e2d::EScene::onCloseWindow()

View File

@ -206,9 +206,10 @@
<ClCompile Include="Msg\Listener\EMouseListener.cpp" />
<ClCompile Include="Msg\Listener\EMousePressListener.cpp" />
<ClCompile Include="Node\ENode.cpp" />
<ClCompile Include="Node\ERectangle.cpp" />
<ClCompile Include="Node\ESprite.cpp" />
<ClCompile Include="Node\EText.cpp" />
<ClCompile Include="Node\EFont.cpp" />
<ClCompile Include="Node\ETexture.cpp" />
<ClCompile Include="Tool\EObjectManager.cpp" />
<ClCompile Include="Tool\ETimerManager.cpp" />
<ClCompile Include="Win\winbase.cpp" />

View File

@ -54,9 +54,6 @@
<ClCompile Include="Tool\ETimerManager.cpp">
<Filter>Tool</Filter>
</ClCompile>
<ClCompile Include="Node\ERectangle.cpp">
<Filter>Node</Filter>
</ClCompile>
<ClCompile Include="Node\ESprite.cpp">
<Filter>Node</Filter>
</ClCompile>
@ -81,6 +78,12 @@
<ClCompile Include="Node\EText.cpp">
<Filter>Node</Filter>
</ClCompile>
<ClCompile Include="Node\EFont.cpp">
<Filter>Node</Filter>
</ClCompile>
<ClCompile Include="Node\ETexture.cpp">
<Filter>Node</Filter>
</ClCompile>
</ItemGroup>
<ItemGroup>
<ClInclude Include="Win\winbase.h">

91
Easy2D/Node/EFont.cpp Normal file
View File

@ -0,0 +1,91 @@
#include "..\enodes.h"
#include "..\Win\winbase.h"
e2d::EFont::EFont()
: m_pTextFormat(nullptr)
, m_fFontSize(22)
, m_FontWeight(EFontWeight::REGULAR)
, m_bItalic(false)
, m_bRecreateNeeded(true)
{
}
e2d::EFont::EFont(EString fontFamily, float fontSize, EFontWeight fontWeight, bool italic)
{
this->setFamily(fontFamily);
this->setSize(fontSize);
this->setWeight(fontWeight);
this->setItalic(italic);
}
e2d::EFont::~EFont()
{
SafeReleaseInterface(&m_pTextFormat);
}
float e2d::EFont::getFontSize() const
{
return m_fFontSize;
}
e2d::EFontWeight e2d::EFont::getFontWeight() const
{
return m_FontWeight;
}
bool e2d::EFont::isItalic() const
{
return m_bItalic;
}
void e2d::EFont::setFamily(EString fontFamily)
{
m_sFontFamily = fontFamily;
m_bRecreateNeeded = true;
}
void e2d::EFont::setSize(float fontSize)
{
m_fFontSize = fontSize;
m_bRecreateNeeded = true;
}
void e2d::EFont::setWeight(EFontWeight fontWeight)
{
m_FontWeight = fontWeight;
m_bRecreateNeeded = true;
}
void e2d::EFont::setItalic(bool value)
{
m_bItalic = value;
m_bRecreateNeeded = true;
}
void e2d::EFont::_initTextFormat()
{
SafeReleaseInterface(&m_pTextFormat);
HRESULT hr = GetDirectWriteFactory()->CreateTextFormat(
m_sFontFamily.c_str(),
NULL, // Font collection(NULL sets it to the system font collection)
DWRITE_FONT_WEIGHT(m_FontWeight.value),
m_bItalic ? DWRITE_FONT_STYLE_ITALIC : DWRITE_FONT_STYLE_NORMAL,
DWRITE_FONT_STRETCH_NORMAL,
m_fFontSize,
L"en-us", // Local
&m_pTextFormat
);
ASSERT(SUCCEEDED(hr), "Create IDWriteTextFormat Failed!");
}
IDWriteTextFormat * e2d::EFont::_getTextFormat()
{
if (m_bRecreateNeeded)
{
_initTextFormat();
m_bRecreateNeeded = false;
}
return m_pTextFormat;
}

View File

@ -357,22 +357,22 @@ void e2d::ENode::move(const EVec & v)
this->move(v.x, v.y);
}
void e2d::ENode::setWidth(float width)
void e2d::ENode::_setWidth(float width)
{
this->setSize(width, m_Size.height);
this->_setSize(width, m_Size.height);
}
void e2d::ENode::setHeight(float height)
void e2d::ENode::_setHeight(float height)
{
this->setSize(m_Size.width, height);
this->_setSize(m_Size.width, height);
}
void e2d::ENode::setSize(const ESize & size)
void e2d::ENode::_setSize(const ESize & size)
{
this->setSize(size.width, size.height);
this->_setSize(size.width, size.height);
}
void e2d::ENode::setSize(float width, float height)
void e2d::ENode::_setSize(float width, float height)
{
if (m_Size.width == width && m_Size.height == height)
return;

View File

@ -1,24 +0,0 @@
#include "..\enodes.h"
#include "..\Win\winbase.h"
e2d::ERectangle::ERectangle()
{
}
e2d::EColor e2d::ERectangle::getColor() const
{
return m_Color;
}
void e2d::ERectangle::setColor(EColor color)
{
m_Color = color;
}
void e2d::ERectangle::_onRender()
{
D2D1_RECT_F rectangle = D2D1::RectF(0, 0, getWidth(), getHeight());
GetSolidColorBrush()->SetColor(D2D1::ColorF(m_Color, m_fDisplayOpacity));
GetRenderTarget()->FillRectangle(&rectangle, GetSolidColorBrush());
}

View File

@ -1,452 +1,79 @@
#include "..\enodes.h"
#include <map>
struct ResKey
{
ResKey() { resNameHash = 0; resTypeHash = 0; }
bool operator < (ResKey const& key) const
{
if (resNameHash > key.resNameHash)
return true;
else if (resNameHash == key.resNameHash)
return resTypeHash > key.resTypeHash;
else
return false;
}
size_t resNameHash;
size_t resTypeHash;
};
static std::map<size_t, ID2D1Bitmap*> s_mBitmapsFromFile;
static std::map<ResKey, ID2D1Bitmap*> s_mBitmapsFromResource;
static ID2D1Bitmap * GetBitmapFromFile(const e2d::EString & fileName);
static ID2D1Bitmap * GetBitmapFromResource(const e2d::EString & resourceName, const e2d::EString & resourceType);
#include "..\Win\winbase.h"
e2d::ESprite::ESprite()
: m_pBitmap(nullptr)
, m_fSourcePosX(0)
: m_fSourcePosX(0)
, m_fSourcePosY(0)
, m_fSourceWidth(0)
, m_fSourceHeight(0)
, m_pTexture(nullptr)
{
}
e2d::ESprite::ESprite(const EString & imageFileName)
: ESprite()
{
setImage(imageFileName);
setTexture(new ETexture(imageFileName));
}
e2d::ESprite::ESprite(const EString & imageFileName, float x, float y, float width, float height)
{
setImage(imageFileName);
clipImage(x, y, width, height);
setTexture(new ETexture(imageFileName));
clipTexture(x, y, width, height);
}
e2d::ESprite::ESprite(const EString & resourceName, const EString & resourceType)
: ESprite()
{
setImage(resourceName, resourceType);
setTexture(new ETexture(resourceName, resourceType));
}
e2d::ESprite::ESprite(const EString & resourceName, const EString & resourceType, float x, float y, float width, float height)
{
setImage(resourceName, resourceType);
clipImage(x, y, width, height);
setTexture(new ETexture(resourceName, resourceType));
clipTexture(x, y, width, height);
}
float e2d::ESprite::getWidth() const
e2d::ESprite::~ESprite()
{
return m_fSourceWidth * m_fScaleX;
SafeRelease(&m_pTexture);
}
float e2d::ESprite::getHeight() const
void e2d::ESprite::setTexture(ETexture * texture)
{
return m_fSourceHeight * m_fScaleY;
}
e2d::ESize e2d::ESprite::getSize() const
{
return ESize(getWidth(), getHeight());
}
float e2d::ESprite::getRealWidth() const
{
return m_fSourceWidth;
}
float e2d::ESprite::getRealHeight() const
{
return m_fSourceHeight;
}
e2d::ESize e2d::ESprite::getRealSize() const
{
return ESize(m_fSourceWidth, m_fSourceHeight);
}
void e2d::ESprite::setWidth(float)
{
}
void e2d::ESprite::setHeight(float)
{
}
void e2d::ESprite::setSize(float, float)
{
}
void e2d::ESprite::setImage(const EString & fileName)
{
WARN_IF(fileName.empty(), "ESprite cannot load bitmap from NULL file name.");
if (fileName.empty() || m_sFileName == fileName)
return;
m_sFileName = fileName;
SafeReleaseInterface(&m_pBitmap);
m_pBitmap = GetBitmapFromFile(m_sFileName);
ASSERT(m_pBitmap, "ESprite create device resources failed!");
SafeRelease(&m_pTexture);
m_pTexture = texture;
m_pTexture->retain();
m_fSourcePosX = m_fSourcePosY = 0;
m_fSourceWidth = m_pBitmap->GetSize().width;
m_fSourceHeight = m_pBitmap->GetSize().height;
ENode::_setWidth(m_pTexture->getSourceWidth());
ENode::_setHeight(m_pTexture->getSourceHeight());
}
void e2d::ESprite::setImage(const EString & fileName, float x, float y, float width, float height)
void e2d::ESprite::setTexture(ETexture * texture, float x, float y, float width, float height)
{
setImage(fileName);
clipImage(x, y, width, height);
setTexture(texture);
clipTexture(x, y, width, height);
}
void e2d::ESprite::setImage(const EString & resourceName, const EString & resourceType)
{
WARN_IF(resourceName.empty() || resourceType.empty(), "ESprite cannot load bitmap from NULL resource.");
if (resourceName.empty() || resourceType.empty())
return;
if (m_sResourceName == resourceName && m_sResourceType == resourceType)
return;
if (!m_sFileName.empty())
m_sFileName.clear();
m_sResourceName = resourceName;
m_sResourceType = resourceType;
SafeReleaseInterface(&m_pBitmap);
m_pBitmap = GetBitmapFromResource(resourceName, resourceType);
ASSERT(m_pBitmap, "ESprite create device resources failed!");
m_fSourcePosX = m_fSourcePosY = 0;
m_fSourceWidth = m_pBitmap->GetSize().width;
m_fSourceHeight = m_pBitmap->GetSize().height;
}
void e2d::ESprite::setImage(const EString & resourceName, const EString & resourceType, float x, float y, float width, float height)
{
setImage(resourceName, resourceType);
clipImage(x, y, width, height);
}
void e2d::ESprite::clipImage(float x, float y, float width, float height)
void e2d::ESprite::clipTexture(float x, float y, float width, float height)
{
m_fSourcePosX = max(x, 0);
m_fSourcePosY = max(y, 0);
m_fSourceWidth = min(max(width, 0), m_pBitmap->GetSize().width - m_fSourcePosX);
m_fSourceHeight = min(max(height, 0), m_pBitmap->GetSize().width - m_fSourcePosX);
ENode::_setWidth(min(max(width, 0), m_pTexture->getSourceWidth() - m_fSourcePosX));
ENode::_setHeight(min(max(height, 0), m_pTexture->getSourceHeight() - m_fSourcePosX));
}
void e2d::ESprite::_onRender()
{
if (m_pBitmap)
if (m_pTexture && m_pTexture->_getBitmap())
{
// Draw bitmap
GetRenderTarget()->DrawBitmap(
m_pBitmap,
D2D1::RectF(0, 0, m_fSourceWidth, m_fSourceHeight),
m_pTexture->_getBitmap(),
D2D1::RectF(0, 0, getRealWidth(), getRealHeight()),
m_fDisplayOpacity,
D2D1_BITMAP_INTERPOLATION_MODE_LINEAR,
D2D1::RectF(m_fSourcePosX, m_fSourcePosY, m_fSourceWidth, m_fSourceHeight)
D2D1::RectF(m_fSourcePosX, m_fSourcePosY, getRealWidth(), getRealHeight())
);
}
}
bool e2d::ESprite::preloadImage(const EString & fileName)
{
std::hash<e2d::EString> h;
size_t hash = h(fileName);
if (s_mBitmapsFromFile.find(hash) != s_mBitmapsFromFile.end())
{
return true;
}
HRESULT hr = S_OK;
IWICBitmapDecoder *pDecoder = nullptr;
IWICBitmapFrameDecode *pSource = nullptr;
IWICStream *pStream = nullptr;
IWICFormatConverter *pConverter = nullptr;
ID2D1Bitmap *pBitmap = nullptr;
// 创建解码器
hr = GetImagingFactory()->CreateDecoderFromFilename(
fileName.c_str(),
NULL,
GENERIC_READ,
WICDecodeMetadataCacheOnLoad,
&pDecoder
);
if (SUCCEEDED(hr))
{
// 创建初始化框架
hr = pDecoder->GetFrame(0, &pSource);
}
if (SUCCEEDED(hr))
{
// 创建图片格式转换器
// (DXGI_FORMAT_B8G8R8A8_UNORM + D2D1_ALPHA_MODE_PREMULTIPLIED).
hr = GetImagingFactory()->CreateFormatConverter(&pConverter);
}
if (SUCCEEDED(hr))
{
// 图片格式转换成 32bbpPBGRA
hr = pConverter->Initialize(
pSource,
GUID_WICPixelFormat32bppPBGRA,
WICBitmapDitherTypeNone,
NULL,
0.f,
WICBitmapPaletteTypeMedianCut
);
}
if (SUCCEEDED(hr))
{
// 从 WIC 位图创建一个 Direct2D 位图
hr = GetRenderTarget()->CreateBitmapFromWicBitmap(
pConverter,
NULL,
&pBitmap
);
}
if (SUCCEEDED(hr))
{
// 保存图片指针和图片的 Hash 名
std::hash<e2d::EString> h;
size_t hash = h(fileName);
s_mBitmapsFromFile.insert(
std::map<size_t, ID2D1Bitmap*>::value_type(
hash,
pBitmap)
);
}
// 释放相关资源
SafeReleaseInterface(&pDecoder);
SafeReleaseInterface(&pSource);
SafeReleaseInterface(&pStream);
SafeReleaseInterface(&pConverter);
return SUCCEEDED(hr);
}
bool e2d::ESprite::preloadImage(const EString & resourceName, const EString & resourceType)
{
std::hash<e2d::EString> h;
ResKey key;
key.resNameHash = h(resourceName);
key.resTypeHash = h(resourceType);
if (s_mBitmapsFromResource.find(key) != s_mBitmapsFromResource.end())
{
return true;
}
HRESULT hr = S_OK;
IWICBitmapDecoder *pDecoder = nullptr;
IWICBitmapFrameDecode *pSource = nullptr;
IWICStream *pStream = nullptr;
IWICFormatConverter *pConverter = nullptr;
IWICBitmapScaler *pScaler = nullptr;
ID2D1Bitmap *pBitmap = nullptr;
HRSRC imageResHandle = nullptr;
HGLOBAL imageResDataHandle = nullptr;
void *pImageFile = nullptr;
DWORD imageFileSize = 0;
// 定位资源
imageResHandle = ::FindResourceW(HINST_THISCOMPONENT, resourceName.c_str(), resourceType.c_str());
hr = imageResHandle ? S_OK : E_FAIL;
if (SUCCEEDED(hr))
{
// 加载资源
imageResDataHandle = ::LoadResource(HINST_THISCOMPONENT, imageResHandle);
hr = imageResDataHandle ? S_OK : E_FAIL;
}
if (SUCCEEDED(hr))
{
// 获取文件指针,并锁定资源
pImageFile = ::LockResource(imageResDataHandle);
hr = pImageFile ? S_OK : E_FAIL;
}
if (SUCCEEDED(hr))
{
// 计算大小
imageFileSize = SizeofResource(HINST_THISCOMPONENT, imageResHandle);
hr = imageFileSize ? S_OK : E_FAIL;
}
if (SUCCEEDED(hr))
{
// 创建 WIC 流
hr = GetImagingFactory()->CreateStream(&pStream);
}
if (SUCCEEDED(hr))
{
// 初始化流
hr = pStream->InitializeFromMemory(
reinterpret_cast<BYTE*>(pImageFile),
imageFileSize
);
}
if (SUCCEEDED(hr))
{
// 创建流的解码器
hr = GetImagingFactory()->CreateDecoderFromStream(
pStream,
NULL,
WICDecodeMetadataCacheOnLoad,
&pDecoder
);
}
if (SUCCEEDED(hr))
{
// 创建初始化框架
hr = pDecoder->GetFrame(0, &pSource);
}
if (SUCCEEDED(hr))
{
// 创建图片格式转换器
// (DXGI_FORMAT_B8G8R8A8_UNORM + D2D1_ALPHA_MODE_PREMULTIPLIED).
hr = GetImagingFactory()->CreateFormatConverter(&pConverter);
}
if (SUCCEEDED(hr))
{
// 图片格式转换成 32bppPBGRA
hr = pConverter->Initialize(
pSource,
GUID_WICPixelFormat32bppPBGRA,
WICBitmapDitherTypeNone,
NULL,
0.f,
WICBitmapPaletteTypeMedianCut
);
}
if (SUCCEEDED(hr))
{
// 从 WIC 位图创建一个 Direct2D 位图
hr = GetRenderTarget()->CreateBitmapFromWicBitmap(
pConverter,
NULL,
&pBitmap
);
}
if (SUCCEEDED(hr))
{
std::hash<e2d::EString> h;
ResKey key;
key.resNameHash = h(resourceName);
key.resTypeHash = h(resourceType);
s_mBitmapsFromResource.insert(
std::map<ResKey, ID2D1Bitmap*>::value_type(
key,
pBitmap)
);
}
// 释放相关资源
SafeReleaseInterface(&pDecoder);
SafeReleaseInterface(&pSource);
SafeReleaseInterface(&pStream);
SafeReleaseInterface(&pConverter);
SafeReleaseInterface(&pScaler);
return SUCCEEDED(hr);
}
void e2d::ESprite::clearCache()
{
for (auto child : s_mBitmapsFromFile)
{
SafeReleaseInterface(&child.second);
}
for (auto child : s_mBitmapsFromResource)
{
SafeReleaseInterface(&child.second);
}
s_mBitmapsFromFile.clear();
s_mBitmapsFromResource.clear();
}
ID2D1Bitmap * GetBitmapFromFile(const e2d::EString & fileName)
{
if (!e2d::ESprite::preloadImage(fileName))
{
return nullptr;
}
std::hash<e2d::EString> h;
size_t hash = h(fileName);
return s_mBitmapsFromFile.at(hash);
}
ID2D1Bitmap * GetBitmapFromResource(const e2d::EString & resourceName, const e2d::EString & resourceType)
{
if (!e2d::ESprite::preloadImage(resourceName, resourceType))
{
return nullptr;
}
ResKey key;
std::hash<e2d::EString> h;
key.resNameHash = h(resourceName);
key.resTypeHash = h(resourceType);
return s_mBitmapsFromResource.at(key);
}

View File

@ -1 +1,166 @@
#include "..\enodes.h"
#include "..\Win\winbase.h"
e2d::EText::EText()
: m_Color(EColor::WHITE)
, m_bWordWrapping(false)
, m_pFont(nullptr)
, m_fWordWrappingWidth(0)
{
this->setFont(new EFont());
}
e2d::EText::EText(const EString & text)
: EText()
{
this->setText(text);
this->setFont(new EFont());
}
e2d::EText::EText(EFont * font)
: EText()
{
this->setFont(font);
}
e2d::EText::EText(const EString & text, EColor color, EFont * font)
: EText()
{
this->setText(text);
this->setColor(color);
this->setFont(font);
}
e2d::EText::EText(const EString & text, EColor color, EString fontFamily, float fontSize, EFontWeight fontWeight, bool italic)
{
this->setText(text);
this->setColor(color);
this->setFont(new EFont(fontFamily, fontSize, fontWeight, italic));
}
e2d::EText::~EText()
{
SafeRelease(&m_pFont);
}
e2d::EString e2d::EText::getText() const
{
return m_sText;
}
float e2d::EText::getWidth() const
{
return m_fWordWrappingWidth * m_fScaleX;
}
float e2d::EText::getRealWidth() const
{
return m_fWordWrappingWidth;
}
e2d::EColor e2d::EText::getColor() const
{
return m_Color;
}
e2d::EFont * e2d::EText::getFont() const
{
return m_pFont;
}
void e2d::EText::setText(const EString & text)
{
m_sText = text;
_initTextLayout();
}
void e2d::EText::setColor(EColor color)
{
m_Color = color;
}
void e2d::EText::setFont(EFont * font)
{
if (font)
{
SafeRelease(&m_pFont);
m_pFont = font;
font->retain();
_initTextLayout();
}
}
void e2d::EText::setWordWrapping(bool value)
{
m_bWordWrapping = value;
_initTextLayout();
}
void e2d::EText::setWordWrappingWidth(float wordWrapWidth)
{
m_fWordWrappingWidth = max(wordWrapWidth, 0);
_initTextLayout();
}
void e2d::EText::_onRender()
{
GetSolidColorBrush()->SetColor(D2D1::ColorF(m_Color.value, m_fDisplayOpacity));
GetRenderTarget()->DrawTextW(
m_sText.c_str(),
m_sText.length(),
m_pFont->_getTextFormat(),
D2D1::RectF(
0,
0,
m_bWordWrapping ? m_fWordWrappingWidth : m_Size.width,
getRealHeight()
),
GetSolidColorBrush()
);
}
void e2d::EText::_initTextLayout()
{
// 未设置字体或空字符串时,文本宽高为 0
if (!m_pFont || m_sText.empty())
{
this->_setHeight(0);
m_fWordWrappingWidth = 0;
return;
}
// 未打开文本自动换行时,设置 TextFormat 属性为不换行
if (!m_bWordWrapping)
{
m_pFont->_getTextFormat()->SetWordWrapping(DWRITE_WORD_WRAPPING_NO_WRAP);
}
else
{
m_pFont->_getTextFormat()->SetWordWrapping(DWRITE_WORD_WRAPPING_WRAP);
}
// 获取 TextLayout
IDWriteTextLayout * pDWriteTextLayout = nullptr;
HRESULT hr = GetDirectWriteFactory()->CreateTextLayout(
m_sText.c_str(),
m_sText.size(),
m_pFont->_getTextFormat(),
m_bWordWrapping ? m_fWordWrappingWidth : 0,
0,
&pDWriteTextLayout
);
ASSERT(SUCCEEDED(hr), "Create IDWriteTextFormat Failed!");
// 获取文本布局的宽度和高度
DWRITE_TEXT_METRICS metrics;
pDWriteTextLayout->GetMetrics(&metrics);
this->_setSize(metrics.widthIncludingTrailingWhitespace, metrics.height);
m_fWordWrappingWidth = metrics.widthIncludingTrailingWhitespace;
// 删除相关资源
SafeReleaseInterface(&pDWriteTextLayout);
}

369
Easy2D/Node/ETexture.cpp Normal file
View File

@ -0,0 +1,369 @@
#include "..\enodes.h"
#include "..\Win\winbase.h"
#include <map>
struct ResKey
{
ResKey() { resNameHash = 0; resTypeHash = 0; }
bool operator < (ResKey const& key) const
{
if (resNameHash > key.resNameHash)
return true;
else if (resNameHash == key.resNameHash)
return resTypeHash > key.resTypeHash;
else
return false;
}
size_t resNameHash;
size_t resTypeHash;
};
static std::map<size_t, ID2D1Bitmap*> s_mBitmapsFromFile;
static std::map<ResKey, ID2D1Bitmap*> s_mBitmapsFromResource;
e2d::ETexture::ETexture()
: m_pBitmap(nullptr)
{
}
e2d::ETexture::ETexture(const EString & fileName)
{
this->loadFromFile(fileName);
}
e2d::ETexture::ETexture(const EString & resourceName, const EString & resourceType)
{
this->loadFromResource(resourceName, resourceType);
}
e2d::ETexture::~ETexture()
{
SafeReleaseInterface(&m_pBitmap);
}
void e2d::ETexture::loadFromFile(const EString & fileName)
{
WARN_IF(fileName.empty(), "ETexture cannot load bitmap from NULL file name.");
if (fileName.empty())
return;
SafeReleaseInterface(&m_pBitmap);
if (!e2d::ETexture::preload(fileName))
{
WARN_IF(true, "Load ETexture from file failed!");
return;
}
std::hash<e2d::EString> h;
size_t hash = h(fileName);
m_pBitmap = s_mBitmapsFromFile.at(hash);
}
void e2d::ETexture::loadFromResource(const EString & resourceName, const EString & resourceType)
{
WARN_IF(resourceName.empty() || resourceType.empty(), "ETexture cannot load bitmap from NULL resource.");
if (resourceName.empty() || resourceType.empty())
return;
SafeReleaseInterface(&m_pBitmap);
if (!e2d::ETexture::preload(resourceName, resourceType))
{
WARN_IF(true, "Load ETexture from resource failed!");
return;
}
ResKey key;
std::hash<e2d::EString> h;
key.resNameHash = h(resourceName);
key.resTypeHash = h(resourceType);
m_pBitmap = s_mBitmapsFromResource.at(key);
}
float e2d::ETexture::getSourceWidth() const
{
if (m_pBitmap)
{
return m_pBitmap->GetSize().width;
}
else
{
return 0;
}
}
float e2d::ETexture::getSourceHeight() const
{
if (m_pBitmap)
{
return m_pBitmap->GetSize().height;
}
else
{
return 0;
}
}
e2d::ESize e2d::ETexture::getSourceSize() const
{
if (m_pBitmap)
{
return ESize(getSourceWidth(), getSourceHeight());
}
else
{
return ESize();
}
}
bool e2d::ETexture::preload(const EString & fileName)
{
std::hash<e2d::EString> h;
size_t hash = h(fileName);
if (s_mBitmapsFromFile.find(hash) != s_mBitmapsFromFile.end())
{
return true;
}
HRESULT hr = S_OK;
IWICBitmapDecoder *pDecoder = nullptr;
IWICBitmapFrameDecode *pSource = nullptr;
IWICStream *pStream = nullptr;
IWICFormatConverter *pConverter = nullptr;
ID2D1Bitmap *pBitmap = nullptr;
// 创建解码器
hr = GetImagingFactory()->CreateDecoderFromFilename(
fileName.c_str(),
NULL,
GENERIC_READ,
WICDecodeMetadataCacheOnLoad,
&pDecoder
);
if (SUCCEEDED(hr))
{
// 创建初始化框架
hr = pDecoder->GetFrame(0, &pSource);
}
if (SUCCEEDED(hr))
{
// 创建图片格式转换器
// (DXGI_FORMAT_B8G8R8A8_UNORM + D2D1_ALPHA_MODE_PREMULTIPLIED).
hr = GetImagingFactory()->CreateFormatConverter(&pConverter);
}
if (SUCCEEDED(hr))
{
// 图片格式转换成 32bbpPBGRA
hr = pConverter->Initialize(
pSource,
GUID_WICPixelFormat32bppPBGRA,
WICBitmapDitherTypeNone,
NULL,
0.f,
WICBitmapPaletteTypeMedianCut
);
}
if (SUCCEEDED(hr))
{
// 从 WIC 位图创建一个 Direct2D 位图
hr = GetRenderTarget()->CreateBitmapFromWicBitmap(
pConverter,
NULL,
&pBitmap
);
}
if (SUCCEEDED(hr))
{
// 保存图片指针和图片的 Hash 名
std::hash<e2d::EString> h;
size_t hash = h(fileName);
s_mBitmapsFromFile.insert(
std::map<size_t, ID2D1Bitmap*>::value_type(
hash,
pBitmap)
);
}
// 释放相关资源
SafeReleaseInterface(&pDecoder);
SafeReleaseInterface(&pSource);
SafeReleaseInterface(&pStream);
SafeReleaseInterface(&pConverter);
return SUCCEEDED(hr);
}
bool e2d::ETexture::preload(const EString & resourceName, const EString & resourceType)
{
std::hash<e2d::EString> h;
ResKey key;
key.resNameHash = h(resourceName);
key.resTypeHash = h(resourceType);
if (s_mBitmapsFromResource.find(key) != s_mBitmapsFromResource.end())
{
return true;
}
HRESULT hr = S_OK;
IWICBitmapDecoder *pDecoder = nullptr;
IWICBitmapFrameDecode *pSource = nullptr;
IWICStream *pStream = nullptr;
IWICFormatConverter *pConverter = nullptr;
IWICBitmapScaler *pScaler = nullptr;
ID2D1Bitmap *pBitmap = nullptr;
HRSRC imageResHandle = nullptr;
HGLOBAL imageResDataHandle = nullptr;
void *pImageFile = nullptr;
DWORD imageFileSize = 0;
// 定位资源
imageResHandle = ::FindResourceW(HINST_THISCOMPONENT, resourceName.c_str(), resourceType.c_str());
hr = imageResHandle ? S_OK : E_FAIL;
if (SUCCEEDED(hr))
{
// 加载资源
imageResDataHandle = ::LoadResource(HINST_THISCOMPONENT, imageResHandle);
hr = imageResDataHandle ? S_OK : E_FAIL;
}
if (SUCCEEDED(hr))
{
// 获取文件指针,并锁定资源
pImageFile = ::LockResource(imageResDataHandle);
hr = pImageFile ? S_OK : E_FAIL;
}
if (SUCCEEDED(hr))
{
// 计算大小
imageFileSize = SizeofResource(HINST_THISCOMPONENT, imageResHandle);
hr = imageFileSize ? S_OK : E_FAIL;
}
if (SUCCEEDED(hr))
{
// 创建 WIC 流
hr = GetImagingFactory()->CreateStream(&pStream);
}
if (SUCCEEDED(hr))
{
// 初始化流
hr = pStream->InitializeFromMemory(
reinterpret_cast<BYTE*>(pImageFile),
imageFileSize
);
}
if (SUCCEEDED(hr))
{
// 创建流的解码器
hr = GetImagingFactory()->CreateDecoderFromStream(
pStream,
NULL,
WICDecodeMetadataCacheOnLoad,
&pDecoder
);
}
if (SUCCEEDED(hr))
{
// 创建初始化框架
hr = pDecoder->GetFrame(0, &pSource);
}
if (SUCCEEDED(hr))
{
// 创建图片格式转换器
// (DXGI_FORMAT_B8G8R8A8_UNORM + D2D1_ALPHA_MODE_PREMULTIPLIED).
hr = GetImagingFactory()->CreateFormatConverter(&pConverter);
}
if (SUCCEEDED(hr))
{
// 图片格式转换成 32bppPBGRA
hr = pConverter->Initialize(
pSource,
GUID_WICPixelFormat32bppPBGRA,
WICBitmapDitherTypeNone,
NULL,
0.f,
WICBitmapPaletteTypeMedianCut
);
}
if (SUCCEEDED(hr))
{
// 从 WIC 位图创建一个 Direct2D 位图
hr = GetRenderTarget()->CreateBitmapFromWicBitmap(
pConverter,
NULL,
&pBitmap
);
}
if (SUCCEEDED(hr))
{
std::hash<e2d::EString> h;
ResKey key;
key.resNameHash = h(resourceName);
key.resTypeHash = h(resourceType);
s_mBitmapsFromResource.insert(
std::map<ResKey, ID2D1Bitmap*>::value_type(
key,
pBitmap)
);
}
// 释放相关资源
SafeReleaseInterface(&pDecoder);
SafeReleaseInterface(&pSource);
SafeReleaseInterface(&pStream);
SafeReleaseInterface(&pConverter);
SafeReleaseInterface(&pScaler);
return SUCCEEDED(hr);
}
void e2d::ETexture::clearCache()
{
for (auto child : s_mBitmapsFromFile)
{
SafeReleaseInterface(&child.second);
}
for (auto child : s_mBitmapsFromResource)
{
SafeReleaseInterface(&child.second);
}
s_mBitmapsFromFile.clear();
s_mBitmapsFromResource.clear();
}
ID2D1Bitmap * e2d::ETexture::_getBitmap()
{
return m_pBitmap;
}

View File

@ -2,12 +2,13 @@
using namespace std::chrono;
HWND s_HWnd = nullptr;
ID2D1Factory * s_pDirect2dFactory = nullptr;
ID2D1HwndRenderTarget * s_pRenderTarget = nullptr;
ID2D1SolidColorBrush * s_pSolidBrush = nullptr;
IWICImagingFactory * s_pIWICFactory = nullptr;
steady_clock::time_point s_tNow;
static HWND s_HWnd = nullptr;
static ID2D1Factory * s_pDirect2dFactory = nullptr;
static ID2D1HwndRenderTarget * s_pRenderTarget = nullptr;
static ID2D1SolidColorBrush * s_pSolidBrush = nullptr;
static IWICImagingFactory * s_pIWICFactory = nullptr;
static IDWriteFactory * s_pDWriteFactory = nullptr;
static steady_clock::time_point s_tNow;
HWND &GetHWnd()
@ -60,6 +61,21 @@ ID2D1HwndRenderTarget * &GetRenderTarget()
return s_pRenderTarget;
}
IDWriteFactory * &GetDirectWriteFactory()
{
if (!s_pDWriteFactory)
{
HRESULT hr;
hr = DWriteCreateFactory(
DWRITE_FACTORY_TYPE_SHARED,
__uuidof(IDWriteFactory),
reinterpret_cast<IUnknown**>(&s_pDWriteFactory)
);
ASSERT(SUCCEEDED(hr), "Create DirectWrite Factory Failed!");
}
return s_pDWriteFactory;
}
ID2D1SolidColorBrush * &GetSolidColorBrush()
{
if (!s_pSolidBrush)

View File

@ -19,6 +19,8 @@ ID2D1SolidColorBrush * &GetSolidColorBrush();
IWICImagingFactory * &GetImagingFactory();
IDWriteFactory * &GetDirectWriteFactory();
std::chrono::steady_clock::time_point &GetNow();
long long GetInterval(std::chrono::steady_clock::time_point tLast);

View File

@ -50,7 +50,7 @@ public:
virtual void onActivate();
// 重写这个函数,它将在窗口非激活时执行
virtual void onInactive();
virtual bool onInactive();
// 重写这个函数,它将在关闭窗口时执行
virtual bool onCloseWindow();
@ -205,7 +205,7 @@ public:
virtual void onActivate();
// 重写这个函数,它将在窗口非激活时执行
virtual void onInactive();
virtual bool onInactive();
// 重写这个函数,它将在关闭窗口时执行
virtual bool onCloseWindow();

View File

@ -82,148 +82,204 @@ typedef std::function<void(int)> TIMER_CALLBACK;
enum EColor
class EColor
{
AliceBlue = 0xF0F8FF,
AntiqueWhite = 0xFAEBD7,
Aqua = 0x00FFFF,
Aquamarine = 0x7FFFD4,
Azure = 0xF0FFFF,
Beige = 0xF5F5DC,
Bisque = 0xFFE4C4,
Black = 0x000000,
BlanchedAlmond = 0xFFEBCD,
Blue = 0x0000FF,
BlueViolet = 0x8A2BE2,
Brown = 0xA52A2A,
BurlyWood = 0xDEB887,
CadetBlue = 0x5F9EA0,
Chartreuse = 0x7FFF00,
Chocolate = 0xD2691E,
Coral = 0xFF7F50,
CornflowerBlue = 0x6495ED,
Cornsilk = 0xFFF8DC,
Crimson = 0xDC143C,
Cyan = 0x00FFFF,
DarkBlue = 0x00008B,
DarkCyan = 0x008B8B,
DarkGoldenrod = 0xB8860B,
DarkGray = 0xA9A9A9,
DarkGreen = 0x006400,
DarkKhaki = 0xBDB76B,
DarkMagenta = 0x8B008B,
DarkOliveGreen = 0x556B2F,
DarkOrange = 0xFF8C00,
DarkOrchid = 0x9932CC,
DarkRed = 0x8B0000,
DarkSalmon = 0xE9967A,
DarkSeaGreen = 0x8FBC8F,
DarkSlateBlue = 0x483D8B,
DarkSlateGray = 0x2F4F4F,
DarkTurquoise = 0x00CED1,
DarkViolet = 0x9400D3,
DeepPink = 0xFF1493,
DeepSkyBlue = 0x00BFFF,
DimGray = 0x696969,
DodgerBlue = 0x1E90FF,
Firebrick = 0xB22222,
FloralWhite = 0xFFFAF0,
ForestGreen = 0x228B22,
Fuchsia = 0xFF00FF,
Gainsboro = 0xDCDCDC,
GhostWhite = 0xF8F8FF,
Gold = 0xFFD700,
Goldenrod = 0xDAA520,
Gray = 0x808080,
Green = 0x008000,
GreenYellow = 0xADFF2F,
Honeydew = 0xF0FFF0,
HotPink = 0xFF69B4,
IndianRed = 0xCD5C5C,
Indigo = 0x4B0082,
Ivory = 0xFFFFF0,
Khaki = 0xF0E68C,
Lavender = 0xE6E6FA,
LavenderBlush = 0xFFF0F5,
LawnGreen = 0x7CFC00,
LemonChiffon = 0xFFFACD,
LightBlue = 0xADD8E6,
LightCoral = 0xF08080,
LightCyan = 0xE0FFFF,
LightGoldenrodYellow = 0xFAFAD2,
LightGreen = 0x90EE90,
LightGray = 0xD3D3D3,
LightPink = 0xFFB6C1,
LightSalmon = 0xFFA07A,
LightSeaGreen = 0x20B2AA,
LightSkyBlue = 0x87CEFA,
LightSlateGray = 0x778899,
LightSteelBlue = 0xB0C4DE,
LightYellow = 0xFFFFE0,
Lime = 0x00FF00,
LimeGreen = 0x32CD32,
Linen = 0xFAF0E6,
Magenta = 0xFF00FF,
Maroon = 0x800000,
MediumAquamarine = 0x66CDAA,
MediumBlue = 0x0000CD,
MediumOrchid = 0xBA55D3,
MediumPurple = 0x9370DB,
MediumSeaGreen = 0x3CB371,
MediumSlateBlue = 0x7B68EE,
MediumSpringGreen = 0x00FA9A,
MediumTurquoise = 0x48D1CC,
MediumVioletRed = 0xC71585,
MidnightBlue = 0x191970,
MintCream = 0xF5FFFA,
MistyRose = 0xFFE4E1,
Moccasin = 0xFFE4B5,
NavajoWhite = 0xFFDEAD,
Navy = 0x000080,
OldLace = 0xFDF5E6,
Olive = 0x808000,
OliveDrab = 0x6B8E23,
Orange = 0xFFA500,
OrangeRed = 0xFF4500,
Orchid = 0xDA70D6,
PaleGoldenrod = 0xEEE8AA,
PaleGreen = 0x98FB98,
PaleTurquoise = 0xAFEEEE,
PaleVioletRed = 0xDB7093,
PapayaWhip = 0xFFEFD5,
PeachPuff = 0xFFDAB9,
Peru = 0xCD853F,
Pink = 0xFFC0CB,
Plum = 0xDDA0DD,
PowderBlue = 0xB0E0E6,
Purple = 0x800080,
Red = 0xFF0000,
RosyBrown = 0xBC8F8F,
RoyalBlue = 0x4169E1,
SaddleBrown = 0x8B4513,
Salmon = 0xFA8072,
SandyBrown = 0xF4A460,
SeaGreen = 0x2E8B57,
SeaShell = 0xFFF5EE,
Sienna = 0xA0522D,
Silver = 0xC0C0C0,
SkyBlue = 0x87CEEB,
SlateBlue = 0x6A5ACD,
SlateGray = 0x708090,
Snow = 0xFFFAFA,
SpringGreen = 0x00FF7F,
SteelBlue = 0x4682B4,
Tan = 0xD2B48C,
Teal = 0x008080,
Thistle = 0xD8BFD8,
Tomato = 0xFF6347,
Turquoise = 0x40E0D0,
Violet = 0xEE82EE,
Wheat = 0xF5DEB3,
White = 0xFFFFFF,
WhiteSmoke = 0xF5F5F5,
Yellow = 0xFFFF00,
YellowGreen = 0x9ACD32,
public:
EColor()
{
value = VALUE::WHITE;
}
EColor(int color)
{
value = VALUE(color);
}
enum VALUE
{
ALICE_BLUE = 0xF0F8FF,
ANTIQUE_WHITE = 0xFAEBD7,
AQUA = 0x00FFFF,
AQUAMARINE = 0x7FFFD4,
AZURE = 0xF0FFFF,
BEIGE = 0xF5F5DC,
BISQUE = 0xFFE4C4,
BLACK = 0x000000,
BLANCHED_ALMOND = 0xFFEBCD,
BLUE = 0x0000FF,
BLUE_VIOLET = 0x8A2BE2,
BROWN = 0xA52A2A,
BURLY_WOOD = 0xDEB887,
CADET_BLUE = 0x5F9EA0,
CHARTREUSE = 0x7FFF00,
CHOCOLATE = 0xD2691E,
CORAL = 0xFF7F50,
CORNFLOWER_BLUE = 0x6495ED,
CORNSILK = 0xFFF8DC,
CRIMSON = 0xDC143C,
CYAN = 0x00FFFF,
DARK_BLUE = 0x00008B,
DARK_CYAN = 0x008B8B,
DARK_GOLDENROD = 0xB8860B,
DARK_GRAY = 0xA9A9A9,
DARK_GREEN = 0x006400,
DARK_KHAKI = 0xBDB76B,
DARK_MAGENTA = 0x8B008B,
DARK_OLIVE_GREEN = 0x556B2F,
DARK_ORANGE = 0xFF8C00,
DARK_ORCHID = 0x9932CC,
DARK_RED = 0x8B0000,
DARK_SALMON = 0xE9967A,
DARK_SEA_GREEN = 0x8FBC8F,
DARK_SLATE_BLUE = 0x483D8B,
DARK_SLATE_GRAY = 0x2F4F4F,
DARK_TURQUOISE = 0x00CED1,
DARK_VIOLET = 0x9400D3,
DEEP_PINK = 0xFF1493,
DEEP_SKY_BLUE = 0x00BFFF,
DIM_GRAY = 0x696969,
DODGER_BLUE = 0x1E90FF,
FIREBRICK = 0xB22222,
FLORAL_WHITE = 0xFFFAF0,
FOREST_GREEN = 0x228B22,
FUCHSIA = 0xFF00FF,
GAINSCORO = 0xDCDCDC,
GHOST_WHITE = 0xF8F8FF,
GOLD = 0xFFD700,
GOLDENROD = 0xDAA520,
GRAY = 0x808080,
GREEN = 0x008000,
GREEN_YELLOW = 0xADFF2F,
HONEYDEW = 0xF0FFF0,
HOT_PINK = 0xFF69B4,
INDIAN_RED = 0xCD5C5C,
INDIGO = 0x4B0082,
IVORY = 0xFFFFF0,
KHAKI = 0xF0E68C,
LAVENDER = 0xE6E6FA,
LAVENDER_BLUSH = 0xFFF0F5,
LAWN_GREEN = 0x7CFC00,
LEMON_CHIFFON = 0xFFFACD,
LIGHT_BLUE = 0xADD8E6,
LIGHT_CORAL = 0xF08080,
LIGHT_CYAN = 0xE0FFFF,
LIGHT_GOLDENROD_YELLOW = 0xFAFAD2,
LIGHT_GREEN = 0x90EE90,
LIGHT_GRAY = 0xD3D3D3,
LIGHT_PINK = 0xFFB6C1,
LIGHT_SALMON = 0xFFA07A,
LIGHT_SEA_GREEN = 0x20B2AA,
LIGHT_SKY_BLUE = 0x87CEFA,
LIGHT_SLATE_GRAY = 0x778899,
LIGHT_STEEL_BLUE = 0xB0C4DE,
LIGHT_YELLOW = 0xFFFFE0,
LIME = 0x00FF00,
LIME_GREEN = 0x32CD32,
LINEN = 0xFAF0E6,
MAGENTA = 0xFF00FF,
MAROON = 0x800000,
MEDIUM_AQUAMARINE = 0x66CDAA,
MEDIUM_BLUE = 0x0000CD,
MEDIUM_ORCHID = 0xBA55D3,
MEDIUM_PURPLE = 0x9370DB,
MEDIUM_SEA_GREEN = 0x3CB371,
MEDIUM_SLATE_BLUE = 0x7B68EE,
MEDIUM_SPRING_GREEN = 0x00FA9A,
MEDIUM_TURQUOISE = 0x48D1CC,
MEDUIM_VIOLET_RED = 0xC71585,
MIDNIGHT_BLUE = 0x191970,
MINT_CREAM = 0xF5FFFA,
MISTY_ROSE = 0xFFE4E1,
MOCCASIN = 0xFFE4B5,
NAVAJO_WHITE = 0xFFDEAD,
NAVY = 0x000080,
OLD_LACE = 0xFDF5E6,
OLIVE = 0x808000,
OLIVE_DRAB = 0x6B8E23,
ORANGE = 0xFFA500,
ORANGE_RED = 0xFF4500,
ORCHID = 0xDA70D6,
PALE_GOLDENROD = 0xEEE8AA,
PALE_GREEN = 0x98FB98,
PALE_TURQUOISE = 0xAFEEEE,
PALE_VIOLET_RED = 0xDB7093,
PAPAYA_WHIP = 0xFFEFD5,
PEACH_PUFF = 0xFFDAB9,
PERU = 0xCD853F,
PINK = 0xFFC0CB,
PLUM = 0xDDA0DD,
POWDER_BLUE = 0xB0E0E6,
PURPLE = 0x800080,
RED = 0xFF0000,
ROSY_BROWN = 0xBC8F8F,
ROYAL_BLUE = 0x4169E1,
SADDLE_BROWN = 0x8B4513,
SALMON = 0xFA8072,
SANDY_BROWN = 0xF4A460,
SEA_GREEN = 0x2E8B57,
SEA_SHELL = 0xFFF5EE,
SIENNA = 0xA0522D,
SILVER = 0xC0C0C0,
SKY_BLUE = 0x87CEEB,
SLATE_BLUE = 0x6A5ACD,
SLATE_GRAY = 0x708090,
SNOW = 0xFFFAFA,
SPRING_GREEN = 0x00FF7F,
STEEL_BLUE = 0x4682B4,
TAN = 0xD2B48C,
TEAL = 0x008080,
THISTLE = 0xD8BFD8,
TOMATO = 0xFF6347,
TURQUOISE = 0x40E0D0,
VIOLET = 0xEE82EE,
WHEAT = 0xF5DEB3,
WHITE = 0xFFFFFF,
WHITE_SMOKE = 0xF5F5F5,
YELLOW = 0xFFFF00,
YELLOW_GREEN = 0x9ACD32
};
VALUE value;
};
class EFontWeight
{
public:
EFontWeight()
{
value = VALUE::REGULAR;
}
EFontWeight(int fontWeight)
{
value = VALUE(fontWeight);
}
enum VALUE
{
THIN = 100,
EXTRA_LIGHT = 200,
ULTRA_LIGHT = 200,
LIGHT = 300,
SEMI_LIGHT = 350,
NORMAL = 400,
REGULAR = 400,
MEDIUM = 500,
DEMI_BOLD = 600,
SEMI_BOLD = 600,
BOLD = 700,
EXTRA_BOLD = 800,
ULTRA_BOLD = 800,
BLACK = 900,
HEAVY = 900,
EXTRA_BLACK = 950,
ULTRA_BLACK = 950
};
VALUE value;
};
}

View File

@ -57,3 +57,6 @@
template<typename T>
inline void SafeDelete(T** p) { if (*p) { delete *p; *p = nullptr; } }
template<typename T>
inline void SafeRelease(T** p) { if (*p) { (*p)->autoRelease(); (*p)->release(); *p = nullptr; } }

View File

@ -1,10 +1,12 @@
#pragma once
#include "ebase.h"
#include "Win\winbase.h"
namespace e2d
{
class EText;
class ESprite;
class ENode :
public EObject
{
@ -138,27 +140,6 @@ public:
const EVec & v
);
// 设置节点宽度
virtual void setWidth(
float width
);
// 设置节点高度
virtual void setHeight(
float height
);
// 设置节点大小
virtual void setSize(
const ESize & size
);
// 设置节点大小
virtual void setSize(
float width,
float height
);
// 设置节点绘图顺序
// 默认为 0
virtual void setOrder(
@ -312,6 +293,27 @@ protected:
// 更新节点透明度
static void _updateOpacity(ENode * node);
// 设置节点宽度
virtual void _setWidth(
float width
);
// 设置节点高度
virtual void _setHeight(
float height
);
// 设置节点大小
virtual void _setSize(
const ESize & size
);
// 设置节点大小
virtual void _setSize(
float width,
float height
);
protected:
EString m_sName;
size_t m_nHashName;
@ -338,21 +340,67 @@ protected:
};
class ERectangle :
public ENode
class ETexture :
public EObject
{
friend ESprite;
public:
ERectangle();
// 创建一个空的纹理
ETexture();
EColor getColor() const;
// 从本地文件中读取资源
ETexture(
const EString & fileName
);
void setColor(EColor color);
// 读取程序资源
ETexture(
const EString & resourceName,
const EString & resourceType
);
~ETexture();
// 从本地文件中读取资源
void loadFromFile(
const EString & fileName
);
// 读取程序资源
void loadFromResource(
const EString & resourceName,
const EString & resourceType
);
// 获取源图片宽度
virtual float getSourceWidth() const;
// 获取源图片高度
virtual float getSourceHeight() const;
// 获取源图片大小
virtual ESize getSourceSize() const;
// 预加载资源
static bool preload(
const EString & fileName
);
// 预加载资源
static bool preload(
const EString & resourceName,
const EString & resourceType
);
// 清空缓存
static void clearCache();
protected:
virtual void _onRender() override;
ID2D1Bitmap * _getBitmap();
protected:
EColor m_Color;
ID2D1Bitmap * m_pBitmap;
};
@ -393,85 +441,30 @@ public:
float height
);
// 获取精灵宽度
virtual float getWidth() const override;
~ESprite();
// 获取精灵高度
virtual float getHeight() const override;
// 获取精灵大小
virtual ESize getSize() const override;
// 获取精灵宽度(不考虑缩放)
virtual float getRealWidth() const override;
// 获取精灵高度(不考虑缩放)
virtual float getRealHeight() const override;
// 获取精灵大小(不考虑缩放)
virtual ESize getRealSize() const override;
// 设置精灵宽度是失效的
virtual void setWidth(float) override;
// 设置精灵高度是失效的
virtual void setHeight(float) override;
// 设置精灵大小是失效的
virtual void setSize(float, float) override;
// 从文件加载图片
void setImage(
const EString & fileName
// 设置精灵纹理
void setTexture(
ETexture * texture
);
// 从文件加载图片并裁剪
void setImage(
const EString & fileName,
// 设置精灵纹理并裁剪
void setTexture(
ETexture * texture,
float x,
float y,
float width,
float height
);
// 从资源加载图片
void setImage(
const EString & resourceName,
const EString & resourceType
);
// 从资源加载图片并裁剪
void setImage(
const EString & resourceName,
const EString & resourceType,
// 裁剪纹理
void clipTexture(
float x,
float y,
float width,
float height
);
// 裁剪原图片
void clipImage(
float x,
float y,
float width,
float height
);
// 预加载资源
static bool preloadImage(
const EString & fileName
);
// 预加载资源
static bool preloadImage(
const EString & resourceName,
const EString & resourceType
);
// 清空图片缓存
static void clearCache();
protected:
// 渲染精灵
virtual void _onRender() override;
@ -479,12 +472,157 @@ protected:
protected:
float m_fSourcePosX;
float m_fSourcePosY;
float m_fSourceWidth;
float m_fSourceHeight;
EString m_sFileName;
EString m_sResourceName;
EString m_sResourceType;
ID2D1Bitmap * m_pBitmap;
ETexture * m_pTexture;
};
class EFont :
public EObject
{
friend EText;
public:
EFont();
EFont(
EString fontFamily,
float fontSize = 22,
EFontWeight fontWeight = EFontWeight::REGULAR,
bool italic = false
);
~EFont();
// 获取当前字号
float getFontSize() const;
// 获取当前字体粗细值
EFontWeight getFontWeight() const;
// 是否是斜体
bool isItalic() const;
// 设置字体
void setFamily(
EString fontFamily
);
// 设置字号
void setSize(
float fontSize
);
// 设置字体粗细值
void setWeight(
EFontWeight fontWeight
);
// 设置文字斜体
void setItalic(
bool value
);
protected:
// 创建文字格式
void _initTextFormat();
// 获取文字格式
IDWriteTextFormat * _getTextFormat();
protected:
EString m_sFontFamily;
float m_fFontSize;
EFontWeight m_FontWeight;
bool m_bItalic;
bool m_bRecreateNeeded;
IDWriteTextFormat * m_pTextFormat;
};
class EText :
public ENode
{
public:
EText();
EText(
const EString & text
);
EText(
EFont * font
);
EText(
const EString & text,
EColor color,
EFont * font
);
EText(
const EString & text,
EColor color,
EString fontFamily,
float fontSize = 22,
EFontWeight fontWeight = EFontWeight::REGULAR,
bool italic = false
);
~EText();
// 获取文本
EString getText() const;
// 获取文本宽度
virtual float getWidth() const override;
// 获取文本宽度(不考虑缩放)
virtual float getRealWidth() const override;
// 获取文字颜色
EColor getColor() const;
// 获取字体
EFont * getFont() const;
// 设置文本
void setText(
const EString & text
);
// 设置文字颜色
void setColor(
EColor color
);
// 设置字体
void setFont(
EFont * font
);
// 设置文字自动换行
void setWordWrapping(
bool value
);
// 设置文字换行宽度WordWrapping 打开时生效)
void setWordWrappingWidth(
float wordWrapWidth
);
protected:
// 渲染文字
virtual void _onRender() override;
// 创建文字布局
void _initTextLayout();
protected:
EString m_sText;
EColor m_Color;
bool m_bWordWrapping;
float m_fWordWrappingWidth;
EFont * m_pFont;
};
}