aboutsummaryrefslogtreecommitdiff
diff options
context:
space:
mode:
-rw-r--r--include/cru/platform/graphics/NullPainter.hpp4
-rw-r--r--include/cru/platform/graphics/Painter.hpp2
-rw-r--r--include/cru/win/graphics/direct/Factory.hpp7
-rw-r--r--include/cru/win/graphics/direct/Image.hpp25
-rw-r--r--include/cru/win/graphics/direct/ImageFactory.hpp27
-rw-r--r--include/cru/win/graphics/direct/Painter.hpp2
-rw-r--r--src/win/graphics/direct/CMakeLists.txt2
-rw-r--r--src/win/graphics/direct/Factory.cpp7
-rw-r--r--src/win/graphics/direct/Image.cpp15
-rw-r--r--src/win/graphics/direct/ImageFactory.cpp52
-rw-r--r--src/win/graphics/direct/Painter.cpp11
11 files changed, 151 insertions, 3 deletions
diff --git a/include/cru/platform/graphics/NullPainter.hpp b/include/cru/platform/graphics/NullPainter.hpp
index a47546b6..54c610c1 100644
--- a/include/cru/platform/graphics/NullPainter.hpp
+++ b/include/cru/platform/graphics/NullPainter.hpp
@@ -66,8 +66,8 @@ class CRU_PLATFORM_GRAPHICS_API NullPainter : public Object,
CRU_UNUSED(brush)
}
- void DrawImage(const Rect& rect, IImage* image) override {
- CRU_UNUSED(rect)
+ void DrawImage(const Point& offset, IImage* image) override {
+ CRU_UNUSED(offset)
CRU_UNUSED(image)
}
diff --git a/include/cru/platform/graphics/Painter.hpp b/include/cru/platform/graphics/Painter.hpp
index eb5bf8e1..171e6260 100644
--- a/include/cru/platform/graphics/Painter.hpp
+++ b/include/cru/platform/graphics/Painter.hpp
@@ -27,7 +27,7 @@ struct CRU_PLATFORM_GRAPHICS_API IPainter : virtual IPlatformResource {
virtual void DrawText(const Point& offset, ITextLayout* text_layout,
IBrush* brush) = 0;
- virtual void DrawImage(const Rect& rect, IImage* image) = 0;
+ virtual void DrawImage(const Point& offset, IImage* image) = 0;
virtual void PushLayer(const Rect& bounds) = 0;
diff --git a/include/cru/win/graphics/direct/Factory.hpp b/include/cru/win/graphics/direct/Factory.hpp
index 932d302b..ffa8c764 100644
--- a/include/cru/win/graphics/direct/Factory.hpp
+++ b/include/cru/win/graphics/direct/Factory.hpp
@@ -1,6 +1,9 @@
#pragma once
#include "Resource.hpp"
+#include "ImageFactory.hpp"
+
+#include "cru/platform/graphics/Base.hpp"
#include "cru/platform/graphics/Factory.hpp"
namespace cru::platform::graphics::win::direct {
@@ -46,6 +49,8 @@ class CRU_WIN_GRAPHICS_DIRECT_API DirectGraphicsFactory
std::unique_ptr<ITextLayout> CreateTextLayout(std::shared_ptr<IFont> font,
String text) override;
+ IImageFactory* GetImageFactory() override;
+
private:
Microsoft::WRL::ComPtr<ID3D11Device> d3d11_device_;
// ID2D1Factory1 is a interface only available in Windows 8 and Windows 7 with
@@ -56,5 +61,7 @@ class CRU_WIN_GRAPHICS_DIRECT_API DirectGraphicsFactory
Microsoft::WRL::ComPtr<IDXGIFactory2> dxgi_factory_;
Microsoft::WRL::ComPtr<IDWriteFactory> dwrite_factory_;
Microsoft::WRL::ComPtr<IDWriteFontCollection> dwrite_system_font_collection_;
+
+ std::unique_ptr<WinImageFactory> image_factory_;
};
} // namespace cru::platform::graphics::win::direct
diff --git a/include/cru/win/graphics/direct/Image.hpp b/include/cru/win/graphics/direct/Image.hpp
new file mode 100644
index 00000000..33d848bd
--- /dev/null
+++ b/include/cru/win/graphics/direct/Image.hpp
@@ -0,0 +1,25 @@
+#pragma once
+#include "Resource.hpp"
+#include "cru/platform/graphics/Image.hpp"
+
+namespace cru::platform::graphics::win::direct {
+class CRU_WIN_GRAPHICS_DIRECT_API Direct2DImage : public DirectGraphicsResource,
+ public virtual IImage {
+ public:
+ explicit Direct2DImage(DirectGraphicsFactory* graphics_factory,
+ ID2D1Image* d2d_image, bool auto_release);
+
+ CRU_DELETE_COPY(Direct2DImage)
+ CRU_DELETE_MOVE(Direct2DImage)
+
+ ~Direct2DImage() override;
+
+ public:
+ ID2D1Image* GetD2DImage() const { return d2d_image_; }
+
+ private:
+ ID2D1Image* d2d_image_;
+ bool auto_release_;
+};
+
+} // namespace cru::platform::graphics::win::direct
diff --git a/include/cru/win/graphics/direct/ImageFactory.hpp b/include/cru/win/graphics/direct/ImageFactory.hpp
new file mode 100644
index 00000000..fa450039
--- /dev/null
+++ b/include/cru/win/graphics/direct/ImageFactory.hpp
@@ -0,0 +1,27 @@
+#pragma once
+
+#include "Resource.hpp"
+#include "cru/platform/graphics/Image.hpp"
+#include "cru/platform/graphics/ImageFactory.hpp"
+
+namespace cru::platform::graphics::win::direct {
+class CRU_WIN_GRAPHICS_DIRECT_API WinImageFactory
+ : public DirectGraphicsResource,
+ public virtual IImageFactory {
+ public:
+ explicit WinImageFactory(DirectGraphicsFactory* graphics_factory);
+
+ CRU_DELETE_COPY(WinImageFactory)
+ CRU_DELETE_MOVE(WinImageFactory)
+
+ ~WinImageFactory() override;
+
+ public:
+ std::unique_ptr<IImage> DecodeFromStream(io::Stream* stream) override;
+
+ private:
+ DirectGraphicsFactory* graphics_factory_;
+
+ Microsoft::WRL::ComPtr<IWICImagingFactory> wic_imaging_factory_;
+};
+} // namespace cru::platform::graphics::win::direct
diff --git a/include/cru/win/graphics/direct/Painter.hpp b/include/cru/win/graphics/direct/Painter.hpp
index 81d102f1..11fb5619 100644
--- a/include/cru/win/graphics/direct/Painter.hpp
+++ b/include/cru/win/graphics/direct/Painter.hpp
@@ -44,6 +44,8 @@ class CRU_WIN_GRAPHICS_DIRECT_API D2DPainter
void DrawText(const Point& offset, ITextLayout* text_layout,
IBrush* brush) override;
+ void DrawImage(const Point& offset, IImage* image) override;
+
void PushLayer(const Rect& bounds) override;
void PopLayer() override;
diff --git a/src/win/graphics/direct/CMakeLists.txt b/src/win/graphics/direct/CMakeLists.txt
index 84c2af61..39f9802a 100644
--- a/src/win/graphics/direct/CMakeLists.txt
+++ b/src/win/graphics/direct/CMakeLists.txt
@@ -2,6 +2,8 @@ add_library(cru_win_graphics_direct SHARED
Brush.cpp
Font.cpp
Geometry.cpp
+ Image.cpp
+ ImageFactory.cpp
Factory.cpp
Painter.cpp
Resource.cpp
diff --git a/src/win/graphics/direct/Factory.cpp b/src/win/graphics/direct/Factory.cpp
index 4c4f1a9a..86ca01b9 100644
--- a/src/win/graphics/direct/Factory.cpp
+++ b/src/win/graphics/direct/Factory.cpp
@@ -5,6 +5,7 @@
#include "cru/win/graphics/direct/Exception.hpp"
#include "cru/win/graphics/direct/Font.hpp"
#include "cru/win/graphics/direct/Geometry.hpp"
+#include "cru/win/graphics/direct/ImageFactory.hpp"
#include "cru/win/graphics/direct/TextLayout.hpp"
#include <cstdlib>
@@ -74,6 +75,8 @@ DirectGraphicsFactory::DirectGraphicsFactory() {
ThrowIfFailed(dwrite_factory_->GetSystemFontCollection(
&dwrite_system_font_collection_));
+
+ image_factory_ = std::make_unique<WinImageFactory>(this);
}
DirectGraphicsFactory::~DirectGraphicsFactory() { UninitializeCom(); }
@@ -106,4 +109,8 @@ std::unique_ptr<ITextLayout> DirectGraphicsFactory::CreateTextLayout(
return std::make_unique<DWriteTextLayout>(this, std::move(font),
std::move(text));
}
+
+IImageFactory* DirectGraphicsFactory::GetImageFactory() {
+ return image_factory_.get();
+}
} // namespace cru::platform::graphics::win::direct
diff --git a/src/win/graphics/direct/Image.cpp b/src/win/graphics/direct/Image.cpp
new file mode 100644
index 00000000..46b763be
--- /dev/null
+++ b/src/win/graphics/direct/Image.cpp
@@ -0,0 +1,15 @@
+#include "cru/win/graphics/direct/Image.hpp"
+
+namespace cru::platform::graphics::win::direct {
+Direct2DImage::Direct2DImage(DirectGraphicsFactory* graphics_factory,
+ ID2D1Image* d2d_image, bool auto_release)
+ : DirectGraphicsResource(graphics_factory),
+ d2d_image_(d2d_image),
+ auto_release_(auto_release) {}
+
+Direct2DImage::~Direct2DImage() {
+ if (auto_release_) {
+ d2d_image_->Release();
+ }
+}
+} // namespace cru::platform::graphics::win::direct
diff --git a/src/win/graphics/direct/ImageFactory.cpp b/src/win/graphics/direct/ImageFactory.cpp
new file mode 100644
index 00000000..dc43a9b9
--- /dev/null
+++ b/src/win/graphics/direct/ImageFactory.cpp
@@ -0,0 +1,52 @@
+#include "cru/win/graphics/direct/ImageFactory.hpp"
+#include "cru/win/graphics/direct/Exception.hpp"
+#include "cru/win/graphics/direct/Factory.hpp"
+#include "cru/win/graphics/direct/Image.hpp"
+
+#include <wincodec.h>
+
+namespace cru::platform::graphics::win::direct {
+WinImageFactory::WinImageFactory(DirectGraphicsFactory* graphics_factory)
+ : DirectGraphicsResource(graphics_factory) {
+ HRESULT hr =
+ CoCreateInstance(CLSID_WICImagingFactory, NULL, CLSCTX_INPROC_SERVER,
+ IID_PPV_ARGS(&wic_imaging_factory_));
+ ThrowIfFailed(hr);
+}
+
+WinImageFactory::~WinImageFactory() {}
+
+std::unique_ptr<IImage> WinImageFactory::DecodeFromStream(io::Stream* stream) {
+ // TODO: The correct way to do this is to implement a IStream wrapper.
+
+ auto buffer = stream->ReadAll();
+
+ HRESULT hr;
+
+ Microsoft::WRL::ComPtr<IWICStream> wic_stream;
+ hr = wic_imaging_factory_->CreateStream(&wic_stream);
+ ThrowIfFailed(hr);
+
+ hr = wic_stream->InitializeFromMemory(
+ reinterpret_cast<unsigned char*>(buffer.data()), buffer.size());
+ ThrowIfFailed(hr);
+
+ Microsoft::WRL::ComPtr<IWICBitmapDecoder> wic_bitmap_decoder;
+ hr = wic_imaging_factory_->CreateDecoderFromStream(
+ wic_stream.Get(), NULL, WICDecodeMetadataCacheOnDemand,
+ &wic_bitmap_decoder);
+ ThrowIfFailed(hr);
+
+ Microsoft::WRL::ComPtr<IWICBitmapFrameDecode> wic_bitmap_frame_decode;
+ hr = wic_bitmap_decoder->GetFrame(0, &wic_bitmap_frame_decode);
+ ThrowIfFailed(hr);
+
+ auto d2d_context = graphics_factory_->GetDefaultD2D1DeviceContext();
+
+ ID2D1Bitmap* d2d_image;
+ d2d_context->CreateBitmapFromWicBitmap(wic_bitmap_frame_decode.Get(), NULL,
+ &d2d_image);
+
+ return std::make_unique<Direct2DImage>(graphics_factory_, d2d_image, true);
+}
+} // namespace cru::platform::graphics::win::direct
diff --git a/src/win/graphics/direct/Painter.cpp b/src/win/graphics/direct/Painter.cpp
index 1a43d1d0..4af8a09a 100644
--- a/src/win/graphics/direct/Painter.cpp
+++ b/src/win/graphics/direct/Painter.cpp
@@ -5,6 +5,7 @@
#include "cru/win/graphics/direct/ConvertUtil.hpp"
#include "cru/win/graphics/direct/Exception.hpp"
#include "cru/win/graphics/direct/Geometry.hpp"
+#include "cru/win/graphics/direct/Image.hpp"
#include "cru/win/graphics/direct/TextLayout.hpp"
#include <type_traits>
@@ -101,6 +102,16 @@ void D2DPainter::DrawText(const Point& offset, ITextLayout* text_layout,
b->GetD2DBrushInterface());
}
+void D2DPainter::DrawImage(const Point& offset, IImage* image) {
+ CheckValidation();
+ const auto i = CheckPlatform<Direct2DImage>(image, GetPlatformId());
+
+ ID2D1DeviceContext* device_context;
+
+ render_target_->QueryInterface(&device_context);
+ device_context->DrawImage(i->GetD2DImage(), Convert(offset));
+}
+
void D2DPainter::PushLayer(const Rect& bounds) {
CheckValidation();