add: Factory

This commit is contained in:
Haibo 2018-11-21 17:18:59 +08:00 committed by Nomango
parent 0088bd88a3
commit b9ac2c3934
16 changed files with 777 additions and 602 deletions

View File

@ -23,6 +23,7 @@
#include "logs.h"
#include "Image.h"
#include "Geometry.h"
#include "Factory.h"
namespace easy2d
{
@ -57,7 +58,7 @@ namespace easy2d
);
ThrowIfFailed(
devices::Graphics::Instance()->CreateTextRenderer(
Factory::Instance()->CreateTextRenderer(
text_renderer_,
render_target_,
text_brush_
@ -125,7 +126,7 @@ namespace easy2d
void Canvas::SetOutlineJoinStyle(StrokeStyle outline_join)
{
outline_join_style_ = devices::Graphics::Instance()->GetStrokeStyle(outline_join);
outline_join_style_ = Factory::Instance()->GetStrokeStyle(outline_join);
}
void Canvas::SetTextStyle(Font const& font, TextStyle const & text_style)
@ -138,7 +139,7 @@ namespace easy2d
text_style_.outline,
text_style_.outline_color,
text_style_.outline_width,
devices::Graphics::Instance()->GetStrokeStyle(text_style_.outline_stroke).Get()
Factory::Instance()->GetStrokeStyle(text_style_.outline_stroke).Get()
);
}
@ -266,11 +267,9 @@ namespace easy2d
if (text.empty())
return;
auto graphics = devices::Graphics::Instance();
cpTextFormat text_format;
ThrowIfFailed(
graphics->CreateTextFormat(
Factory::Instance()->CreateTextFormat(
text_format,
text_font_,
text_style_
@ -280,7 +279,7 @@ namespace easy2d
cpTextLayout text_layout;
Size layout_size;
ThrowIfFailed(
graphics->CreateTextLayout(
Factory::Instance()->CreateTextLayout(
text_layout,
layout_size,
text,
@ -389,7 +388,7 @@ namespace easy2d
current_geometry_ = nullptr;
ThrowIfFailed(
devices::Graphics::Instance()->CreatePathGeometry(current_geometry_)
Factory::Instance()->CreatePathGeometry(current_geometry_)
);
ThrowIfFailed(

518
core/base/Factory.cpp Normal file
View File

@ -0,0 +1,518 @@
// Copyright (c) 2016-2018 Easy2D - Nomango
//
// Permission is hereby granted, free of charge, to any person obtaining a copy
// of this software and associated documentation files (the "Software"), to deal
// in the Software without restriction, including without limitation the rights
// to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
// copies of the Software, and to permit persons to whom the Software is
// furnished to do so, subject to the following conditions:
//
// The above copyright notice and this permission notice shall be included in
// all copies or substantial portions of the Software.
//
// THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
// IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
// FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
// AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
// LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
// OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN
// THE SOFTWARE.
#include "Factory.h"
#include "logs.h"
#include "modules.h"
#include "Transform.hpp"
namespace easy2d
{
FactoryImpl::FactoryImpl()
: initialized_(false)
{
}
FactoryImpl::~FactoryImpl()
{
E2D_LOG("Destroying device independent resources");
}
void FactoryImpl::Init(bool debug)
{
if (initialized_)
return;
E2D_LOG("Creating device independent resources");
D2D1_FACTORY_OPTIONS fact_options;
fact_options.debugLevel = debug ? D2D1_DEBUG_LEVEL_INFORMATION : D2D1_DEBUG_LEVEL_NONE;
ThrowIfFailed(
modules::DirectX().D2D1CreateFactory(
D2D1_FACTORY_TYPE_SINGLE_THREADED,
__uuidof(ID2D1Factory),
&fact_options,
reinterpret_cast<void**>(&factory)
)
);
ThrowIfFailed(
CoCreateInstance(
CLSID_WICImagingFactory,
nullptr,
CLSCTX_INPROC_SERVER,
__uuidof(IWICImagingFactory),
reinterpret_cast<void**>(&imaging_factory)
)
);
ThrowIfFailed(
modules::DirectX().DWriteCreateFactory(
DWRITE_FACTORY_TYPE_SHARED,
__uuidof(IDWriteFactory),
reinterpret_cast<IUnknown**>(&write_factory)
)
);
auto stroke_style = D2D1::StrokeStyleProperties(
D2D1_CAP_STYLE_FLAT,
D2D1_CAP_STYLE_FLAT,
D2D1_CAP_STYLE_FLAT,
D2D1_LINE_JOIN_MITER,
2.0f,
D2D1_DASH_STYLE_SOLID,
0.0f
);
ThrowIfFailed(
factory->CreateStrokeStyle(
stroke_style,
nullptr,
0,
&miter_stroke_style
)
);
stroke_style.lineJoin = D2D1_LINE_JOIN_BEVEL;
ThrowIfFailed(
factory->CreateStrokeStyle(
stroke_style,
nullptr,
0,
&bevel_stroke_style
)
);
stroke_style.lineJoin = D2D1_LINE_JOIN_ROUND;
ThrowIfFailed(
factory->CreateStrokeStyle(
stroke_style,
nullptr,
0,
&round_stroke_style
)
);
initialized_ = true;
}
HRESULT FactoryImpl::CreateHwndRenderTarget(cpHwndRenderTarget & hwnd_render_target, D2D1_RENDER_TARGET_PROPERTIES const & properties, D2D1_HWND_RENDER_TARGET_PROPERTIES const & hwnd_rt_properties) const
{
if (!factory)
return E_UNEXPECTED;
cpHwndRenderTarget hwnd_render_target_tmp;
HRESULT hr = factory->CreateHwndRenderTarget(
properties,
hwnd_rt_properties,
&hwnd_render_target_tmp
);
if (SUCCEEDED(hr))
hwnd_render_target = hwnd_render_target_tmp;
return hr;
}
HRESULT FactoryImpl::CreateTextRenderer(
cpTextRenderer& text_renderer,
cpRenderTarget const& render_target,
cpSolidColorBrush const& brush
)
{
if (!factory)
return E_UNEXPECTED;
cpTextRenderer text_renderer_tmp;
HRESULT hr = ITextRenderer::Create(
&text_renderer_tmp,
factory.Get(),
render_target.Get(),
brush.Get()
);
if (SUCCEEDED(hr))
text_renderer = text_renderer_tmp;
return hr;
}
HRESULT FactoryImpl::CreateBitmapFromFile(cpBitmap & bitmap, cpRenderTarget const & rt, String const & file_path)
{
if (imaging_factory == nullptr)
{
return E_UNEXPECTED;
}
using namespace intrusive;
SmartPointer<IWICBitmapDecoder> decoder;
SmartPointer<IWICBitmapFrameDecode> source;
SmartPointer<IWICStream> stream;
SmartPointer<IWICFormatConverter> converter;
SmartPointer<ID2D1Bitmap> bitmap_tmp;
HRESULT hr = imaging_factory->CreateDecoderFromFilename(
file_path.c_str(),
nullptr,
GENERIC_READ,
WICDecodeMetadataCacheOnLoad,
&decoder
);
if (SUCCEEDED(hr))
{
hr = decoder->GetFrame(0, &source);
}
if (SUCCEEDED(hr))
{
hr = imaging_factory->CreateFormatConverter(&converter);
}
if (SUCCEEDED(hr))
{
// 图片格式转换成 32bppPBGRA
hr = converter->Initialize(
source.Get(),
GUID_WICPixelFormat32bppPBGRA,
WICBitmapDitherTypeNone,
nullptr,
0.f,
WICBitmapPaletteTypeMedianCut
);
}
if (SUCCEEDED(hr))
{
hr = rt->CreateBitmapFromWicBitmap(
converter.Get(),
nullptr,
&bitmap_tmp
);
}
if (SUCCEEDED(hr))
bitmap = bitmap_tmp;
return hr;
}
HRESULT FactoryImpl::CreateBitmapFromResource(cpBitmap & bitmap, cpRenderTarget const & rt, Resource const & res)
{
if (imaging_factory == nullptr)
{
return E_UNEXPECTED;
}
using namespace intrusive;
SmartPointer<IWICBitmapDecoder> decoder;
SmartPointer<IWICBitmapFrameDecode> source;
SmartPointer<IWICStream> stream;
SmartPointer<IWICFormatConverter> converter;
SmartPointer<ID2D1Bitmap> bitmap_tmp;
// 加载资源
ResourceData buffer;
HRESULT hr = res.Load(&buffer) ? S_OK : E_FAIL;
if (SUCCEEDED(hr))
{
hr = imaging_factory->CreateStream(&stream);
}
if (SUCCEEDED(hr))
{
hr = stream->InitializeFromMemory(
static_cast<WICInProcPointer>(buffer.buffer),
buffer.buffer_size
);
}
if (SUCCEEDED(hr))
{
hr = imaging_factory->CreateDecoderFromStream(
stream.Get(),
nullptr,
WICDecodeMetadataCacheOnLoad,
&decoder
);
}
if (SUCCEEDED(hr))
{
hr = decoder->GetFrame(0, &source);
}
if (SUCCEEDED(hr))
{
hr = imaging_factory->CreateFormatConverter(&converter);
}
if (SUCCEEDED(hr))
{
// 图片格式转换成 32bppPBGRA
hr = converter->Initialize(
source.Get(),
GUID_WICPixelFormat32bppPBGRA,
WICBitmapDitherTypeNone,
nullptr,
0.f,
WICBitmapPaletteTypeMedianCut
);
}
if (SUCCEEDED(hr))
{
hr = rt->CreateBitmapFromWicBitmap(
converter.Get(),
nullptr,
&bitmap_tmp
);
}
if (SUCCEEDED(hr))
{
bitmap = bitmap_tmp;
}
return hr;
}
HRESULT FactoryImpl::CreateRectangleGeometry(cpRectangleGeometry & geo, Rect const& rect) const
{
if (!factory)
return E_UNEXPECTED;
cpRectangleGeometry rectangle;
HRESULT hr = factory->CreateRectangleGeometry(
rect,
&rectangle
);
if (SUCCEEDED(hr))
geo = rectangle;
return hr;
}
HRESULT FactoryImpl::CreateRoundedRectangleGeometry(cpRoundedRectangleGeometry & geo, Rect const & rect, float radius_x, float radius_y) const
{
if (!factory)
return E_UNEXPECTED;
cpRoundedRectangleGeometry rounded_rect;
HRESULT hr = factory->CreateRoundedRectangleGeometry(
D2D1::RoundedRect(
rect,
radius_x,
radius_y
),
&rounded_rect
);
if (SUCCEEDED(hr))
geo = rounded_rect;
return hr;
}
HRESULT FactoryImpl::CreateEllipseGeometry(cpEllipseGeometry & geo, Point const & center, float radius_x, float radius_y) const
{
if (!factory)
return E_UNEXPECTED;
cpEllipseGeometry ellipse;
HRESULT hr = factory->CreateEllipseGeometry(
D2D1::Ellipse(
center,
radius_x,
radius_y
),
&ellipse
);
if (SUCCEEDED(hr))
geo = ellipse;
return hr;
}
HRESULT FactoryImpl::CreateTransformedGeometry(
cpTransformedGeometry& transformed,
math::Matrix const& matrix,
cpGeometry const& geo
) const
{
if (!factory)
return E_UNEXPECTED;
cpTransformedGeometry transformed_tmp;
HRESULT hr = factory->CreateTransformedGeometry(
geo.Get(),
ConvertToD2DMatrix(matrix),
&transformed_tmp
);
if (SUCCEEDED(hr))
{
transformed = transformed_tmp;
}
return hr;
}
HRESULT FactoryImpl::CreatePathGeometry(cpPathGeometry & geometry) const
{
if (!factory)
return E_UNEXPECTED;
return factory->CreatePathGeometry(&geometry);
}
HRESULT FactoryImpl::CreateTextFormat(cpTextFormat & text_format, Font const & font, TextStyle const & text_style) const
{
if (!write_factory)
return E_UNEXPECTED;
cpTextFormat text_format_tmp;
HRESULT hr = write_factory->CreateTextFormat(
font.family.c_str(),
nullptr,
DWRITE_FONT_WEIGHT(font.weight),
font.italic ? DWRITE_FONT_STYLE_ITALIC : DWRITE_FONT_STYLE_NORMAL,
DWRITE_FONT_STRETCH_NORMAL,
font.size,
L"",
&text_format_tmp
);
if (SUCCEEDED(hr))
{
if (text_style.line_spacing == 0.f)
{
text_format_tmp->SetLineSpacing(DWRITE_LINE_SPACING_METHOD_DEFAULT, 0, 0);
}
else
{
text_format_tmp->SetLineSpacing(
DWRITE_LINE_SPACING_METHOD_UNIFORM,
text_style.line_spacing,
text_style.line_spacing * 0.8f
);
}
text_format_tmp->SetTextAlignment(DWRITE_TEXT_ALIGNMENT(text_style.alignment));
text_format_tmp->SetWordWrapping(text_style.wrap ? DWRITE_WORD_WRAPPING_WRAP : DWRITE_WORD_WRAPPING_NO_WRAP);
text_format = text_format_tmp;
}
return hr;
}
HRESULT FactoryImpl::CreateTextLayout(cpTextLayout & text_layout, Size& layout_size, String const & text, cpTextFormat const& text_format, TextStyle const & text_style) const
{
if (!write_factory)
return E_UNEXPECTED;
text_layout = nullptr;
HRESULT hr;
cpTextLayout text_layout_tmp;
UINT32 length = static_cast<UINT32>(text.length());
if (text_style.wrap)
{
hr = write_factory->CreateTextLayout(
text.c_str(),
length,
text_format.Get(),
text_style.wrap_width,
0,
&text_layout_tmp
);
}
else
{
hr = write_factory->CreateTextLayout(
text.c_str(),
length,
text_format.Get(),
0,
0,
&text_layout_tmp
);
DWRITE_TEXT_METRICS metrics;
text_layout_tmp->GetMetrics(&metrics);
if (SUCCEEDED(hr))
{
text_layout_tmp = nullptr;
hr = write_factory->CreateTextLayout(
text.c_str(),
length,
text_format.Get(),
metrics.width,
0,
&text_layout_tmp
);
}
}
if (SUCCEEDED(hr))
{
DWRITE_TEXT_METRICS metrics;
text_layout_tmp->GetMetrics(&metrics);
if (text_style.wrap)
{
layout_size = Size(metrics.layoutWidth, metrics.height);
}
else
{
layout_size = Size(metrics.width, metrics.height);
}
DWRITE_TEXT_RANGE range = { 0, length };
if (text_style.underline)
{
text_layout_tmp->SetUnderline(true, range);
}
if (text_style.strikethrough)
{
text_layout_tmp->SetStrikethrough(true, range);
}
text_layout = text_layout_tmp;
}
return hr;
}
cpStrokeStyle const& FactoryImpl::GetStrokeStyle(StrokeStyle stroke) const
{
switch (stroke)
{
case StrokeStyle::Miter:
return miter_stroke_style;
break;
case StrokeStyle::Bevel:
return bevel_stroke_style;
break;
case StrokeStyle::Round:
return round_stroke_style;
break;
}
return miter_stroke_style;
}
}

127
core/base/Factory.h Normal file
View File

@ -0,0 +1,127 @@
// Copyright (c) 2016-2018 Easy2D - Nomango
//
// Permission is hereby granted, free of charge, to any person obtaining a copy
// of this software and associated documentation files (the "Software"), to deal
// in the Software without restriction, including without limitation the rights
// to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
// copies of the Software, and to permit persons to whom the Software is
// furnished to do so, subject to the following conditions:
//
// The above copyright notice and this permission notice shall be included in
// all copies or substantial portions of the Software.
//
// THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
// IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
// FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
// AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
// LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
// OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN
// THE SOFTWARE.
#pragma once
#include "base.hpp"
#include "Singleton.hpp"
#include "Font.hpp"
#include "Resource.h"
#include "TextRenderer.h"
#include "TextStyle.hpp"
#include "../math/Matrix.hpp"
namespace easy2d
{
class FactoryImpl
: protected Noncopyable
{
E2D_DECLARE_SINGLETON(FactoryImpl);
public:
void Init(bool debug);
HRESULT CreateHwndRenderTarget(
cpHwndRenderTarget& hwnd_render_target,
D2D1_RENDER_TARGET_PROPERTIES const& properties,
D2D1_HWND_RENDER_TARGET_PROPERTIES const& hwnd_rt_properties
) const;
HRESULT CreateTextRenderer(
cpTextRenderer& text_renderer,
cpRenderTarget const& render_target,
cpSolidColorBrush const& brush
);
HRESULT CreateBitmapFromFile(
cpBitmap& bitmap,
cpRenderTarget const& rt,
String const& file_path
);
HRESULT CreateBitmapFromResource(
cpBitmap& bitmap,
cpRenderTarget const& rt,
Resource const& res
);
HRESULT CreateRectangleGeometry(
cpRectangleGeometry& geo,
Rect const& rect
) const;
HRESULT CreateRoundedRectangleGeometry(
cpRoundedRectangleGeometry& geo,
Rect const& rect,
float radius_x,
float radius_y
) const;
HRESULT CreateEllipseGeometry(
cpEllipseGeometry& geo,
Point const& center,
float radius_x,
float radius_y
) const;
HRESULT CreateTransformedGeometry(
cpTransformedGeometry& transformed,
math::Matrix const& matrix,
cpGeometry const& geo
) const;
HRESULT CreatePathGeometry(
cpPathGeometry& geometry
) const;
HRESULT CreateTextFormat(
cpTextFormat& text_format,
Font const& font,
TextStyle const& text_style
) const;
HRESULT CreateTextLayout(
cpTextLayout& text_layout,
Size& layout_size,
String const& text,
cpTextFormat const& text_format,
TextStyle const& text_style
) const;
cpStrokeStyle const& GetStrokeStyle(
StrokeStyle stroke
) const;
protected:
FactoryImpl();
~FactoryImpl();
protected:
bool initialized_;
cpFactory factory;
cpImagingFactory imaging_factory;
cpWriteFactory write_factory;
cpStrokeStyle miter_stroke_style;
cpStrokeStyle bevel_stroke_style;
cpStrokeStyle round_stroke_style;
};
E2D_DECLARE_SINGLETON_TYPE(FactoryImpl, Factory);
}

View File

@ -23,6 +23,7 @@
#include "input.h"
#include "audio.h"
#include "modules.h"
#include "Factory.h"
#include "Scene.h"
#include "Transition.h"
#include "Debuger.h"
@ -77,6 +78,7 @@ namespace easy2d
::SetWindowLongW(hwnd_, GWLP_USERDATA, PtrToUlong(this));
Factory::Instance()->Init(debug_enabled_);
devices::Graphics::Instance()->Init(hwnd_, options.graphics_options, debug_enabled_);
devices::Input::Instance()->Init(hwnd_, window->GetContentScaleX(), window->GetContentScaleY(), debug_enabled_);
devices::Audio::Instance()->Init(debug_enabled_);

View File

@ -19,6 +19,7 @@
// THE SOFTWARE.
#include "Geometry.h"
#include "Factory.h"
#include "render.h"
#include "logs.h"
@ -120,7 +121,7 @@ namespace easy2d
return GeometryRelation::Unknown;
cpTransformedGeometry transformed;
HRESULT hr = devices::Graphics::Instance()->CreateTransformedGeometry(
HRESULT hr = Factory::Instance()->CreateTransformedGeometry(
transformed,
GetTransformMatrix(),
geo_.Get()
@ -162,7 +163,7 @@ namespace easy2d
cpPathGeometry path_geo;
cpGeometrySink path_sink;
HRESULT hr = devices::Graphics::Instance()->CreatePathGeometry(path_geo);
HRESULT hr = Factory::Instance()->CreatePathGeometry(path_geo);
if (SUCCEEDED(hr))
{
@ -219,7 +220,7 @@ namespace easy2d
void RectangleGeometry::SetRect(Rect const & rect)
{
cpRectangleGeometry geo;
if (SUCCEEDED(devices::Graphics::Instance()->CreateRectangleGeometry(geo, rect)))
if (SUCCEEDED(Factory::Instance()->CreateRectangleGeometry(geo, rect)))
{
geo_ = geo;
rect_ = rect;
@ -258,7 +259,7 @@ namespace easy2d
void CircleGeometry::SetCircle(Point const & center, float radius)
{
cpEllipseGeometry geo;
if (SUCCEEDED(devices::Graphics::Instance()->CreateEllipseGeometry(geo, center, radius, radius)))
if (SUCCEEDED(Factory::Instance()->CreateEllipseGeometry(geo, center, radius, radius)))
{
geo_ = geo;
center_ = center;
@ -299,7 +300,7 @@ namespace easy2d
void EllipseGeometry::SetEllipse(Point const & center, float radius_x, float radius_y)
{
cpEllipseGeometry geo;
if (SUCCEEDED(devices::Graphics::Instance()->CreateEllipseGeometry(geo, center, radius_x, radius_y)))
if (SUCCEEDED(Factory::Instance()->CreateEllipseGeometry(geo, center, radius_x, radius_y)))
{
geo_ = geo;
radius_x_ = radius_x;
@ -325,7 +326,7 @@ namespace easy2d
current_geometry_ = nullptr;
ThrowIfFailed(
devices::Graphics::Instance()->CreatePathGeometry(current_geometry_)
Factory::Instance()->CreatePathGeometry(current_geometry_)
);
ThrowIfFailed(
@ -448,7 +449,7 @@ namespace easy2d
void RoundedRectGeometry::SetRoundedRect(Rect const & rect, float radius_x, float radius_y)
{
cpRoundedRectangleGeometry geo;
if (SUCCEEDED(devices::Graphics::Instance()->CreateRoundedRectangleGeometry(geo, rect, radius_x, radius_y)))
if (SUCCEEDED(Factory::Instance()->CreateRoundedRectangleGeometry(geo, rect, radius_x, radius_y)))
{
geo_ = geo;
rect_ = rect;

View File

@ -19,6 +19,7 @@
// THE SOFTWARE.
#include "Node.h"
#include "Factory.h"
#include "Scene.h"
#include "Task.h"
#include "Action.hpp"
@ -213,14 +214,14 @@ namespace easy2d
cpTransformedGeometry transformed;
ThrowIfFailed(
devices::Graphics::Instance()->CreateRectangleGeometry(
Factory::Instance()->CreateRectangleGeometry(
rect,
Rect(Point{}, size_)
)
);
ThrowIfFailed(
devices::Graphics::Instance()->CreateTransformedGeometry(
Factory::Instance()->CreateTransformedGeometry(
transformed,
final_matrix_,
rect

View File

@ -19,6 +19,7 @@
// THE SOFTWARE.
#include "Text.h"
#include "Factory.h"
#include "render.h"
#include "base.hpp"
#include "logs.h"
@ -314,10 +315,8 @@ namespace easy2d
if (text_.empty())
return;
auto graphics = devices::Graphics::Instance();
ThrowIfFailed(
graphics->CreateTextFormat(
Factory::Instance()->CreateTextFormat(
text_format_,
font_,
style_
@ -326,7 +325,7 @@ namespace easy2d
Size layout_size;
ThrowIfFailed(
graphics->CreateTextLayout(
Factory::Instance()->CreateTextLayout(
text_layout_,
layout_size,
text_,

View File

@ -22,7 +22,7 @@
#include "time.h"
#include "base.hpp"
#include "logs.h"
#include "modules.h"
#include "Factory.h"
#include "Image.h"
#include "Transform.hpp"
@ -39,7 +39,6 @@ namespace easy2d
, initialized_(false)
, options_()
{
ZeroMemory(&d2d, sizeof(D2DResources));
}
GraphicsDevice::~GraphicsDevice()
@ -58,74 +57,6 @@ namespace easy2d
options_ = options;
D2D1_FACTORY_OPTIONS fact_options;
fact_options.debugLevel = debug ? D2D1_DEBUG_LEVEL_INFORMATION : D2D1_DEBUG_LEVEL_NONE;
ThrowIfFailed(
modules::DirectX().D2D1CreateFactory(
D2D1_FACTORY_TYPE_SINGLE_THREADED,
__uuidof(ID2D1Factory),
&fact_options,
reinterpret_cast<void**>(&d2d.factory)
)
);
ThrowIfFailed(
CoCreateInstance(
CLSID_WICImagingFactory,
nullptr,
CLSCTX_INPROC_SERVER,
__uuidof(IWICImagingFactory),
reinterpret_cast<void**>(&d2d.imaging_factory)
)
);
ThrowIfFailed(
modules::DirectX().DWriteCreateFactory(
DWRITE_FACTORY_TYPE_SHARED,
__uuidof(IDWriteFactory),
reinterpret_cast<IUnknown**>(&d2d.write_factory)
)
);
auto stroke_style = D2D1::StrokeStyleProperties(
D2D1_CAP_STYLE_FLAT,
D2D1_CAP_STYLE_FLAT,
D2D1_CAP_STYLE_FLAT,
D2D1_LINE_JOIN_MITER,
2.0f,
D2D1_DASH_STYLE_SOLID,
0.0f
);
ThrowIfFailed(
d2d.factory->CreateStrokeStyle(
stroke_style,
nullptr,
0,
&d2d.miter_stroke_style
)
);
stroke_style.lineJoin = D2D1_LINE_JOIN_BEVEL;
ThrowIfFailed(
d2d.factory->CreateStrokeStyle(
stroke_style,
nullptr,
0,
&d2d.bevel_stroke_style
)
);
stroke_style.lineJoin = D2D1_LINE_JOIN_ROUND;
ThrowIfFailed(
d2d.factory->CreateStrokeStyle(
stroke_style,
nullptr,
0,
&d2d.round_stroke_style
)
);
CreateDeviceResources(hwnd);
initialized_ = true;
@ -135,12 +66,12 @@ namespace easy2d
{
CreateDeviceResources(hwnd);
window_occluded_ = !!(d2d.render_target->CheckWindowState() & D2D1_WINDOW_STATE_OCCLUDED);
window_occluded_ = !!(render_target->CheckWindowState() & D2D1_WINDOW_STATE_OCCLUDED);
if (!window_occluded_)
{
d2d.render_target->BeginDraw();
d2d.render_target->Clear(clear_color_);
render_target->BeginDraw();
render_target->Clear(clear_color_);
}
}
@ -148,7 +79,7 @@ namespace easy2d
{
if (!window_occluded_)
{
HRESULT hr = d2d.render_target->EndDraw();
HRESULT hr = render_target->EndDraw();
if (hr == D2DERR_RECREATE_TARGET)
{
@ -158,9 +89,9 @@ namespace easy2d
fps_text_format_ = nullptr;
fps_text_layout_ = nullptr;
d2d.text_renderer = nullptr;
d2d.solid_brush = nullptr;
d2d.render_target = nullptr;
text_renderer = nullptr;
solid_brush = nullptr;
render_target = nullptr;
}
ThrowIfFailed(hr);
@ -172,247 +103,22 @@ namespace easy2d
bitmap_cache_.clear();
}
HRESULT GraphicsDevice::CreateRectangleGeometry(cpRectangleGeometry & geo, Rect const& rect) const
{
if (!d2d.factory)
return E_UNEXPECTED;
cpRectangleGeometry rectangle;
HRESULT hr = d2d.factory->CreateRectangleGeometry(
rect,
&rectangle
);
if (SUCCEEDED(hr))
geo = rectangle;
return hr;
}
HRESULT GraphicsDevice::CreateRoundedRectangleGeometry(cpRoundedRectangleGeometry & geo, Rect const & rect, float radius_x, float radius_y) const
{
if (!d2d.factory)
return E_UNEXPECTED;
cpRoundedRectangleGeometry rounded_rect;
HRESULT hr = d2d.factory->CreateRoundedRectangleGeometry(
D2D1::RoundedRect(
rect,
radius_x,
radius_y
),
&rounded_rect
);
if (SUCCEEDED(hr))
geo = rounded_rect;
return hr;
}
HRESULT GraphicsDevice::CreateEllipseGeometry(cpEllipseGeometry & geo, Point const & center, float radius_x, float radius_y) const
{
if (!d2d.factory)
return E_UNEXPECTED;
cpEllipseGeometry ellipse;
HRESULT hr = d2d.factory->CreateEllipseGeometry(
D2D1::Ellipse(
center,
radius_x,
radius_y
),
&ellipse
);
if (SUCCEEDED(hr))
geo = ellipse;
return hr;
}
HRESULT GraphicsDevice::CreateTransformedGeometry(
cpTransformedGeometry& transformed,
math::Matrix const& matrix,
cpGeometry const& geo
) const
{
if (!d2d.factory)
return E_UNEXPECTED;
cpTransformedGeometry transformed_tmp;
HRESULT hr = d2d.factory->CreateTransformedGeometry(
geo.Get(),
ConvertToD2DMatrix(matrix),
&transformed_tmp
);
if (SUCCEEDED(hr))
{
transformed = transformed_tmp;
}
return hr;
}
HRESULT GraphicsDevice::CreatePathGeometry(cpPathGeometry & geometry) const
{
if (!d2d.factory)
return E_UNEXPECTED;
return d2d.factory->CreatePathGeometry(&geometry);
}
HRESULT GraphicsDevice::CreateTextFormat(cpTextFormat & text_format, Font const & font, TextStyle const & text_style) const
{
if (!d2d.write_factory)
return E_UNEXPECTED;
cpTextFormat text_format_tmp;
HRESULT hr = d2d.write_factory->CreateTextFormat(
font.family.c_str(),
nullptr,
DWRITE_FONT_WEIGHT(font.weight),
font.italic ? DWRITE_FONT_STYLE_ITALIC : DWRITE_FONT_STYLE_NORMAL,
DWRITE_FONT_STRETCH_NORMAL,
font.size,
L"",
&text_format_tmp
);
if (SUCCEEDED(hr))
{
if (text_style.line_spacing == 0.f)
{
text_format_tmp->SetLineSpacing(DWRITE_LINE_SPACING_METHOD_DEFAULT, 0, 0);
}
else
{
text_format_tmp->SetLineSpacing(
DWRITE_LINE_SPACING_METHOD_UNIFORM,
text_style.line_spacing,
text_style.line_spacing * 0.8f
);
}
text_format_tmp->SetTextAlignment(DWRITE_TEXT_ALIGNMENT(text_style.alignment));
text_format_tmp->SetWordWrapping(text_style.wrap ? DWRITE_WORD_WRAPPING_WRAP : DWRITE_WORD_WRAPPING_NO_WRAP);
text_format = text_format_tmp;
}
return hr;
}
HRESULT GraphicsDevice::CreateTextLayout(cpTextLayout & text_layout, Size& layout_size, String const & text, cpTextFormat const& text_format, TextStyle const & text_style) const
{
if (!d2d.write_factory)
return E_UNEXPECTED;
text_layout = nullptr;
HRESULT hr;
cpTextLayout text_layout_tmp;
UINT32 length = static_cast<UINT32>(text.length());
if (text_style.wrap)
{
hr = d2d.write_factory->CreateTextLayout(
text.c_str(),
length,
text_format.Get(),
text_style.wrap_width,
0,
&text_layout_tmp
);
}
else
{
hr = d2d.write_factory->CreateTextLayout(
text.c_str(),
length,
text_format.Get(),
0,
0,
&text_layout_tmp
);
DWRITE_TEXT_METRICS metrics;
text_layout_tmp->GetMetrics(&metrics);
if (SUCCEEDED(hr))
{
text_layout_tmp = nullptr;
hr = d2d.write_factory->CreateTextLayout(
text.c_str(),
length,
text_format.Get(),
metrics.width,
0,
&text_layout_tmp
);
}
}
if (SUCCEEDED(hr))
{
DWRITE_TEXT_METRICS metrics;
text_layout_tmp->GetMetrics(&metrics);
if (text_style.wrap)
{
layout_size = Size(metrics.layoutWidth, metrics.height);
}
else
{
layout_size = Size(metrics.width, metrics.height);
}
DWRITE_TEXT_RANGE range = { 0, length };
if (text_style.underline)
{
text_layout_tmp->SetUnderline(true, range);
}
if (text_style.strikethrough)
{
text_layout_tmp->SetStrikethrough(true, range);
}
text_layout = text_layout_tmp;
}
return hr;
}
HRESULT GraphicsDevice::CreateTextRenderer(
cpTextRenderer& text_renderer,
cpRenderTarget const& render_target,
cpSolidColorBrush const& brush
)
{
if (!d2d.factory)
return E_UNEXPECTED;
cpTextRenderer text_renderer_tmp;
HRESULT hr = ITextRenderer::Create(
&text_renderer_tmp,
d2d.factory.Get(),
render_target.Get(),
brush.Get()
);
if (SUCCEEDED(hr))
text_renderer = text_renderer_tmp;
return hr;
}
HRESULT GraphicsDevice::CreateLayer(cpLayer& layer)
{
if (!d2d.render_target)
if (!render_target)
return E_UNEXPECTED;
layer = nullptr;
return d2d.render_target->CreateLayer(&layer);
return render_target->CreateLayer(&layer);
}
HRESULT GraphicsDevice::CreateSolidColorBrush(cpSolidColorBrush & brush) const
{
if (!d2d.render_target)
if (!render_target)
return E_UNEXPECTED;
brush = nullptr;
return d2d.render_target->CreateSolidColorBrush(
return render_target->CreateSolidColorBrush(
D2D1::ColorF(D2D1::ColorF::White),
&brush
);
@ -425,43 +131,44 @@ namespace easy2d
StrokeStyle stroke
)
{
if (!d2d.solid_brush ||
!d2d.render_target)
if (!solid_brush ||
!render_target)
return E_UNEXPECTED;
if (window_occluded_)
return S_OK;
d2d.solid_brush->SetColor(stroke_color);
d2d.render_target->DrawGeometry(
solid_brush->SetColor(stroke_color);
auto stroke_style = Factory::Instance()->GetStrokeStyle(stroke);
render_target->DrawGeometry(
geometry.Get(),
d2d.solid_brush.Get(),
solid_brush.Get(),
stroke_width,
GetStrokeStyle(stroke).Get()
stroke_style.Get()
);
return S_OK;
}
HRESULT GraphicsDevice::FillGeometry(cpGeometry const & geometry, const Color & fill_color)
{
if (!d2d.solid_brush ||
!d2d.render_target)
if (!solid_brush ||
!render_target)
return E_UNEXPECTED;
if (window_occluded_)
return S_OK;
d2d.solid_brush->SetColor(fill_color);
d2d.render_target->FillGeometry(
solid_brush->SetColor(fill_color);
render_target->FillGeometry(
geometry.Get(),
d2d.solid_brush.Get()
solid_brush.Get()
);
return S_OK;
}
HRESULT GraphicsDevice::DrawImage(spImage const & image)
{
if (!d2d.render_target)
if (!render_target)
return E_UNEXPECTED;
if (!image->GetBitmap())
@ -470,7 +177,7 @@ namespace easy2d
if (window_occluded_)
return S_OK;
d2d.render_target->DrawBitmap(
render_target->DrawBitmap(
image->GetBitmap().Get(),
D2D1::RectF(0.f, 0.f, image->GetWidth(), image->GetHeight()),
opacity_,
@ -480,28 +187,11 @@ namespace easy2d
return S_OK;
}
cpStrokeStyle const& GraphicsDevice::GetStrokeStyle(StrokeStyle stroke) const
{
switch (stroke)
{
case StrokeStyle::Miter:
return d2d.miter_stroke_style;
break;
case StrokeStyle::Bevel:
return d2d.bevel_stroke_style;
break;
case StrokeStyle::Round:
return d2d.round_stroke_style;
break;
}
return d2d.miter_stroke_style;
}
HRESULT GraphicsDevice::DrawBitmap(
cpBitmap const& bitmap
)
{
if (!d2d.render_target)
if (!render_target)
return E_UNEXPECTED;
if (window_occluded_)
@ -509,7 +199,7 @@ namespace easy2d
// Do not crop bitmap
auto rect = D2D1::RectF(0.f, 0.f, bitmap->GetSize().width, bitmap->GetSize().height);
d2d.render_target->DrawBitmap(
render_target->DrawBitmap(
bitmap.Get(),
rect,
opacity_,
@ -521,25 +211,25 @@ namespace easy2d
HRESULT GraphicsDevice::DrawTextLayout(cpTextLayout const& text_layout)
{
if (!d2d.text_renderer)
if (!text_renderer)
return E_UNEXPECTED;
if (window_occluded_)
return S_OK;
return text_layout->Draw(nullptr, d2d.text_renderer.Get(), 0, 0);
return text_layout->Draw(nullptr, text_renderer.Get(), 0, 0);
}
HRESULT GraphicsDevice::PushClip(const math::Matrix & clip_matrix, const Size & clip_size)
{
if (!d2d.render_target)
if (!render_target)
return E_UNEXPECTED;
if (window_occluded_)
return S_OK;
d2d.render_target->SetTransform(ConvertToD2DMatrix(clip_matrix));
d2d.render_target->PushAxisAlignedClip(
render_target->SetTransform(ConvertToD2DMatrix(clip_matrix));
render_target->PushAxisAlignedClip(
D2D1::RectF(0, 0, clip_size.width, clip_size.height),
D2D1_ANTIALIAS_MODE_PER_PRIMITIVE
);
@ -548,33 +238,33 @@ namespace easy2d
HRESULT GraphicsDevice::PopClip()
{
if (!d2d.render_target)
if (!render_target)
return E_UNEXPECTED;
if (window_occluded_)
return S_OK;
d2d.render_target->PopAxisAlignedClip();
render_target->PopAxisAlignedClip();
return S_OK;
}
HRESULT GraphicsDevice::PushLayer(cpLayer const& layer, LayerProperties const& properties)
{
if (!d2d.render_target ||
!d2d.solid_brush)
if (!render_target ||
!solid_brush)
return E_UNEXPECTED;
if (window_occluded_)
return S_OK;
d2d.render_target->PushLayer(
render_target->PushLayer(
D2D1::LayerParameters(
properties.area,
nullptr,
D2D1_ANTIALIAS_MODE_PER_PRIMITIVE,
D2D1::Matrix3x2F::Identity(),
properties.opacity,
d2d.solid_brush.Get(),
solid_brush.Get(),
D2D1_LAYER_OPTIONS_NONE
),
layer.Get()
@ -584,22 +274,22 @@ namespace easy2d
HRESULT GraphicsDevice::PopLayer()
{
if (!d2d.render_target)
if (!render_target)
return E_UNEXPECTED;
if (window_occluded_)
return S_OK;
d2d.render_target->PopLayer();
render_target->PopLayer();
return S_OK;
}
HRESULT GraphicsDevice::GetSize(Size & size)
{
if (!d2d.render_target)
if (!render_target)
return E_UNEXPECTED;
auto rtsize = d2d.render_target->GetSize();
auto rtsize = render_target->GetSize();
size.width = rtsize.width;
size.height = rtsize.height;
return S_OK;
@ -607,8 +297,7 @@ namespace easy2d
HRESULT GraphicsDevice::CreateBitmapFromFile(cpBitmap& bitmap, String const& file_path)
{
if (d2d.imaging_factory == nullptr ||
d2d.render_target == nullptr)
if (render_target == nullptr)
{
return E_UNEXPECTED;
}
@ -620,73 +309,24 @@ namespace easy2d
return S_OK;
}
IWICBitmapDecoder* decoder = nullptr;
IWICBitmapFrameDecode* source = nullptr;
IWICStream* stream = nullptr;
IWICFormatConverter* converter = nullptr;
// 创建解码器
HRESULT hr = d2d.imaging_factory->CreateDecoderFromFilename(
file_path.c_str(),
nullptr,
GENERIC_READ,
WICDecodeMetadataCacheOnLoad,
&decoder
cpBitmap bitmap_tmp;
HRESULT hr = Factory::Instance()->CreateBitmapFromFile(
bitmap,
render_target,
file_path
);
if (SUCCEEDED(hr))
{
// 创建初始化框架
hr = decoder->GetFrame(0, &source);
}
if (SUCCEEDED(hr))
{
// 创建图片格式转换器
hr = d2d.imaging_factory->CreateFormatConverter(&converter);
}
if (SUCCEEDED(hr))
{
// 图片格式转换成 32bppPBGRA
hr = converter->Initialize(
source,
GUID_WICPixelFormat32bppPBGRA,
WICBitmapDitherTypeNone,
nullptr,
0.f,
WICBitmapPaletteTypeMedianCut
);
}
if (SUCCEEDED(hr))
{
// 从 WIC 位图创建一个 Direct2D 位图
bitmap = nullptr;
hr = d2d.render_target->CreateBitmapFromWicBitmap(
converter,
nullptr,
&bitmap
);
}
if (SUCCEEDED(hr))
{
bitmap_cache_.insert(std::make_pair(hash_code, bitmap));
}
SafeRelease(decoder);
SafeRelease(source);
SafeRelease(stream);
SafeRelease(converter);
return hr;
}
HRESULT GraphicsDevice::CreateBitmapFromResource(cpBitmap& bitmap, Resource const& res)
{
if (d2d.imaging_factory == nullptr ||
d2d.render_target == nullptr)
if (render_target == nullptr)
{
return E_UNEXPECTED;
}
@ -698,126 +338,54 @@ namespace easy2d
return S_OK;
}
HRESULT hr;
HINSTANCE hinstance = GetModuleHandle(nullptr);
IWICBitmapDecoder* decoder = nullptr;
IWICBitmapFrameDecode* source = nullptr;
IWICStream* stream = nullptr;
IWICFormatConverter* converter = nullptr;
ResourceData buffer;
// 加载资源
hr = res.Load(&buffer) ? S_OK : E_FAIL;
if (SUCCEEDED(hr))
{
// 创建 WIC 流
hr = d2d.imaging_factory->CreateStream(&stream);
}
if (SUCCEEDED(hr))
{
// 初始化流
hr = stream->InitializeFromMemory(
static_cast<WICInProcPointer>(buffer.buffer),
buffer.buffer_size
);
}
if (SUCCEEDED(hr))
{
// 创建流的解码器
hr = d2d.imaging_factory->CreateDecoderFromStream(
stream,
nullptr,
WICDecodeMetadataCacheOnLoad,
&decoder
);
}
if (SUCCEEDED(hr))
{
// 创建初始化框架
hr = decoder->GetFrame(0, &source);
}
if (SUCCEEDED(hr))
{
// 创建图片格式转换器
hr = d2d.imaging_factory->CreateFormatConverter(&converter);
}
if (SUCCEEDED(hr))
{
// 图片格式转换成 32bppPBGRA
hr = converter->Initialize(
source,
GUID_WICPixelFormat32bppPBGRA,
WICBitmapDitherTypeNone,
nullptr,
0.f,
WICBitmapPaletteTypeMedianCut
);
}
if (SUCCEEDED(hr))
{
// 从 WIC 位图创建一个 Direct2D 位图
hr = d2d.render_target->CreateBitmapFromWicBitmap(
converter,
nullptr,
&bitmap
);
}
HRESULT hr = Factory::Instance()->CreateBitmapFromResource(
bitmap,
render_target,
res
);
if (SUCCEEDED(hr))
{
bitmap_cache_.insert(std::make_pair(hash_code, bitmap));
}
SafeRelease(decoder);
SafeRelease(source);
SafeRelease(stream);
SafeRelease(converter);
return hr;
}
HRESULT GraphicsDevice::CreateBitmapRenderTarget(cpBitmapRenderTarget & brt)
{
if (!d2d.render_target)
if (!render_target)
return E_UNEXPECTED;
brt = nullptr;
return d2d.render_target->CreateCompatibleRenderTarget(&brt);
return render_target->CreateCompatibleRenderTarget(&brt);
}
HRESULT GraphicsDevice::Resize(UINT32 width, UINT32 height)
{
if (!d2d.render_target)
if (!render_target)
return E_UNEXPECTED;
d2d.render_target->Resize(D2D1::SizeU(width, height));
render_target->Resize(D2D1::SizeU(width, height));
return S_OK;
}
HRESULT GraphicsDevice::SetTransform(const math::Matrix & matrix)
{
if (!d2d.render_target)
if (!render_target)
return E_UNEXPECTED;
d2d.render_target->SetTransform(ConvertToD2DMatrix(matrix));
render_target->SetTransform(ConvertToD2DMatrix(matrix));
return S_OK;
}
HRESULT GraphicsDevice::SetOpacity(float opacity)
{
if (!d2d.render_target)
if (!render_target)
return E_UNEXPECTED;
opacity_ = opacity;
d2d.solid_brush->SetOpacity(opacity);
solid_brush->SetOpacity(opacity);
return S_OK;
}
@ -829,15 +397,16 @@ namespace easy2d
StrokeStyle outline_stroke
)
{
if (!d2d.text_renderer)
if (!text_renderer)
return E_UNEXPECTED;
d2d.text_renderer->SetTextStyle(
auto stroke_style = Factory::Instance()->GetStrokeStyle(outline_stroke);
text_renderer->SetTextStyle(
color,
has_outline,
outline_color,
outline_width,
GetStrokeStyle(outline_stroke).Get()
stroke_style.Get()
);
return S_OK;
}
@ -849,7 +418,7 @@ namespace easy2d
void GraphicsDevice::CreateDeviceResources(HWND hwnd)
{
if (!d2d.render_target)
if (!render_target)
{
RECT rc;
::GetClientRect(hwnd, &rc);
@ -862,18 +431,18 @@ namespace easy2d
// 创建设备相关资源。这些资源应在 Direct2D 设备消失时重建
// 创建一个 Direct2D 渲染目标
ThrowIfFailed(
d2d.factory->CreateHwndRenderTarget(
Factory::Instance()->CreateHwndRenderTarget(
render_target,
D2D1::RenderTargetProperties(),
D2D1::HwndRenderTargetProperties(
hwnd,
size,
options_.vsync ? D2D1_PRESENT_OPTIONS_NONE : D2D1_PRESENT_OPTIONS_IMMEDIATELY
),
&d2d.render_target
)
)
);
d2d.render_target->SetAntialiasMode(
render_target->SetAntialiasMode(
options_.antialias ? D2D1_ANTIALIAS_MODE_PER_PRIMITIVE : D2D1_ANTIALIAS_MODE_ALIASED
);
@ -895,27 +464,26 @@ namespace easy2d
default:
break;
}
d2d.render_target->SetTextAntialiasMode(mode);
render_target->SetTextAntialiasMode(mode);
}
if (!d2d.solid_brush)
if (!solid_brush)
{
ThrowIfFailed(
d2d.render_target->CreateSolidColorBrush(
render_target->CreateSolidColorBrush(
D2D1::ColorF(D2D1::ColorF::White),
&d2d.solid_brush
&solid_brush
)
);
}
if (!d2d.text_renderer)
if (!text_renderer)
{
ThrowIfFailed(
ITextRenderer::Create(
&d2d.text_renderer,
d2d.factory.Get(),
d2d.render_target.Get(),
d2d.solid_brush.Get()
Factory::Instance()->CreateTextRenderer(
text_renderer,
render_target,
solid_brush
)
);
}

View File

@ -53,20 +53,6 @@ namespace easy2d
namespace devices
{
struct D2DResources
{
cpFactory factory;
cpImagingFactory imaging_factory;
cpWriteFactory write_factory;
cpTextRenderer text_renderer;
cpSolidColorBrush solid_brush;
cpHwndRenderTarget render_target;
cpStrokeStyle miter_stroke_style;
cpStrokeStyle bevel_stroke_style;
cpStrokeStyle round_stroke_style;
};
class GraphicsDevice
: protected Noncopyable
{
@ -88,55 +74,6 @@ namespace easy2d
void CreateDeviceResources(HWND hwnd);
HRESULT CreateRectangleGeometry(
cpRectangleGeometry& geo,
Rect const& rect
) const;
HRESULT CreateRoundedRectangleGeometry(
cpRoundedRectangleGeometry& geo,
Rect const& rect,
float radius_x,
float radius_y
) const;
HRESULT CreateEllipseGeometry(
cpEllipseGeometry& geo,
Point const& center,
float radius_x,
float radius_y
) const;
HRESULT CreateTransformedGeometry(
cpTransformedGeometry& transformed,
math::Matrix const& matrix,
cpGeometry const& geo
) const;
HRESULT CreatePathGeometry(
cpPathGeometry& geometry
) const;
HRESULT CreateTextFormat(
cpTextFormat& text_format,
Font const& font,
TextStyle const& text_style
) const;
HRESULT CreateTextLayout(
cpTextLayout& text_layout,
Size& layout_size,
String const& text,
cpTextFormat const& text_format,
TextStyle const& text_style
) const;
HRESULT CreateTextRenderer(
cpTextRenderer& text_renderer,
cpRenderTarget const& render_target,
cpSolidColorBrush const& brush
);
HRESULT CreateLayer(
cpLayer& layer
);
@ -159,10 +96,6 @@ namespace easy2d
cpBitmapRenderTarget& brt
);
cpStrokeStyle const& GetStrokeStyle(
StrokeStyle stroke
) const;
HRESULT SetTransform(
const math::Matrix& matrix
);
@ -238,7 +171,9 @@ namespace easy2d
bool window_occluded_;
float opacity_;
GraphicsOptions options_;
D2DResources d2d;
cpTextRenderer text_renderer;
cpSolidColorBrush solid_brush;
cpHwndRenderTarget render_target;
D2D1_COLOR_F clear_color_;
cpTextFormat fps_text_format_;
cpTextLayout fps_text_layout_;

View File

@ -78,6 +78,7 @@
#include "base/KeyEvent.h"
#include "base/MouseEvent.h"
#include "base/Factory.h"
#include "base/Game.h"

View File

@ -32,6 +32,7 @@
<ClInclude Include="..\..\core\base\d2dres.hpp" />
<ClInclude Include="..\..\core\base\Debuger.h" />
<ClInclude Include="..\..\core\base\Delay.h" />
<ClInclude Include="..\..\core\base\Factory.h" />
<ClInclude Include="..\..\core\base\Font.hpp" />
<ClInclude Include="..\..\core\base\Frames.h" />
<ClInclude Include="..\..\core\base\Game.h" />
@ -95,6 +96,7 @@
<ClCompile Include="..\..\core\base\Color.cpp" />
<ClCompile Include="..\..\core\base\Debuger.cpp" />
<ClCompile Include="..\..\core\base\Delay.cpp" />
<ClCompile Include="..\..\core\base\Factory.cpp" />
<ClCompile Include="..\..\core\base\Frames.cpp" />
<ClCompile Include="..\..\core\base\Game.cpp" />
<ClCompile Include="..\..\core\base\Geometry.cpp" />

View File

@ -194,6 +194,9 @@
<ClInclude Include="..\..\core\math\constants.hpp">
<Filter>math</Filter>
</ClInclude>
<ClInclude Include="..\..\core\base\Factory.h">
<Filter>base</Filter>
</ClInclude>
</ItemGroup>
<ItemGroup>
<Filter Include="base">
@ -342,5 +345,8 @@
<ClCompile Include="..\..\core\base\Frames.cpp">
<Filter>base</Filter>
</ClCompile>
<ClCompile Include="..\..\core\base\Factory.cpp">
<Filter>base</Filter>
</ClCompile>
</ItemGroup>
</Project>

View File

@ -32,6 +32,7 @@
<ClInclude Include="..\..\core\base\d2dres.hpp" />
<ClInclude Include="..\..\core\base\Debuger.h" />
<ClInclude Include="..\..\core\base\Delay.h" />
<ClInclude Include="..\..\core\base\Factory.h" />
<ClInclude Include="..\..\core\base\Font.hpp" />
<ClInclude Include="..\..\core\base\Frames.h" />
<ClInclude Include="..\..\core\base\Game.h" />
@ -95,6 +96,7 @@
<ClCompile Include="..\..\core\base\Color.cpp" />
<ClCompile Include="..\..\core\base\Debuger.cpp" />
<ClCompile Include="..\..\core\base\Delay.cpp" />
<ClCompile Include="..\..\core\base\Factory.cpp" />
<ClCompile Include="..\..\core\base\Frames.cpp" />
<ClCompile Include="..\..\core\base\Game.cpp" />
<ClCompile Include="..\..\core\base\Geometry.cpp" />

View File

@ -194,6 +194,9 @@
<ClInclude Include="..\..\core\math\constants.hpp">
<Filter>math</Filter>
</ClInclude>
<ClInclude Include="..\..\core\base\Factory.h">
<Filter>base</Filter>
</ClInclude>
</ItemGroup>
<ItemGroup>
<Filter Include="base">
@ -342,5 +345,8 @@
<ClCompile Include="..\..\core\base\Frames.cpp">
<Filter>base</Filter>
</ClCompile>
<ClCompile Include="..\..\core\base\Factory.cpp">
<Filter>base</Filter>
</ClCompile>
</ItemGroup>
</Project>

View File

@ -32,6 +32,7 @@
<ClInclude Include="..\..\core\base\d2dres.hpp" />
<ClInclude Include="..\..\core\base\Debuger.h" />
<ClInclude Include="..\..\core\base\Delay.h" />
<ClInclude Include="..\..\core\base\Factory.h" />
<ClInclude Include="..\..\core\base\Font.hpp" />
<ClInclude Include="..\..\core\base\Frames.h" />
<ClInclude Include="..\..\core\base\Game.h" />
@ -95,6 +96,7 @@
<ClCompile Include="..\..\core\base\Color.cpp" />
<ClCompile Include="..\..\core\base\Debuger.cpp" />
<ClCompile Include="..\..\core\base\Delay.cpp" />
<ClCompile Include="..\..\core\base\Factory.cpp" />
<ClCompile Include="..\..\core\base\Frames.cpp" />
<ClCompile Include="..\..\core\base\Game.cpp" />
<ClCompile Include="..\..\core\base\Geometry.cpp" />

View File

@ -194,6 +194,9 @@
<ClInclude Include="..\..\core\math\constants.hpp">
<Filter>math</Filter>
</ClInclude>
<ClInclude Include="..\..\core\base\Factory.h">
<Filter>base</Filter>
</ClInclude>
</ItemGroup>
<ItemGroup>
<Filter Include="base">
@ -342,5 +345,8 @@
<ClCompile Include="..\..\core\base\Frames.cpp">
<Filter>base</Filter>
</ClCompile>
<ClCompile Include="..\..\core\base\Factory.cpp">
<Filter>base</Filter>
</ClCompile>
</ItemGroup>
</Project>