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