diff --git a/examples/DemoRunner/Builds/Android/app/CMakeLists.txt b/examples/DemoRunner/Builds/Android/app/CMakeLists.txt
index 3343e32980..f4a393d9d7 100644
--- a/examples/DemoRunner/Builds/Android/app/CMakeLists.txt
+++ b/examples/DemoRunner/Builds/Android/app/CMakeLists.txt
@@ -1983,6 +1983,7 @@ add_library( ${BINARY_NAME}
"../../../../../modules/juce_graphics/native/juce_Direct2DImageContext_windows.h"
"../../../../../modules/juce_graphics/native/juce_Direct2DMetrics_windows.cpp"
"../../../../../modules/juce_graphics/native/juce_Direct2DMetrics_windows.h"
+ "../../../../../modules/juce_graphics/native/juce_Direct2DPixelDataPage_windows.h"
"../../../../../modules/juce_graphics/native/juce_Direct2DResources_windows.cpp"
"../../../../../modules/juce_graphics/native/juce_DirectWriteTypeface_windows.cpp"
"../../../../../modules/juce_graphics/native/juce_DirectX_windows.h"
@@ -4580,6 +4581,7 @@ set_source_files_properties(
"../../../../../modules/juce_graphics/native/juce_Direct2DImageContext_windows.h"
"../../../../../modules/juce_graphics/native/juce_Direct2DMetrics_windows.cpp"
"../../../../../modules/juce_graphics/native/juce_Direct2DMetrics_windows.h"
+ "../../../../../modules/juce_graphics/native/juce_Direct2DPixelDataPage_windows.h"
"../../../../../modules/juce_graphics/native/juce_Direct2DResources_windows.cpp"
"../../../../../modules/juce_graphics/native/juce_DirectWriteTypeface_windows.cpp"
"../../../../../modules/juce_graphics/native/juce_DirectX_windows.h"
diff --git a/examples/DemoRunner/Builds/VisualStudio2019/DemoRunner_App.vcxproj b/examples/DemoRunner/Builds/VisualStudio2019/DemoRunner_App.vcxproj
index 1aff7dbe3d..fefef374fd 100644
--- a/examples/DemoRunner/Builds/VisualStudio2019/DemoRunner_App.vcxproj
+++ b/examples/DemoRunner/Builds/VisualStudio2019/DemoRunner_App.vcxproj
@@ -4372,6 +4372,7 @@
+
diff --git a/examples/DemoRunner/Builds/VisualStudio2019/DemoRunner_App.vcxproj.filters b/examples/DemoRunner/Builds/VisualStudio2019/DemoRunner_App.vcxproj.filters
index ab561f2652..ffc08de103 100644
--- a/examples/DemoRunner/Builds/VisualStudio2019/DemoRunner_App.vcxproj.filters
+++ b/examples/DemoRunner/Builds/VisualStudio2019/DemoRunner_App.vcxproj.filters
@@ -7518,6 +7518,9 @@
JUCE Modules\juce_graphics\native
+
+ JUCE Modules\juce_graphics\native
+
JUCE Modules\juce_graphics\native
diff --git a/examples/DemoRunner/Builds/VisualStudio2022/DemoRunner_App.vcxproj b/examples/DemoRunner/Builds/VisualStudio2022/DemoRunner_App.vcxproj
index fdb60d7e6b..d908cabcbb 100644
--- a/examples/DemoRunner/Builds/VisualStudio2022/DemoRunner_App.vcxproj
+++ b/examples/DemoRunner/Builds/VisualStudio2022/DemoRunner_App.vcxproj
@@ -4372,6 +4372,7 @@
+
diff --git a/examples/DemoRunner/Builds/VisualStudio2022/DemoRunner_App.vcxproj.filters b/examples/DemoRunner/Builds/VisualStudio2022/DemoRunner_App.vcxproj.filters
index 17b708163b..fffee08a62 100644
--- a/examples/DemoRunner/Builds/VisualStudio2022/DemoRunner_App.vcxproj.filters
+++ b/examples/DemoRunner/Builds/VisualStudio2022/DemoRunner_App.vcxproj.filters
@@ -7518,6 +7518,9 @@
JUCE Modules\juce_graphics\native
+
+ JUCE Modules\juce_graphics\native
+
JUCE Modules\juce_graphics\native
diff --git a/extras/AudioPerformanceTest/Builds/Android/app/CMakeLists.txt b/extras/AudioPerformanceTest/Builds/Android/app/CMakeLists.txt
index 5a91733edb..6120235666 100644
--- a/extras/AudioPerformanceTest/Builds/Android/app/CMakeLists.txt
+++ b/extras/AudioPerformanceTest/Builds/Android/app/CMakeLists.txt
@@ -1745,6 +1745,7 @@ add_library( ${BINARY_NAME}
"../../../../../modules/juce_graphics/native/juce_Direct2DImageContext_windows.h"
"../../../../../modules/juce_graphics/native/juce_Direct2DMetrics_windows.cpp"
"../../../../../modules/juce_graphics/native/juce_Direct2DMetrics_windows.h"
+ "../../../../../modules/juce_graphics/native/juce_Direct2DPixelDataPage_windows.h"
"../../../../../modules/juce_graphics/native/juce_Direct2DResources_windows.cpp"
"../../../../../modules/juce_graphics/native/juce_DirectWriteTypeface_windows.cpp"
"../../../../../modules/juce_graphics/native/juce_DirectX_windows.h"
@@ -4002,6 +4003,7 @@ set_source_files_properties(
"../../../../../modules/juce_graphics/native/juce_Direct2DImageContext_windows.h"
"../../../../../modules/juce_graphics/native/juce_Direct2DMetrics_windows.cpp"
"../../../../../modules/juce_graphics/native/juce_Direct2DMetrics_windows.h"
+ "../../../../../modules/juce_graphics/native/juce_Direct2DPixelDataPage_windows.h"
"../../../../../modules/juce_graphics/native/juce_Direct2DResources_windows.cpp"
"../../../../../modules/juce_graphics/native/juce_DirectWriteTypeface_windows.cpp"
"../../../../../modules/juce_graphics/native/juce_DirectX_windows.h"
diff --git a/extras/AudioPerformanceTest/Builds/VisualStudio2022/AudioPerformanceTest_App.vcxproj b/extras/AudioPerformanceTest/Builds/VisualStudio2022/AudioPerformanceTest_App.vcxproj
index a6c3112f5e..082fdfd5f3 100644
--- a/extras/AudioPerformanceTest/Builds/VisualStudio2022/AudioPerformanceTest_App.vcxproj
+++ b/extras/AudioPerformanceTest/Builds/VisualStudio2022/AudioPerformanceTest_App.vcxproj
@@ -3827,6 +3827,7 @@
+
diff --git a/extras/AudioPerformanceTest/Builds/VisualStudio2022/AudioPerformanceTest_App.vcxproj.filters b/extras/AudioPerformanceTest/Builds/VisualStudio2022/AudioPerformanceTest_App.vcxproj.filters
index d10888ab25..dfa71ed215 100644
--- a/extras/AudioPerformanceTest/Builds/VisualStudio2022/AudioPerformanceTest_App.vcxproj.filters
+++ b/extras/AudioPerformanceTest/Builds/VisualStudio2022/AudioPerformanceTest_App.vcxproj.filters
@@ -6528,6 +6528,9 @@
JUCE Modules\juce_graphics\native
+
+ JUCE Modules\juce_graphics\native
+
JUCE Modules\juce_graphics\native
diff --git a/extras/AudioPluginHost/Builds/Android/app/CMakeLists.txt b/extras/AudioPluginHost/Builds/Android/app/CMakeLists.txt
index e9fa4cb5bb..4fa59f56df 100644
--- a/extras/AudioPluginHost/Builds/Android/app/CMakeLists.txt
+++ b/extras/AudioPluginHost/Builds/Android/app/CMakeLists.txt
@@ -1875,6 +1875,7 @@ add_library( ${BINARY_NAME}
"../../../../../modules/juce_graphics/native/juce_Direct2DImageContext_windows.h"
"../../../../../modules/juce_graphics/native/juce_Direct2DMetrics_windows.cpp"
"../../../../../modules/juce_graphics/native/juce_Direct2DMetrics_windows.h"
+ "../../../../../modules/juce_graphics/native/juce_Direct2DPixelDataPage_windows.h"
"../../../../../modules/juce_graphics/native/juce_Direct2DResources_windows.cpp"
"../../../../../modules/juce_graphics/native/juce_DirectWriteTypeface_windows.cpp"
"../../../../../modules/juce_graphics/native/juce_DirectX_windows.h"
@@ -4285,6 +4286,7 @@ set_source_files_properties(
"../../../../../modules/juce_graphics/native/juce_Direct2DImageContext_windows.h"
"../../../../../modules/juce_graphics/native/juce_Direct2DMetrics_windows.cpp"
"../../../../../modules/juce_graphics/native/juce_Direct2DMetrics_windows.h"
+ "../../../../../modules/juce_graphics/native/juce_Direct2DPixelDataPage_windows.h"
"../../../../../modules/juce_graphics/native/juce_Direct2DResources_windows.cpp"
"../../../../../modules/juce_graphics/native/juce_DirectWriteTypeface_windows.cpp"
"../../../../../modules/juce_graphics/native/juce_DirectX_windows.h"
diff --git a/extras/AudioPluginHost/Builds/VisualStudio2019/AudioPluginHost_App.vcxproj b/extras/AudioPluginHost/Builds/VisualStudio2019/AudioPluginHost_App.vcxproj
index bcbf0b82f1..a5689f1b24 100644
--- a/extras/AudioPluginHost/Builds/VisualStudio2019/AudioPluginHost_App.vcxproj
+++ b/extras/AudioPluginHost/Builds/VisualStudio2019/AudioPluginHost_App.vcxproj
@@ -4060,6 +4060,7 @@
+
diff --git a/extras/AudioPluginHost/Builds/VisualStudio2019/AudioPluginHost_App.vcxproj.filters b/extras/AudioPluginHost/Builds/VisualStudio2019/AudioPluginHost_App.vcxproj.filters
index 948932a1b1..a45229306f 100644
--- a/extras/AudioPluginHost/Builds/VisualStudio2019/AudioPluginHost_App.vcxproj.filters
+++ b/extras/AudioPluginHost/Builds/VisualStudio2019/AudioPluginHost_App.vcxproj.filters
@@ -6963,6 +6963,9 @@
JUCE Modules\juce_graphics\native
+
+ JUCE Modules\juce_graphics\native
+
JUCE Modules\juce_graphics\native
diff --git a/extras/AudioPluginHost/Builds/VisualStudio2022/AudioPluginHost_App.vcxproj b/extras/AudioPluginHost/Builds/VisualStudio2022/AudioPluginHost_App.vcxproj
index bcc48e0bee..872cf5da77 100644
--- a/extras/AudioPluginHost/Builds/VisualStudio2022/AudioPluginHost_App.vcxproj
+++ b/extras/AudioPluginHost/Builds/VisualStudio2022/AudioPluginHost_App.vcxproj
@@ -4060,6 +4060,7 @@
+
diff --git a/extras/AudioPluginHost/Builds/VisualStudio2022/AudioPluginHost_App.vcxproj.filters b/extras/AudioPluginHost/Builds/VisualStudio2022/AudioPluginHost_App.vcxproj.filters
index 2c7225ac1c..46ffe5ae7b 100644
--- a/extras/AudioPluginHost/Builds/VisualStudio2022/AudioPluginHost_App.vcxproj.filters
+++ b/extras/AudioPluginHost/Builds/VisualStudio2022/AudioPluginHost_App.vcxproj.filters
@@ -6963,6 +6963,9 @@
JUCE Modules\juce_graphics\native
+
+ JUCE Modules\juce_graphics\native
+
JUCE Modules\juce_graphics\native
diff --git a/extras/NetworkGraphicsDemo/Builds/Android/app/CMakeLists.txt b/extras/NetworkGraphicsDemo/Builds/Android/app/CMakeLists.txt
index 528054c271..2004545996 100644
--- a/extras/NetworkGraphicsDemo/Builds/Android/app/CMakeLists.txt
+++ b/extras/NetworkGraphicsDemo/Builds/Android/app/CMakeLists.txt
@@ -1764,6 +1764,7 @@ add_library( ${BINARY_NAME}
"../../../../../modules/juce_graphics/native/juce_Direct2DImageContext_windows.h"
"../../../../../modules/juce_graphics/native/juce_Direct2DMetrics_windows.cpp"
"../../../../../modules/juce_graphics/native/juce_Direct2DMetrics_windows.h"
+ "../../../../../modules/juce_graphics/native/juce_Direct2DPixelDataPage_windows.h"
"../../../../../modules/juce_graphics/native/juce_Direct2DResources_windows.cpp"
"../../../../../modules/juce_graphics/native/juce_DirectWriteTypeface_windows.cpp"
"../../../../../modules/juce_graphics/native/juce_DirectX_windows.h"
@@ -4101,6 +4102,7 @@ set_source_files_properties(
"../../../../../modules/juce_graphics/native/juce_Direct2DImageContext_windows.h"
"../../../../../modules/juce_graphics/native/juce_Direct2DMetrics_windows.cpp"
"../../../../../modules/juce_graphics/native/juce_Direct2DMetrics_windows.h"
+ "../../../../../modules/juce_graphics/native/juce_Direct2DPixelDataPage_windows.h"
"../../../../../modules/juce_graphics/native/juce_Direct2DResources_windows.cpp"
"../../../../../modules/juce_graphics/native/juce_DirectWriteTypeface_windows.cpp"
"../../../../../modules/juce_graphics/native/juce_DirectX_windows.h"
diff --git a/extras/NetworkGraphicsDemo/Builds/VisualStudio2022/NetworkGraphicsDemo_App.vcxproj b/extras/NetworkGraphicsDemo/Builds/VisualStudio2022/NetworkGraphicsDemo_App.vcxproj
index 067118e908..5270971306 100644
--- a/extras/NetworkGraphicsDemo/Builds/VisualStudio2022/NetworkGraphicsDemo_App.vcxproj
+++ b/extras/NetworkGraphicsDemo/Builds/VisualStudio2022/NetworkGraphicsDemo_App.vcxproj
@@ -3925,6 +3925,7 @@
+
diff --git a/extras/NetworkGraphicsDemo/Builds/VisualStudio2022/NetworkGraphicsDemo_App.vcxproj.filters b/extras/NetworkGraphicsDemo/Builds/VisualStudio2022/NetworkGraphicsDemo_App.vcxproj.filters
index 29c234b53d..1e7e862481 100644
--- a/extras/NetworkGraphicsDemo/Builds/VisualStudio2022/NetworkGraphicsDemo_App.vcxproj.filters
+++ b/extras/NetworkGraphicsDemo/Builds/VisualStudio2022/NetworkGraphicsDemo_App.vcxproj.filters
@@ -6690,6 +6690,9 @@
JUCE Modules\juce_graphics\native
+
+ JUCE Modules\juce_graphics\native
+
JUCE Modules\juce_graphics\native
diff --git a/extras/Projucer/Builds/VisualStudio2019/Projucer_App.vcxproj b/extras/Projucer/Builds/VisualStudio2019/Projucer_App.vcxproj
index 79f22c2210..e3ea262b97 100644
--- a/extras/Projucer/Builds/VisualStudio2019/Projucer_App.vcxproj
+++ b/extras/Projucer/Builds/VisualStudio2019/Projucer_App.vcxproj
@@ -2625,6 +2625,7 @@
+
diff --git a/extras/Projucer/Builds/VisualStudio2019/Projucer_App.vcxproj.filters b/extras/Projucer/Builds/VisualStudio2019/Projucer_App.vcxproj.filters
index 6b88ad8bab..dcf0ea544d 100644
--- a/extras/Projucer/Builds/VisualStudio2019/Projucer_App.vcxproj.filters
+++ b/extras/Projucer/Builds/VisualStudio2019/Projucer_App.vcxproj.filters
@@ -4332,6 +4332,9 @@
JUCE Modules\juce_graphics\native
+
+ JUCE Modules\juce_graphics\native
+
JUCE Modules\juce_graphics\native
diff --git a/extras/Projucer/Builds/VisualStudio2022/Projucer_App.vcxproj b/extras/Projucer/Builds/VisualStudio2022/Projucer_App.vcxproj
index f614495cc8..fa0855ebef 100644
--- a/extras/Projucer/Builds/VisualStudio2022/Projucer_App.vcxproj
+++ b/extras/Projucer/Builds/VisualStudio2022/Projucer_App.vcxproj
@@ -2625,6 +2625,7 @@
+
diff --git a/extras/Projucer/Builds/VisualStudio2022/Projucer_App.vcxproj.filters b/extras/Projucer/Builds/VisualStudio2022/Projucer_App.vcxproj.filters
index ebc4e0f63a..e4f7b301fa 100644
--- a/extras/Projucer/Builds/VisualStudio2022/Projucer_App.vcxproj.filters
+++ b/extras/Projucer/Builds/VisualStudio2022/Projucer_App.vcxproj.filters
@@ -4332,6 +4332,9 @@
JUCE Modules\juce_graphics\native
+
+ JUCE Modules\juce_graphics\native
+
JUCE Modules\juce_graphics\native
diff --git a/extras/UnitTestRunner/Builds/VisualStudio2019/UnitTestRunner_ConsoleApp.vcxproj b/extras/UnitTestRunner/Builds/VisualStudio2019/UnitTestRunner_ConsoleApp.vcxproj
index 3f59cff8d7..138f5cc555 100644
--- a/extras/UnitTestRunner/Builds/VisualStudio2019/UnitTestRunner_ConsoleApp.vcxproj
+++ b/extras/UnitTestRunner/Builds/VisualStudio2019/UnitTestRunner_ConsoleApp.vcxproj
@@ -4172,6 +4172,7 @@
+
diff --git a/extras/UnitTestRunner/Builds/VisualStudio2019/UnitTestRunner_ConsoleApp.vcxproj.filters b/extras/UnitTestRunner/Builds/VisualStudio2019/UnitTestRunner_ConsoleApp.vcxproj.filters
index 1606e0ba92..ab481d529d 100644
--- a/extras/UnitTestRunner/Builds/VisualStudio2019/UnitTestRunner_ConsoleApp.vcxproj.filters
+++ b/extras/UnitTestRunner/Builds/VisualStudio2019/UnitTestRunner_ConsoleApp.vcxproj.filters
@@ -7122,6 +7122,9 @@
JUCE Modules\juce_graphics\native
+
+ JUCE Modules\juce_graphics\native
+
JUCE Modules\juce_graphics\native
diff --git a/extras/UnitTestRunner/Builds/VisualStudio2022/UnitTestRunner_ConsoleApp.vcxproj b/extras/UnitTestRunner/Builds/VisualStudio2022/UnitTestRunner_ConsoleApp.vcxproj
index 67f5332dfb..bb4b4b654d 100644
--- a/extras/UnitTestRunner/Builds/VisualStudio2022/UnitTestRunner_ConsoleApp.vcxproj
+++ b/extras/UnitTestRunner/Builds/VisualStudio2022/UnitTestRunner_ConsoleApp.vcxproj
@@ -4172,6 +4172,7 @@
+
diff --git a/extras/UnitTestRunner/Builds/VisualStudio2022/UnitTestRunner_ConsoleApp.vcxproj.filters b/extras/UnitTestRunner/Builds/VisualStudio2022/UnitTestRunner_ConsoleApp.vcxproj.filters
index bc1b2cbdef..f3a20709f7 100644
--- a/extras/UnitTestRunner/Builds/VisualStudio2022/UnitTestRunner_ConsoleApp.vcxproj.filters
+++ b/extras/UnitTestRunner/Builds/VisualStudio2022/UnitTestRunner_ConsoleApp.vcxproj.filters
@@ -7122,6 +7122,9 @@
JUCE Modules\juce_graphics\native
+
+ JUCE Modules\juce_graphics\native
+
JUCE Modules\juce_graphics\native
diff --git a/extras/WindowsDLL/Builds/VisualStudio2022/WindowsDLL_DynamicLibrary.vcxproj b/extras/WindowsDLL/Builds/VisualStudio2022/WindowsDLL_DynamicLibrary.vcxproj
index b33d368cdd..67cd7df9e0 100644
--- a/extras/WindowsDLL/Builds/VisualStudio2022/WindowsDLL_DynamicLibrary.vcxproj
+++ b/extras/WindowsDLL/Builds/VisualStudio2022/WindowsDLL_DynamicLibrary.vcxproj
@@ -3901,6 +3901,7 @@
+
diff --git a/extras/WindowsDLL/Builds/VisualStudio2022/WindowsDLL_DynamicLibrary.vcxproj.filters b/extras/WindowsDLL/Builds/VisualStudio2022/WindowsDLL_DynamicLibrary.vcxproj.filters
index c5b3a9ced8..0930f6a0c7 100644
--- a/extras/WindowsDLL/Builds/VisualStudio2022/WindowsDLL_DynamicLibrary.vcxproj.filters
+++ b/extras/WindowsDLL/Builds/VisualStudio2022/WindowsDLL_DynamicLibrary.vcxproj.filters
@@ -6657,6 +6657,9 @@
JUCE Modules\juce_graphics\native
+
+ JUCE Modules\juce_graphics\native
+
JUCE Modules\juce_graphics\native
diff --git a/modules/juce_graphics/images/juce_Image.cpp b/modules/juce_graphics/images/juce_Image.cpp
index 6af4ae1487..8b1f45cedf 100644
--- a/modules/juce_graphics/images/juce_Image.cpp
+++ b/modules/juce_graphics/images/juce_Image.cpp
@@ -276,14 +276,22 @@ public:
/* For subsection images, this returns the top-left pixel inside the root image */
Point getTopLeft() const { return impl->getTopLeft(); }
+ #if JUCE_WINDOWS
+ Span getPages (ComSmartPtr x) const { return impl->getPages (x); }
+ #endif
+
private:
struct Base
{
virtual ~Base() = default;
virtual Point getTopLeft() const = 0;
- };
- template
+ #if JUCE_WINDOWS
+ virtual Span getPages (ComSmartPtr) const = 0;
+ #endif
+ };
+
+ template
class Concrete : public Base
{
public:
@@ -292,6 +300,10 @@ private:
Point getTopLeft() const override { return impl.getTopLeft(); }
+ #if JUCE_WINDOWS
+ Span getPages (ComSmartPtr x) const override { return impl.getPages (x); }
+ #endif
+
private:
Impl impl;
};
@@ -377,6 +389,13 @@ public:
explicit Wrapped (Ptr selfIn)
: self (selfIn) {}
+ #if JUCE_WINDOWS
+ Span getPages (ComSmartPtr x) const
+ {
+ return self->sourceImage->getNativeExtensions().getPages (x);
+ }
+ #endif
+
Point getTopLeft() const
{
return self->sourceImage->getNativeExtensions().getTopLeft() + self->area.getTopLeft();
@@ -465,6 +484,10 @@ auto ImagePixelData::getNativeExtensions() -> NativeExtensions
struct Wrapped
{
Point getTopLeft() const { return {}; }
+
+ #if JUCE_WINDOWS
+ Span getPages (ComSmartPtr) const { return {}; }
+ #endif
};
return NativeExtensions { Wrapped{} };
diff --git a/modules/juce_graphics/juce_graphics.cpp b/modules/juce_graphics/juce_graphics.cpp
index 251c4332b7..37e43a6855 100644
--- a/modules/juce_graphics/juce_graphics.cpp
+++ b/modules/juce_graphics/juce_graphics.cpp
@@ -95,6 +95,8 @@
#pragma comment(lib, "dxguid.lib")
#endif
+ #include "native/juce_Direct2DPixelDataPage_windows.h"
+
#elif JUCE_IOS
#import
#import
diff --git a/modules/juce_graphics/native/juce_Direct2DGraphicsContext_windows.cpp b/modules/juce_graphics/native/juce_Direct2DGraphicsContext_windows.cpp
index 206f2473d0..1417c64cd3 100644
--- a/modules/juce_graphics/native/juce_Direct2DGraphicsContext_windows.cpp
+++ b/modules/juce_graphics/native/juce_Direct2DGraphicsContext_windows.cpp
@@ -245,6 +245,33 @@ private:
// layer stack accordingly.
};
+struct PagesAndArea
+{
+ Image imageHandle;
+ Span pages;
+ Rectangle area;
+
+ static PagesAndArea make (const Image& image, ComSmartPtr device)
+ {
+ using GetImage = Image (*) (const Image&);
+ constexpr GetImage converters[] { [] (const Image& i) { return i; },
+ [] (const Image& i) { return NativeImageType{}.convert (i); } };
+
+ for (auto* getImage : converters)
+ {
+ const auto converted = getImage (image);
+ const auto native = converted.getPixelData()->getNativeExtensions();
+
+ if (auto pages = native.getPages (device); ! pages.empty())
+ return PagesAndArea { converted, std::move (pages), converted.getBounds().withPosition (native.getTopLeft()) };
+ }
+
+ // Not sure how this could happen unless the NativeImageType no longer provides Windows native details...
+ jassertfalse;
+ return {};
+ }
+};
+
struct Direct2DGraphicsContext::SavedState
{
public:
@@ -338,30 +365,30 @@ public:
if (fillType.image.isNull())
return;
- const auto d2d1Bitmap = [&]
- {
- if (auto direct2DPixelData = dynamic_cast (fillType.image.getPixelData().get()))
- if (const auto page = direct2DPixelData->getFirstPageForDevice (D2DUtilities::getDeviceForContext (context)))
- if (page->GetPixelFormat().format == DXGI_FORMAT_B8G8R8A8_UNORM)
- return page;
+ const auto device = D2DUtilities::getDeviceForContext (context);
+ const auto imageFormat = fillType.image.getFormat();
+ const auto targetFormat = imageFormat == Image::SingleChannel ? Image::ARGB : imageFormat;
+ const auto pagesAndArea = PagesAndArea::make (fillType.image.convertedToFormat (targetFormat), device);
- JUCE_D2DMETRICS_SCOPED_ELAPSED_TIME (Direct2DMetricsHub::getInstance()->imageContextMetrics, createBitmapTime);
+ if (pagesAndArea.pages.empty())
+ return;
- return Direct2DBitmap::toBitmap (fillType.image, context, Image::ARGB);
- }();
+ const auto bitmap = pagesAndArea.pages.front().bitmap;
- if (d2d1Bitmap != nullptr)
- {
- D2D1_BRUSH_PROPERTIES brushProps { fillType.getOpacity(), D2DUtilities::transformToMatrix (fillType.transform) };
- auto bmProps = D2D1::BitmapBrushProperties (D2D1_EXTEND_MODE_WRAP, D2D1_EXTEND_MODE_WRAP);
- if (const auto hr = context->CreateBitmapBrush (d2d1Bitmap,
- bmProps,
- brushProps,
- bitmapBrush.resetAndGetPointerAddress()); SUCCEEDED (hr))
- {
- currentBrush = bitmapBrush;
- }
- }
+ if (bitmap == nullptr)
+ return;
+
+ D2D1_BRUSH_PROPERTIES brushProps { fillType.getOpacity(), D2DUtilities::transformToMatrix (fillType.transform) };
+ auto bmProps = D2D1::BitmapBrushProperties (D2D1_EXTEND_MODE_WRAP, D2D1_EXTEND_MODE_WRAP);
+ const auto hr = context->CreateBitmapBrush (bitmap,
+ bmProps,
+ brushProps,
+ bitmapBrush.resetAndGetPointerAddress());
+
+ if (FAILED (hr))
+ return;
+
+ currentBrush = bitmapBrush;
}
else if (fillType.isGradient())
{
@@ -1170,42 +1197,38 @@ void Direct2DGraphicsContext::clipToImageAlpha (const Image& sourceImage, const
return;
}
- // Is this a Direct2D image already?
- ComSmartPtr d2d1Bitmap;
+ const auto device = D2DUtilities::getDeviceForContext (deviceContext);
+ const auto pagesAndArea = PagesAndArea::make (sourceImage, device);
- if (auto direct2DPixelData = dynamic_cast (sourceImage.getPixelData().get()))
- d2d1Bitmap = direct2DPixelData->getFirstPageForDevice (D2DUtilities::getDeviceForContext (deviceContext));
+ if (pagesAndArea.pages.empty())
+ return;
- if (! d2d1Bitmap)
- {
- // Convert sourceImage to single-channel alpha-only maskImage
- d2d1Bitmap = Direct2DBitmap::toBitmap (sourceImage, deviceContext, Image::SingleChannel);
- }
+ const auto bitmap = pagesAndArea.pages.front().bitmap;
- if (d2d1Bitmap)
- {
- // Make a transformed bitmap brush using the bitmap
- // As usual, apply the current transform first *then* the transform parameter
- ComSmartPtr brush;
- auto matrix = D2DUtilities::transformToMatrix (brushTransform);
- D2D1_BRUSH_PROPERTIES brushProps = { 1.0f, matrix };
+ if (bitmap == nullptr)
+ return;
- auto bitmapBrushProps = D2D1::BitmapBrushProperties (D2D1_EXTEND_MODE_WRAP, D2D1_EXTEND_MODE_WRAP);
- auto hr = deviceContext->CreateBitmapBrush (d2d1Bitmap, bitmapBrushProps, brushProps, brush.resetAndGetPointerAddress());
+ // Make a transformed bitmap brush using the bitmap
+ // As usual, apply the current transform first *then* the transform parameter
+ ComSmartPtr brush;
+ auto matrix = D2DUtilities::transformToMatrix (brushTransform);
+ D2D1_BRUSH_PROPERTIES brushProps = { 1.0f, matrix };
- if (SUCCEEDED (hr))
- {
- // Push the clipping layer onto the layer stack
- // Don't set maskTransform in the LayerParameters struct; that only applies to geometry clipping
- // Do set the contentBounds member, transformed appropriately
- auto layerParams = D2D1::LayerParameters1();
- auto transformedBounds = sourceImage.getBounds().toFloat().transformedBy (brushTransform);
- layerParams.contentBounds = D2DUtilities::toRECT_F (transformedBounds);
- layerParams.opacityBrush = brush;
+ auto bitmapBrushProps = D2D1::BitmapBrushProperties (D2D1_EXTEND_MODE_WRAP, D2D1_EXTEND_MODE_WRAP);
+ auto hr = deviceContext->CreateBitmapBrush (bitmap, bitmapBrushProps, brushProps, brush.resetAndGetPointerAddress());
- currentState->pushLayer (layerParams);
- }
- }
+ if (FAILED (hr))
+ return;
+
+ // Push the clipping layer onto the layer stack
+ // Don't set maskTransform in the LayerParameters struct; that only applies to geometry clipping
+ // Do set the contentBounds member, transformed appropriately
+ auto layerParams = D2D1::LayerParameters1();
+ auto transformedBounds = sourceImage.getBounds().toFloat().transformedBy (brushTransform);
+ layerParams.contentBounds = D2DUtilities::toRECT_F (transformedBounds);
+ layerParams.opacityBrush = brush;
+
+ currentState->pushLayer (layerParams);
}
}
@@ -1451,53 +1474,36 @@ void Direct2DGraphicsContext::drawImage (const Image& imageIn, const AffineTrans
if (auto deviceContext = getPimpl()->getDeviceContext())
{
- auto image = NativeImageType{}.convert (imageIn);
- Direct2DPixelData* nativeBitmap = nullptr;
- Rectangle imageClipArea;
+ const auto device = D2DUtilities::getDeviceForContext (deviceContext);
+ const auto pagesAndArea = PagesAndArea::make (imageIn, device);
- const auto imageTransform = currentState->currentTransform.getTransformWith (transform);
-
- if (auto* subsectionPixelData = dynamic_cast (image.getPixelData().get()))
- {
- if (auto direct2DPixelData = dynamic_cast (subsectionPixelData->getSourcePixelData().get()))
- {
- nativeBitmap = direct2DPixelData;
- imageClipArea = subsectionPixelData->getSubsection();
- }
- }
- else if (auto direct2DPixelData = dynamic_cast (image.getPixelData().get()))
- {
- nativeBitmap = direct2DPixelData;
- imageClipArea = { direct2DPixelData->width, direct2DPixelData->height };
- }
- else
- {
- // This shouldn't happen, we converted the image to a native type already
- jassertfalse;
- }
-
- if (! nativeBitmap)
+ if (pagesAndArea.pages.empty())
{
jassertfalse;
return;
}
- auto drawTiles = [&] (const auto& pixelData, auto&& getRect)
+ const auto imageTransform = currentState->currentTransform.getTransformWith (transform);
+
+ auto drawTiles = [&] (auto&& getRect)
{
- for (const auto& page : pixelData->getPagesForDevice (D2DUtilities::getDeviceForContext (deviceContext)))
+ for (const auto& page : pagesAndArea.pages)
{
+ if (page.bitmap == nullptr)
+ continue;
+
const auto pageBounds = page.getBounds();
- const auto intersection = pageBounds.toFloat().getIntersection (imageClipArea.toFloat());
+ const auto intersection = pageBounds.toFloat().getIntersection (pagesAndArea.area.toFloat());
if (intersection.isEmpty())
continue;
const auto src = intersection - pageBounds.getPosition().toFloat();
- const auto dst = getRect (intersection - imageClipArea.getPosition().toFloat());
+ const auto dst = getRect (intersection - pagesAndArea.area.getPosition().toFloat());
const auto [srcConverted, dstConverted] = std::tuple (D2DUtilities::toRECT_F (src),
D2DUtilities::toRECT_F (dst));
- if (nativeBitmap->pixelFormat == Image::SingleChannel)
+ if (page.bitmap->GetPixelFormat().format == DXGI_FORMAT_A8_UNORM)
{
const auto lastColour = currentState->colourBrush->GetColor();
const auto lastMode = deviceContext->GetAntialiasMode();
@@ -1526,7 +1532,7 @@ void Direct2DGraphicsContext::drawImage (const Image& imageIn, const AffineTrans
if (imageTransform.isOnlyTranslation() || D2DHelpers::isTransformAxisAligned (imageTransform))
{
- drawTiles (nativeBitmap, [&] (auto intersection)
+ drawTiles ([&] (auto intersection)
{
return intersection.transformedBy (imageTransform);
});
@@ -1536,7 +1542,7 @@ void Direct2DGraphicsContext::drawImage (const Image& imageIn, const AffineTrans
ScopedTransform scopedTransform { *getPimpl(), currentState, transform };
- drawTiles (nativeBitmap, [] (auto intersection)
+ drawTiles ([] (auto intersection)
{
return intersection;
});
diff --git a/modules/juce_graphics/native/juce_Direct2DImage_windows.cpp b/modules/juce_graphics/native/juce_Direct2DImage_windows.cpp
index 78d04aa0c2..01032886db 100644
--- a/modules/juce_graphics/native/juce_Direct2DImage_windows.cpp
+++ b/modules/juce_graphics/native/juce_Direct2DImage_windows.cpp
@@ -35,13 +35,6 @@
namespace juce
{
-Rectangle Direct2DPixelDataPage::getBounds() const
-{
- return bitmap != nullptr ? D2DUtilities::rectFromSize (bitmap->GetPixelSize()).withPosition (topLeft)
- : Rectangle{};
-}
-
-//==============================================================================
static std::vector makePages (ComSmartPtr device,
ImagePixelData::Ptr backingData,
bool needsClear)
@@ -783,6 +776,29 @@ bool Direct2DPixelData::canBackup() const
});
}
+auto Direct2DPixelData::getNativeExtensions() -> NativeExtensions
+{
+ struct Wrapped
+ {
+ explicit Wrapped (Ptr s)
+ : self (s) {}
+
+ Span getPages (ComSmartPtr x) const
+ {
+ return self->getPagesForDevice (x);
+ }
+
+ Point getTopLeft() const
+ {
+ return {};
+ }
+
+ Ptr self;
+ };
+
+ return NativeExtensions { Wrapped { this } };
+}
+
//==============================================================================
ImagePixelData::Ptr NativeImageType::create (Image::PixelFormat format, int width, int height, bool clearImage) const
{
diff --git a/modules/juce_graphics/native/juce_Direct2DImage_windows.h b/modules/juce_graphics/native/juce_Direct2DImage_windows.h
index 1e4980ee8e..9f4d18bb92 100644
--- a/modules/juce_graphics/native/juce_Direct2DImage_windows.h
+++ b/modules/juce_graphics/native/juce_Direct2DImage_windows.h
@@ -35,19 +35,6 @@
namespace juce
{
-/* A single bitmap that represents a subsection of a virtual bitmap. */
-struct Direct2DPixelDataPage
-{
- /* The bounds of the stored bitmap inside the virtual bitmap. */
- Rectangle getBounds() const;
-
- /* The stored subsection bitmap. */
- ComSmartPtr bitmap;
-
- /* The top-left position of this virtual bitmap inside the virtual bitmap. */
- Point topLeft;
-};
-
/* A set of pages that together represent a full virtual bitmap.
All pages in the set always share the same resource context.
Additionally, stores a reference to a software-backed bitmap, the content of which will
@@ -204,6 +191,8 @@ public:
BackupExtensions* getBackupExtensions() override { return this; }
const BackupExtensions* getBackupExtensions() const override { return this; }
+ ImagePixelDataNativeExtensions getNativeExtensions() override;
+
private:
enum class State
{
diff --git a/modules/juce_graphics/native/juce_Direct2DPixelDataPage_windows.h b/modules/juce_graphics/native/juce_Direct2DPixelDataPage_windows.h
new file mode 100644
index 0000000000..2239677d85
--- /dev/null
+++ b/modules/juce_graphics/native/juce_Direct2DPixelDataPage_windows.h
@@ -0,0 +1,58 @@
+/*
+ ==============================================================================
+
+ This file is part of the JUCE framework.
+ Copyright (c) Raw Material Software Limited
+
+ JUCE is an open source framework subject to commercial or open source
+ licensing.
+
+ By downloading, installing, or using the JUCE framework, or combining the
+ JUCE framework with any other source code, object code, content or any other
+ copyrightable work, you agree to the terms of the JUCE End User Licence
+ Agreement, and all incorporated terms including the JUCE Privacy Policy and
+ the JUCE Website Terms of Service, as applicable, which will bind you. If you
+ do not agree to the terms of these agreements, we will not license the JUCE
+ framework to you, and you must discontinue the installation or download
+ process and cease use of the JUCE framework.
+
+ JUCE End User Licence Agreement: https://juce.com/legal/juce-8-licence/
+ JUCE Privacy Policy: https://juce.com/juce-privacy-policy
+ JUCE Website Terms of Service: https://juce.com/juce-website-terms-of-service/
+
+ Or:
+
+ You may also use this code under the terms of the AGPLv3:
+ https://www.gnu.org/licenses/agpl-3.0.en.html
+
+ THE JUCE FRAMEWORK IS PROVIDED "AS IS" WITHOUT ANY WARRANTY, AND ALL
+ WARRANTIES, WHETHER EXPRESSED OR IMPLIED, INCLUDING WARRANTY OF
+ MERCHANTABILITY OR FITNESS FOR A PARTICULAR PURPOSE, ARE DISCLAIMED.
+
+ ==============================================================================
+*/
+
+namespace juce
+{
+
+/* A single bitmap that represents a subsection of a virtual bitmap. */
+struct Direct2DPixelDataPage
+{
+ /* The bounds of the stored bitmap inside the virtual bitmap. */
+ Rectangle getBounds() const
+ {
+ if (bitmap == nullptr)
+ return {};
+
+ const auto size = bitmap->GetPixelSize();
+ return Rectangle { (int) size.width, (int) size.height }.withPosition (topLeft);
+ }
+
+ /* The stored subsection bitmap. */
+ ComSmartPtr bitmap;
+
+ /* The top-left position of this virtual bitmap inside the virtual bitmap. */
+ Point topLeft;
+};
+
+} // namespace juce
diff --git a/modules/juce_gui_basics/juce_gui_basics.cpp b/modules/juce_gui_basics/juce_gui_basics.cpp
index 1aae6dce37..52311596f3 100644
--- a/modules/juce_gui_basics/juce_gui_basics.cpp
+++ b/modules/juce_gui_basics/juce_gui_basics.cpp
@@ -199,6 +199,7 @@
#include
#include
#include
+ #include
#include
#include