1
0
Fork 0
mirror of https://github.com/juce-framework/JUCE.git synced 2026-01-11 23:54:18 +00:00

Direct2D: Add initial support

This commit is contained in:
reuk 2024-04-15 19:15:28 +01:00
parent 0e6a358c45
commit 19061e6d17
No known key found for this signature in database
GPG key ID: FCB43929F012EE5C
83 changed files with 8182 additions and 1558 deletions

View file

@ -1949,8 +1949,20 @@ add_library( ${BINARY_NAME}
"../../../../../modules/juce_graphics/native/juce_CoreGraphicsHelpers_mac.h"
"../../../../../modules/juce_graphics/native/juce_Direct2DGraphicsContext_windows.cpp"
"../../../../../modules/juce_graphics/native/juce_Direct2DGraphicsContext_windows.h"
"../../../../../modules/juce_graphics/native/juce_Direct2DHelpers_windows.cpp"
"../../../../../modules/juce_graphics/native/juce_Direct2DHwndContext_windows.cpp"
"../../../../../modules/juce_graphics/native/juce_Direct2DHwndContext_windows.h"
"../../../../../modules/juce_graphics/native/juce_Direct2DImage_windows.cpp"
"../../../../../modules/juce_graphics/native/juce_Direct2DImage_windows.h"
"../../../../../modules/juce_graphics/native/juce_Direct2DImageContext_windows.cpp"
"../../../../../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_Direct2DResources_windows.cpp"
"../../../../../modules/juce_graphics/native/juce_DirectWriteTypeface_windows.cpp"
"../../../../../modules/juce_graphics/native/juce_DirectWriteTypeLayout_windows.cpp"
"../../../../../modules/juce_graphics/native/juce_DirectX_windows.h"
"../../../../../modules/juce_graphics/native/juce_EventTracing.h"
"../../../../../modules/juce_graphics/native/juce_Fonts_android.cpp"
"../../../../../modules/juce_graphics/native/juce_Fonts_freetype.cpp"
"../../../../../modules/juce_graphics/native/juce_Fonts_linux.cpp"
@ -2050,6 +2062,7 @@ add_library( ${BINARY_NAME}
"../../../../../modules/juce_gui_basics/detail/juce_ScopedContentSharerInterface.h"
"../../../../../modules/juce_gui_basics/detail/juce_ScopedMessageBoxImpl.h"
"../../../../../modules/juce_gui_basics/detail/juce_ScopedMessageBoxInterface.h"
"../../../../../modules/juce_gui_basics/detail/juce_StandardCachedComponentImage.h"
"../../../../../modules/juce_gui_basics/detail/juce_ToolbarItemDragAndDropOverlayComponent.h"
"../../../../../modules/juce_gui_basics/detail/juce_TopLevelWindowManager.h"
"../../../../../modules/juce_gui_basics/detail/juce_ViewportHelpers.h"
@ -4432,8 +4445,20 @@ set_source_files_properties(
"../../../../../modules/juce_graphics/native/juce_CoreGraphicsHelpers_mac.h"
"../../../../../modules/juce_graphics/native/juce_Direct2DGraphicsContext_windows.cpp"
"../../../../../modules/juce_graphics/native/juce_Direct2DGraphicsContext_windows.h"
"../../../../../modules/juce_graphics/native/juce_Direct2DHelpers_windows.cpp"
"../../../../../modules/juce_graphics/native/juce_Direct2DHwndContext_windows.cpp"
"../../../../../modules/juce_graphics/native/juce_Direct2DHwndContext_windows.h"
"../../../../../modules/juce_graphics/native/juce_Direct2DImage_windows.cpp"
"../../../../../modules/juce_graphics/native/juce_Direct2DImage_windows.h"
"../../../../../modules/juce_graphics/native/juce_Direct2DImageContext_windows.cpp"
"../../../../../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_Direct2DResources_windows.cpp"
"../../../../../modules/juce_graphics/native/juce_DirectWriteTypeface_windows.cpp"
"../../../../../modules/juce_graphics/native/juce_DirectWriteTypeLayout_windows.cpp"
"../../../../../modules/juce_graphics/native/juce_DirectX_windows.h"
"../../../../../modules/juce_graphics/native/juce_EventTracing.h"
"../../../../../modules/juce_graphics/native/juce_Fonts_android.cpp"
"../../../../../modules/juce_graphics/native/juce_Fonts_freetype.cpp"
"../../../../../modules/juce_graphics/native/juce_Fonts_linux.cpp"
@ -4533,6 +4558,7 @@ set_source_files_properties(
"../../../../../modules/juce_gui_basics/detail/juce_ScopedContentSharerInterface.h"
"../../../../../modules/juce_gui_basics/detail/juce_ScopedMessageBoxImpl.h"
"../../../../../modules/juce_gui_basics/detail/juce_ScopedMessageBoxInterface.h"
"../../../../../modules/juce_gui_basics/detail/juce_StandardCachedComponentImage.h"
"../../../../../modules/juce_gui_basics/detail/juce_ToolbarItemDragAndDropOverlayComponent.h"
"../../../../../modules/juce_gui_basics/detail/juce_TopLevelWindowManager.h"
"../../../../../modules/juce_gui_basics/detail/juce_ViewportHelpers.h"

View file

@ -2351,6 +2351,24 @@
<ClCompile Include="..\..\..\..\modules\juce_graphics\native\juce_Direct2DGraphicsContext_windows.cpp">
<ExcludedFromBuild>true</ExcludedFromBuild>
</ClCompile>
<ClCompile Include="..\..\..\..\modules\juce_graphics\native\juce_Direct2DHelpers_windows.cpp">
<ExcludedFromBuild>true</ExcludedFromBuild>
</ClCompile>
<ClCompile Include="..\..\..\..\modules\juce_graphics\native\juce_Direct2DHwndContext_windows.cpp">
<ExcludedFromBuild>true</ExcludedFromBuild>
</ClCompile>
<ClCompile Include="..\..\..\..\modules\juce_graphics\native\juce_Direct2DImage_windows.cpp">
<ExcludedFromBuild>true</ExcludedFromBuild>
</ClCompile>
<ClCompile Include="..\..\..\..\modules\juce_graphics\native\juce_Direct2DImageContext_windows.cpp">
<ExcludedFromBuild>true</ExcludedFromBuild>
</ClCompile>
<ClCompile Include="..\..\..\..\modules\juce_graphics\native\juce_Direct2DMetrics_windows.cpp">
<ExcludedFromBuild>true</ExcludedFromBuild>
</ClCompile>
<ClCompile Include="..\..\..\..\modules\juce_graphics\native\juce_Direct2DResources_windows.cpp">
<ExcludedFromBuild>true</ExcludedFromBuild>
</ClCompile>
<ClCompile Include="..\..\..\..\modules\juce_graphics\native\juce_DirectWriteTypeface_windows.cpp">
<ExcludedFromBuild>true</ExcludedFromBuild>
</ClCompile>
@ -4220,6 +4238,12 @@
<ClInclude Include="..\..\..\..\modules\juce_graphics\native\juce_CoreGraphicsContext_mac.h"/>
<ClInclude Include="..\..\..\..\modules\juce_graphics\native\juce_CoreGraphicsHelpers_mac.h"/>
<ClInclude Include="..\..\..\..\modules\juce_graphics\native\juce_Direct2DGraphicsContext_windows.h"/>
<ClInclude Include="..\..\..\..\modules\juce_graphics\native\juce_Direct2DHwndContext_windows.h"/>
<ClInclude Include="..\..\..\..\modules\juce_graphics\native\juce_Direct2DImage_windows.h"/>
<ClInclude Include="..\..\..\..\modules\juce_graphics\native\juce_Direct2DImageContext_windows.h"/>
<ClInclude Include="..\..\..\..\modules\juce_graphics\native\juce_Direct2DMetrics_windows.h"/>
<ClInclude Include="..\..\..\..\modules\juce_graphics\native\juce_DirectX_windows.h"/>
<ClInclude Include="..\..\..\..\modules\juce_graphics\native\juce_EventTracing.h"/>
<ClInclude Include="..\..\..\..\modules\juce_graphics\native\juce_RenderingHelpers.h"/>
<ClInclude Include="..\..\..\..\modules\juce_graphics\placement\juce_Justification.h"/>
<ClInclude Include="..\..\..\..\modules\juce_graphics\placement\juce_RectanglePlacement.h"/>
@ -4275,6 +4299,7 @@
<ClInclude Include="..\..\..\..\modules\juce_gui_basics\detail\juce_ScopedContentSharerInterface.h"/>
<ClInclude Include="..\..\..\..\modules\juce_gui_basics\detail\juce_ScopedMessageBoxImpl.h"/>
<ClInclude Include="..\..\..\..\modules\juce_gui_basics\detail\juce_ScopedMessageBoxInterface.h"/>
<ClInclude Include="..\..\..\..\modules\juce_gui_basics\detail\juce_StandardCachedComponentImage.h"/>
<ClInclude Include="..\..\..\..\modules\juce_gui_basics\detail\juce_ToolbarItemDragAndDropOverlayComponent.h"/>
<ClInclude Include="..\..\..\..\modules\juce_gui_basics\detail\juce_TopLevelWindowManager.h"/>
<ClInclude Include="..\..\..\..\modules\juce_gui_basics\detail\juce_ViewportHelpers.h"/>

View file

@ -3103,6 +3103,24 @@
<ClCompile Include="..\..\..\..\modules\juce_graphics\native\juce_Direct2DGraphicsContext_windows.cpp">
<Filter>JUCE Modules\juce_graphics\native</Filter>
</ClCompile>
<ClCompile Include="..\..\..\..\modules\juce_graphics\native\juce_Direct2DHelpers_windows.cpp">
<Filter>JUCE Modules\juce_graphics\native</Filter>
</ClCompile>
<ClCompile Include="..\..\..\..\modules\juce_graphics\native\juce_Direct2DHwndContext_windows.cpp">
<Filter>JUCE Modules\juce_graphics\native</Filter>
</ClCompile>
<ClCompile Include="..\..\..\..\modules\juce_graphics\native\juce_Direct2DImage_windows.cpp">
<Filter>JUCE Modules\juce_graphics\native</Filter>
</ClCompile>
<ClCompile Include="..\..\..\..\modules\juce_graphics\native\juce_Direct2DImageContext_windows.cpp">
<Filter>JUCE Modules\juce_graphics\native</Filter>
</ClCompile>
<ClCompile Include="..\..\..\..\modules\juce_graphics\native\juce_Direct2DMetrics_windows.cpp">
<Filter>JUCE Modules\juce_graphics\native</Filter>
</ClCompile>
<ClCompile Include="..\..\..\..\modules\juce_graphics\native\juce_Direct2DResources_windows.cpp">
<Filter>JUCE Modules\juce_graphics\native</Filter>
</ClCompile>
<ClCompile Include="..\..\..\..\modules\juce_graphics\native\juce_DirectWriteTypeface_windows.cpp">
<Filter>JUCE Modules\juce_graphics\native</Filter>
</ClCompile>
@ -7314,6 +7332,24 @@
<ClInclude Include="..\..\..\..\modules\juce_graphics\native\juce_Direct2DGraphicsContext_windows.h">
<Filter>JUCE Modules\juce_graphics\native</Filter>
</ClInclude>
<ClInclude Include="..\..\..\..\modules\juce_graphics\native\juce_Direct2DHwndContext_windows.h">
<Filter>JUCE Modules\juce_graphics\native</Filter>
</ClInclude>
<ClInclude Include="..\..\..\..\modules\juce_graphics\native\juce_Direct2DImage_windows.h">
<Filter>JUCE Modules\juce_graphics\native</Filter>
</ClInclude>
<ClInclude Include="..\..\..\..\modules\juce_graphics\native\juce_Direct2DImageContext_windows.h">
<Filter>JUCE Modules\juce_graphics\native</Filter>
</ClInclude>
<ClInclude Include="..\..\..\..\modules\juce_graphics\native\juce_Direct2DMetrics_windows.h">
<Filter>JUCE Modules\juce_graphics\native</Filter>
</ClInclude>
<ClInclude Include="..\..\..\..\modules\juce_graphics\native\juce_DirectX_windows.h">
<Filter>JUCE Modules\juce_graphics\native</Filter>
</ClInclude>
<ClInclude Include="..\..\..\..\modules\juce_graphics\native\juce_EventTracing.h">
<Filter>JUCE Modules\juce_graphics\native</Filter>
</ClInclude>
<ClInclude Include="..\..\..\..\modules\juce_graphics\native\juce_RenderingHelpers.h">
<Filter>JUCE Modules\juce_graphics\native</Filter>
</ClInclude>
@ -7479,6 +7515,9 @@
<ClInclude Include="..\..\..\..\modules\juce_gui_basics\detail\juce_ScopedMessageBoxInterface.h">
<Filter>JUCE Modules\juce_gui_basics\detail</Filter>
</ClInclude>
<ClInclude Include="..\..\..\..\modules\juce_gui_basics\detail\juce_StandardCachedComponentImage.h">
<Filter>JUCE Modules\juce_gui_basics\detail</Filter>
</ClInclude>
<ClInclude Include="..\..\..\..\modules\juce_gui_basics\detail\juce_ToolbarItemDragAndDropOverlayComponent.h">
<Filter>JUCE Modules\juce_gui_basics\detail</Filter>
</ClInclude>

View file

@ -2351,6 +2351,24 @@
<ClCompile Include="..\..\..\..\modules\juce_graphics\native\juce_Direct2DGraphicsContext_windows.cpp">
<ExcludedFromBuild>true</ExcludedFromBuild>
</ClCompile>
<ClCompile Include="..\..\..\..\modules\juce_graphics\native\juce_Direct2DHelpers_windows.cpp">
<ExcludedFromBuild>true</ExcludedFromBuild>
</ClCompile>
<ClCompile Include="..\..\..\..\modules\juce_graphics\native\juce_Direct2DHwndContext_windows.cpp">
<ExcludedFromBuild>true</ExcludedFromBuild>
</ClCompile>
<ClCompile Include="..\..\..\..\modules\juce_graphics\native\juce_Direct2DImage_windows.cpp">
<ExcludedFromBuild>true</ExcludedFromBuild>
</ClCompile>
<ClCompile Include="..\..\..\..\modules\juce_graphics\native\juce_Direct2DImageContext_windows.cpp">
<ExcludedFromBuild>true</ExcludedFromBuild>
</ClCompile>
<ClCompile Include="..\..\..\..\modules\juce_graphics\native\juce_Direct2DMetrics_windows.cpp">
<ExcludedFromBuild>true</ExcludedFromBuild>
</ClCompile>
<ClCompile Include="..\..\..\..\modules\juce_graphics\native\juce_Direct2DResources_windows.cpp">
<ExcludedFromBuild>true</ExcludedFromBuild>
</ClCompile>
<ClCompile Include="..\..\..\..\modules\juce_graphics\native\juce_DirectWriteTypeface_windows.cpp">
<ExcludedFromBuild>true</ExcludedFromBuild>
</ClCompile>
@ -4220,6 +4238,12 @@
<ClInclude Include="..\..\..\..\modules\juce_graphics\native\juce_CoreGraphicsContext_mac.h"/>
<ClInclude Include="..\..\..\..\modules\juce_graphics\native\juce_CoreGraphicsHelpers_mac.h"/>
<ClInclude Include="..\..\..\..\modules\juce_graphics\native\juce_Direct2DGraphicsContext_windows.h"/>
<ClInclude Include="..\..\..\..\modules\juce_graphics\native\juce_Direct2DHwndContext_windows.h"/>
<ClInclude Include="..\..\..\..\modules\juce_graphics\native\juce_Direct2DImage_windows.h"/>
<ClInclude Include="..\..\..\..\modules\juce_graphics\native\juce_Direct2DImageContext_windows.h"/>
<ClInclude Include="..\..\..\..\modules\juce_graphics\native\juce_Direct2DMetrics_windows.h"/>
<ClInclude Include="..\..\..\..\modules\juce_graphics\native\juce_DirectX_windows.h"/>
<ClInclude Include="..\..\..\..\modules\juce_graphics\native\juce_EventTracing.h"/>
<ClInclude Include="..\..\..\..\modules\juce_graphics\native\juce_RenderingHelpers.h"/>
<ClInclude Include="..\..\..\..\modules\juce_graphics\placement\juce_Justification.h"/>
<ClInclude Include="..\..\..\..\modules\juce_graphics\placement\juce_RectanglePlacement.h"/>
@ -4275,6 +4299,7 @@
<ClInclude Include="..\..\..\..\modules\juce_gui_basics\detail\juce_ScopedContentSharerInterface.h"/>
<ClInclude Include="..\..\..\..\modules\juce_gui_basics\detail\juce_ScopedMessageBoxImpl.h"/>
<ClInclude Include="..\..\..\..\modules\juce_gui_basics\detail\juce_ScopedMessageBoxInterface.h"/>
<ClInclude Include="..\..\..\..\modules\juce_gui_basics\detail\juce_StandardCachedComponentImage.h"/>
<ClInclude Include="..\..\..\..\modules\juce_gui_basics\detail\juce_ToolbarItemDragAndDropOverlayComponent.h"/>
<ClInclude Include="..\..\..\..\modules\juce_gui_basics\detail\juce_TopLevelWindowManager.h"/>
<ClInclude Include="..\..\..\..\modules\juce_gui_basics\detail\juce_ViewportHelpers.h"/>

View file

@ -3103,6 +3103,24 @@
<ClCompile Include="..\..\..\..\modules\juce_graphics\native\juce_Direct2DGraphicsContext_windows.cpp">
<Filter>JUCE Modules\juce_graphics\native</Filter>
</ClCompile>
<ClCompile Include="..\..\..\..\modules\juce_graphics\native\juce_Direct2DHelpers_windows.cpp">
<Filter>JUCE Modules\juce_graphics\native</Filter>
</ClCompile>
<ClCompile Include="..\..\..\..\modules\juce_graphics\native\juce_Direct2DHwndContext_windows.cpp">
<Filter>JUCE Modules\juce_graphics\native</Filter>
</ClCompile>
<ClCompile Include="..\..\..\..\modules\juce_graphics\native\juce_Direct2DImage_windows.cpp">
<Filter>JUCE Modules\juce_graphics\native</Filter>
</ClCompile>
<ClCompile Include="..\..\..\..\modules\juce_graphics\native\juce_Direct2DImageContext_windows.cpp">
<Filter>JUCE Modules\juce_graphics\native</Filter>
</ClCompile>
<ClCompile Include="..\..\..\..\modules\juce_graphics\native\juce_Direct2DMetrics_windows.cpp">
<Filter>JUCE Modules\juce_graphics\native</Filter>
</ClCompile>
<ClCompile Include="..\..\..\..\modules\juce_graphics\native\juce_Direct2DResources_windows.cpp">
<Filter>JUCE Modules\juce_graphics\native</Filter>
</ClCompile>
<ClCompile Include="..\..\..\..\modules\juce_graphics\native\juce_DirectWriteTypeface_windows.cpp">
<Filter>JUCE Modules\juce_graphics\native</Filter>
</ClCompile>
@ -7314,6 +7332,24 @@
<ClInclude Include="..\..\..\..\modules\juce_graphics\native\juce_Direct2DGraphicsContext_windows.h">
<Filter>JUCE Modules\juce_graphics\native</Filter>
</ClInclude>
<ClInclude Include="..\..\..\..\modules\juce_graphics\native\juce_Direct2DHwndContext_windows.h">
<Filter>JUCE Modules\juce_graphics\native</Filter>
</ClInclude>
<ClInclude Include="..\..\..\..\modules\juce_graphics\native\juce_Direct2DImage_windows.h">
<Filter>JUCE Modules\juce_graphics\native</Filter>
</ClInclude>
<ClInclude Include="..\..\..\..\modules\juce_graphics\native\juce_Direct2DImageContext_windows.h">
<Filter>JUCE Modules\juce_graphics\native</Filter>
</ClInclude>
<ClInclude Include="..\..\..\..\modules\juce_graphics\native\juce_Direct2DMetrics_windows.h">
<Filter>JUCE Modules\juce_graphics\native</Filter>
</ClInclude>
<ClInclude Include="..\..\..\..\modules\juce_graphics\native\juce_DirectX_windows.h">
<Filter>JUCE Modules\juce_graphics\native</Filter>
</ClInclude>
<ClInclude Include="..\..\..\..\modules\juce_graphics\native\juce_EventTracing.h">
<Filter>JUCE Modules\juce_graphics\native</Filter>
</ClInclude>
<ClInclude Include="..\..\..\..\modules\juce_graphics\native\juce_RenderingHelpers.h">
<Filter>JUCE Modules\juce_graphics\native</Filter>
</ClInclude>
@ -7479,6 +7515,9 @@
<ClInclude Include="..\..\..\..\modules\juce_gui_basics\detail\juce_ScopedMessageBoxInterface.h">
<Filter>JUCE Modules\juce_gui_basics\detail</Filter>
</ClInclude>
<ClInclude Include="..\..\..\..\modules\juce_gui_basics\detail\juce_StandardCachedComponentImage.h">
<Filter>JUCE Modules\juce_gui_basics\detail</Filter>
</ClInclude>
<ClInclude Include="..\..\..\..\modules\juce_gui_basics\detail\juce_ToolbarItemDragAndDropOverlayComponent.h">
<Filter>JUCE Modules\juce_gui_basics\detail</Filter>
</ClInclude>

View file

@ -2351,6 +2351,24 @@
<ClCompile Include="..\..\..\..\modules\juce_graphics\native\juce_Direct2DGraphicsContext_windows.cpp">
<ExcludedFromBuild>true</ExcludedFromBuild>
</ClCompile>
<ClCompile Include="..\..\..\..\modules\juce_graphics\native\juce_Direct2DHelpers_windows.cpp">
<ExcludedFromBuild>true</ExcludedFromBuild>
</ClCompile>
<ClCompile Include="..\..\..\..\modules\juce_graphics\native\juce_Direct2DHwndContext_windows.cpp">
<ExcludedFromBuild>true</ExcludedFromBuild>
</ClCompile>
<ClCompile Include="..\..\..\..\modules\juce_graphics\native\juce_Direct2DImage_windows.cpp">
<ExcludedFromBuild>true</ExcludedFromBuild>
</ClCompile>
<ClCompile Include="..\..\..\..\modules\juce_graphics\native\juce_Direct2DImageContext_windows.cpp">
<ExcludedFromBuild>true</ExcludedFromBuild>
</ClCompile>
<ClCompile Include="..\..\..\..\modules\juce_graphics\native\juce_Direct2DMetrics_windows.cpp">
<ExcludedFromBuild>true</ExcludedFromBuild>
</ClCompile>
<ClCompile Include="..\..\..\..\modules\juce_graphics\native\juce_Direct2DResources_windows.cpp">
<ExcludedFromBuild>true</ExcludedFromBuild>
</ClCompile>
<ClCompile Include="..\..\..\..\modules\juce_graphics\native\juce_DirectWriteTypeface_windows.cpp">
<ExcludedFromBuild>true</ExcludedFromBuild>
</ClCompile>
@ -4220,6 +4238,12 @@
<ClInclude Include="..\..\..\..\modules\juce_graphics\native\juce_CoreGraphicsContext_mac.h"/>
<ClInclude Include="..\..\..\..\modules\juce_graphics\native\juce_CoreGraphicsHelpers_mac.h"/>
<ClInclude Include="..\..\..\..\modules\juce_graphics\native\juce_Direct2DGraphicsContext_windows.h"/>
<ClInclude Include="..\..\..\..\modules\juce_graphics\native\juce_Direct2DHwndContext_windows.h"/>
<ClInclude Include="..\..\..\..\modules\juce_graphics\native\juce_Direct2DImage_windows.h"/>
<ClInclude Include="..\..\..\..\modules\juce_graphics\native\juce_Direct2DImageContext_windows.h"/>
<ClInclude Include="..\..\..\..\modules\juce_graphics\native\juce_Direct2DMetrics_windows.h"/>
<ClInclude Include="..\..\..\..\modules\juce_graphics\native\juce_DirectX_windows.h"/>
<ClInclude Include="..\..\..\..\modules\juce_graphics\native\juce_EventTracing.h"/>
<ClInclude Include="..\..\..\..\modules\juce_graphics\native\juce_RenderingHelpers.h"/>
<ClInclude Include="..\..\..\..\modules\juce_graphics\placement\juce_Justification.h"/>
<ClInclude Include="..\..\..\..\modules\juce_graphics\placement\juce_RectanglePlacement.h"/>
@ -4275,6 +4299,7 @@
<ClInclude Include="..\..\..\..\modules\juce_gui_basics\detail\juce_ScopedContentSharerInterface.h"/>
<ClInclude Include="..\..\..\..\modules\juce_gui_basics\detail\juce_ScopedMessageBoxImpl.h"/>
<ClInclude Include="..\..\..\..\modules\juce_gui_basics\detail\juce_ScopedMessageBoxInterface.h"/>
<ClInclude Include="..\..\..\..\modules\juce_gui_basics\detail\juce_StandardCachedComponentImage.h"/>
<ClInclude Include="..\..\..\..\modules\juce_gui_basics\detail\juce_ToolbarItemDragAndDropOverlayComponent.h"/>
<ClInclude Include="..\..\..\..\modules\juce_gui_basics\detail\juce_TopLevelWindowManager.h"/>
<ClInclude Include="..\..\..\..\modules\juce_gui_basics\detail\juce_ViewportHelpers.h"/>

View file

@ -3103,6 +3103,24 @@
<ClCompile Include="..\..\..\..\modules\juce_graphics\native\juce_Direct2DGraphicsContext_windows.cpp">
<Filter>JUCE Modules\juce_graphics\native</Filter>
</ClCompile>
<ClCompile Include="..\..\..\..\modules\juce_graphics\native\juce_Direct2DHelpers_windows.cpp">
<Filter>JUCE Modules\juce_graphics\native</Filter>
</ClCompile>
<ClCompile Include="..\..\..\..\modules\juce_graphics\native\juce_Direct2DHwndContext_windows.cpp">
<Filter>JUCE Modules\juce_graphics\native</Filter>
</ClCompile>
<ClCompile Include="..\..\..\..\modules\juce_graphics\native\juce_Direct2DImage_windows.cpp">
<Filter>JUCE Modules\juce_graphics\native</Filter>
</ClCompile>
<ClCompile Include="..\..\..\..\modules\juce_graphics\native\juce_Direct2DImageContext_windows.cpp">
<Filter>JUCE Modules\juce_graphics\native</Filter>
</ClCompile>
<ClCompile Include="..\..\..\..\modules\juce_graphics\native\juce_Direct2DMetrics_windows.cpp">
<Filter>JUCE Modules\juce_graphics\native</Filter>
</ClCompile>
<ClCompile Include="..\..\..\..\modules\juce_graphics\native\juce_Direct2DResources_windows.cpp">
<Filter>JUCE Modules\juce_graphics\native</Filter>
</ClCompile>
<ClCompile Include="..\..\..\..\modules\juce_graphics\native\juce_DirectWriteTypeface_windows.cpp">
<Filter>JUCE Modules\juce_graphics\native</Filter>
</ClCompile>
@ -7314,6 +7332,24 @@
<ClInclude Include="..\..\..\..\modules\juce_graphics\native\juce_Direct2DGraphicsContext_windows.h">
<Filter>JUCE Modules\juce_graphics\native</Filter>
</ClInclude>
<ClInclude Include="..\..\..\..\modules\juce_graphics\native\juce_Direct2DHwndContext_windows.h">
<Filter>JUCE Modules\juce_graphics\native</Filter>
</ClInclude>
<ClInclude Include="..\..\..\..\modules\juce_graphics\native\juce_Direct2DImage_windows.h">
<Filter>JUCE Modules\juce_graphics\native</Filter>
</ClInclude>
<ClInclude Include="..\..\..\..\modules\juce_graphics\native\juce_Direct2DImageContext_windows.h">
<Filter>JUCE Modules\juce_graphics\native</Filter>
</ClInclude>
<ClInclude Include="..\..\..\..\modules\juce_graphics\native\juce_Direct2DMetrics_windows.h">
<Filter>JUCE Modules\juce_graphics\native</Filter>
</ClInclude>
<ClInclude Include="..\..\..\..\modules\juce_graphics\native\juce_DirectX_windows.h">
<Filter>JUCE Modules\juce_graphics\native</Filter>
</ClInclude>
<ClInclude Include="..\..\..\..\modules\juce_graphics\native\juce_EventTracing.h">
<Filter>JUCE Modules\juce_graphics\native</Filter>
</ClInclude>
<ClInclude Include="..\..\..\..\modules\juce_graphics\native\juce_RenderingHelpers.h">
<Filter>JUCE Modules\juce_graphics\native</Filter>
</ClInclude>
@ -7479,6 +7515,9 @@
<ClInclude Include="..\..\..\..\modules\juce_gui_basics\detail\juce_ScopedMessageBoxInterface.h">
<Filter>JUCE Modules\juce_gui_basics\detail</Filter>
</ClInclude>
<ClInclude Include="..\..\..\..\modules\juce_gui_basics\detail\juce_StandardCachedComponentImage.h">
<Filter>JUCE Modules\juce_gui_basics\detail</Filter>
</ClInclude>
<ClInclude Include="..\..\..\..\modules\juce_gui_basics\detail\juce_ToolbarItemDragAndDropOverlayComponent.h">
<Filter>JUCE Modules\juce_gui_basics\detail</Filter>
</ClInclude>

View file

@ -288,7 +288,7 @@ MainComponent::MainComponent()
{
#if JUCE_MAC && USE_COREGRAPHICS_RENDERING
setRenderingEngine (1);
#else
#elif ! JUCE_WINDOWS
setRenderingEngine (0);
#endif
}

View file

@ -1711,8 +1711,20 @@ add_library( ${BINARY_NAME}
"../../../../../modules/juce_graphics/native/juce_CoreGraphicsHelpers_mac.h"
"../../../../../modules/juce_graphics/native/juce_Direct2DGraphicsContext_windows.cpp"
"../../../../../modules/juce_graphics/native/juce_Direct2DGraphicsContext_windows.h"
"../../../../../modules/juce_graphics/native/juce_Direct2DHelpers_windows.cpp"
"../../../../../modules/juce_graphics/native/juce_Direct2DHwndContext_windows.cpp"
"../../../../../modules/juce_graphics/native/juce_Direct2DHwndContext_windows.h"
"../../../../../modules/juce_graphics/native/juce_Direct2DImage_windows.cpp"
"../../../../../modules/juce_graphics/native/juce_Direct2DImage_windows.h"
"../../../../../modules/juce_graphics/native/juce_Direct2DImageContext_windows.cpp"
"../../../../../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_Direct2DResources_windows.cpp"
"../../../../../modules/juce_graphics/native/juce_DirectWriteTypeface_windows.cpp"
"../../../../../modules/juce_graphics/native/juce_DirectWriteTypeLayout_windows.cpp"
"../../../../../modules/juce_graphics/native/juce_DirectX_windows.h"
"../../../../../modules/juce_graphics/native/juce_EventTracing.h"
"../../../../../modules/juce_graphics/native/juce_Fonts_android.cpp"
"../../../../../modules/juce_graphics/native/juce_Fonts_freetype.cpp"
"../../../../../modules/juce_graphics/native/juce_Fonts_linux.cpp"
@ -1812,6 +1824,7 @@ add_library( ${BINARY_NAME}
"../../../../../modules/juce_gui_basics/detail/juce_ScopedContentSharerInterface.h"
"../../../../../modules/juce_gui_basics/detail/juce_ScopedMessageBoxImpl.h"
"../../../../../modules/juce_gui_basics/detail/juce_ScopedMessageBoxInterface.h"
"../../../../../modules/juce_gui_basics/detail/juce_StandardCachedComponentImage.h"
"../../../../../modules/juce_gui_basics/detail/juce_ToolbarItemDragAndDropOverlayComponent.h"
"../../../../../modules/juce_gui_basics/detail/juce_TopLevelWindowManager.h"
"../../../../../modules/juce_gui_basics/detail/juce_ViewportHelpers.h"
@ -3876,8 +3889,20 @@ set_source_files_properties(
"../../../../../modules/juce_graphics/native/juce_CoreGraphicsHelpers_mac.h"
"../../../../../modules/juce_graphics/native/juce_Direct2DGraphicsContext_windows.cpp"
"../../../../../modules/juce_graphics/native/juce_Direct2DGraphicsContext_windows.h"
"../../../../../modules/juce_graphics/native/juce_Direct2DHelpers_windows.cpp"
"../../../../../modules/juce_graphics/native/juce_Direct2DHwndContext_windows.cpp"
"../../../../../modules/juce_graphics/native/juce_Direct2DHwndContext_windows.h"
"../../../../../modules/juce_graphics/native/juce_Direct2DImage_windows.cpp"
"../../../../../modules/juce_graphics/native/juce_Direct2DImage_windows.h"
"../../../../../modules/juce_graphics/native/juce_Direct2DImageContext_windows.cpp"
"../../../../../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_Direct2DResources_windows.cpp"
"../../../../../modules/juce_graphics/native/juce_DirectWriteTypeface_windows.cpp"
"../../../../../modules/juce_graphics/native/juce_DirectWriteTypeLayout_windows.cpp"
"../../../../../modules/juce_graphics/native/juce_DirectX_windows.h"
"../../../../../modules/juce_graphics/native/juce_EventTracing.h"
"../../../../../modules/juce_graphics/native/juce_Fonts_android.cpp"
"../../../../../modules/juce_graphics/native/juce_Fonts_freetype.cpp"
"../../../../../modules/juce_graphics/native/juce_Fonts_linux.cpp"
@ -3977,6 +4002,7 @@ set_source_files_properties(
"../../../../../modules/juce_gui_basics/detail/juce_ScopedContentSharerInterface.h"
"../../../../../modules/juce_gui_basics/detail/juce_ScopedMessageBoxImpl.h"
"../../../../../modules/juce_gui_basics/detail/juce_ScopedMessageBoxInterface.h"
"../../../../../modules/juce_gui_basics/detail/juce_StandardCachedComponentImage.h"
"../../../../../modules/juce_gui_basics/detail/juce_ToolbarItemDragAndDropOverlayComponent.h"
"../../../../../modules/juce_gui_basics/detail/juce_TopLevelWindowManager.h"
"../../../../../modules/juce_gui_basics/detail/juce_ViewportHelpers.h"

View file

@ -2044,6 +2044,24 @@
<ClCompile Include="..\..\..\..\modules\juce_graphics\native\juce_Direct2DGraphicsContext_windows.cpp">
<ExcludedFromBuild>true</ExcludedFromBuild>
</ClCompile>
<ClCompile Include="..\..\..\..\modules\juce_graphics\native\juce_Direct2DHelpers_windows.cpp">
<ExcludedFromBuild>true</ExcludedFromBuild>
</ClCompile>
<ClCompile Include="..\..\..\..\modules\juce_graphics\native\juce_Direct2DHwndContext_windows.cpp">
<ExcludedFromBuild>true</ExcludedFromBuild>
</ClCompile>
<ClCompile Include="..\..\..\..\modules\juce_graphics\native\juce_Direct2DImage_windows.cpp">
<ExcludedFromBuild>true</ExcludedFromBuild>
</ClCompile>
<ClCompile Include="..\..\..\..\modules\juce_graphics\native\juce_Direct2DImageContext_windows.cpp">
<ExcludedFromBuild>true</ExcludedFromBuild>
</ClCompile>
<ClCompile Include="..\..\..\..\modules\juce_graphics\native\juce_Direct2DMetrics_windows.cpp">
<ExcludedFromBuild>true</ExcludedFromBuild>
</ClCompile>
<ClCompile Include="..\..\..\..\modules\juce_graphics\native\juce_Direct2DResources_windows.cpp">
<ExcludedFromBuild>true</ExcludedFromBuild>
</ClCompile>
<ClCompile Include="..\..\..\..\modules\juce_graphics\native\juce_DirectWriteTypeface_windows.cpp">
<ExcludedFromBuild>true</ExcludedFromBuild>
</ClCompile>
@ -3691,6 +3709,12 @@
<ClInclude Include="..\..\..\..\modules\juce_graphics\native\juce_CoreGraphicsContext_mac.h"/>
<ClInclude Include="..\..\..\..\modules\juce_graphics\native\juce_CoreGraphicsHelpers_mac.h"/>
<ClInclude Include="..\..\..\..\modules\juce_graphics\native\juce_Direct2DGraphicsContext_windows.h"/>
<ClInclude Include="..\..\..\..\modules\juce_graphics\native\juce_Direct2DHwndContext_windows.h"/>
<ClInclude Include="..\..\..\..\modules\juce_graphics\native\juce_Direct2DImage_windows.h"/>
<ClInclude Include="..\..\..\..\modules\juce_graphics\native\juce_Direct2DImageContext_windows.h"/>
<ClInclude Include="..\..\..\..\modules\juce_graphics\native\juce_Direct2DMetrics_windows.h"/>
<ClInclude Include="..\..\..\..\modules\juce_graphics\native\juce_DirectX_windows.h"/>
<ClInclude Include="..\..\..\..\modules\juce_graphics\native\juce_EventTracing.h"/>
<ClInclude Include="..\..\..\..\modules\juce_graphics\native\juce_RenderingHelpers.h"/>
<ClInclude Include="..\..\..\..\modules\juce_graphics\placement\juce_Justification.h"/>
<ClInclude Include="..\..\..\..\modules\juce_graphics\placement\juce_RectanglePlacement.h"/>
@ -3746,6 +3770,7 @@
<ClInclude Include="..\..\..\..\modules\juce_gui_basics\detail\juce_ScopedContentSharerInterface.h"/>
<ClInclude Include="..\..\..\..\modules\juce_gui_basics\detail\juce_ScopedMessageBoxImpl.h"/>
<ClInclude Include="..\..\..\..\modules\juce_gui_basics\detail\juce_ScopedMessageBoxInterface.h"/>
<ClInclude Include="..\..\..\..\modules\juce_gui_basics\detail\juce_StandardCachedComponentImage.h"/>
<ClInclude Include="..\..\..\..\modules\juce_gui_basics\detail\juce_ToolbarItemDragAndDropOverlayComponent.h"/>
<ClInclude Include="..\..\..\..\modules\juce_gui_basics\detail\juce_TopLevelWindowManager.h"/>
<ClInclude Include="..\..\..\..\modules\juce_gui_basics\detail\juce_ViewportHelpers.h"/>

View file

@ -2647,6 +2647,24 @@
<ClCompile Include="..\..\..\..\modules\juce_graphics\native\juce_Direct2DGraphicsContext_windows.cpp">
<Filter>JUCE Modules\juce_graphics\native</Filter>
</ClCompile>
<ClCompile Include="..\..\..\..\modules\juce_graphics\native\juce_Direct2DHelpers_windows.cpp">
<Filter>JUCE Modules\juce_graphics\native</Filter>
</ClCompile>
<ClCompile Include="..\..\..\..\modules\juce_graphics\native\juce_Direct2DHwndContext_windows.cpp">
<Filter>JUCE Modules\juce_graphics\native</Filter>
</ClCompile>
<ClCompile Include="..\..\..\..\modules\juce_graphics\native\juce_Direct2DImage_windows.cpp">
<Filter>JUCE Modules\juce_graphics\native</Filter>
</ClCompile>
<ClCompile Include="..\..\..\..\modules\juce_graphics\native\juce_Direct2DImageContext_windows.cpp">
<Filter>JUCE Modules\juce_graphics\native</Filter>
</ClCompile>
<ClCompile Include="..\..\..\..\modules\juce_graphics\native\juce_Direct2DMetrics_windows.cpp">
<Filter>JUCE Modules\juce_graphics\native</Filter>
</ClCompile>
<ClCompile Include="..\..\..\..\modules\juce_graphics\native\juce_Direct2DResources_windows.cpp">
<Filter>JUCE Modules\juce_graphics\native</Filter>
</ClCompile>
<ClCompile Include="..\..\..\..\modules\juce_graphics\native\juce_DirectWriteTypeface_windows.cpp">
<Filter>JUCE Modules\juce_graphics\native</Filter>
</ClCompile>
@ -6369,6 +6387,24 @@
<ClInclude Include="..\..\..\..\modules\juce_graphics\native\juce_Direct2DGraphicsContext_windows.h">
<Filter>JUCE Modules\juce_graphics\native</Filter>
</ClInclude>
<ClInclude Include="..\..\..\..\modules\juce_graphics\native\juce_Direct2DHwndContext_windows.h">
<Filter>JUCE Modules\juce_graphics\native</Filter>
</ClInclude>
<ClInclude Include="..\..\..\..\modules\juce_graphics\native\juce_Direct2DImage_windows.h">
<Filter>JUCE Modules\juce_graphics\native</Filter>
</ClInclude>
<ClInclude Include="..\..\..\..\modules\juce_graphics\native\juce_Direct2DImageContext_windows.h">
<Filter>JUCE Modules\juce_graphics\native</Filter>
</ClInclude>
<ClInclude Include="..\..\..\..\modules\juce_graphics\native\juce_Direct2DMetrics_windows.h">
<Filter>JUCE Modules\juce_graphics\native</Filter>
</ClInclude>
<ClInclude Include="..\..\..\..\modules\juce_graphics\native\juce_DirectX_windows.h">
<Filter>JUCE Modules\juce_graphics\native</Filter>
</ClInclude>
<ClInclude Include="..\..\..\..\modules\juce_graphics\native\juce_EventTracing.h">
<Filter>JUCE Modules\juce_graphics\native</Filter>
</ClInclude>
<ClInclude Include="..\..\..\..\modules\juce_graphics\native\juce_RenderingHelpers.h">
<Filter>JUCE Modules\juce_graphics\native</Filter>
</ClInclude>
@ -6534,6 +6570,9 @@
<ClInclude Include="..\..\..\..\modules\juce_gui_basics\detail\juce_ScopedMessageBoxInterface.h">
<Filter>JUCE Modules\juce_gui_basics\detail</Filter>
</ClInclude>
<ClInclude Include="..\..\..\..\modules\juce_gui_basics\detail\juce_StandardCachedComponentImage.h">
<Filter>JUCE Modules\juce_gui_basics\detail</Filter>
</ClInclude>
<ClInclude Include="..\..\..\..\modules\juce_gui_basics\detail\juce_ToolbarItemDragAndDropOverlayComponent.h">
<Filter>JUCE Modules\juce_gui_basics\detail</Filter>
</ClInclude>

View file

@ -1841,8 +1841,20 @@ add_library( ${BINARY_NAME}
"../../../../../modules/juce_graphics/native/juce_CoreGraphicsHelpers_mac.h"
"../../../../../modules/juce_graphics/native/juce_Direct2DGraphicsContext_windows.cpp"
"../../../../../modules/juce_graphics/native/juce_Direct2DGraphicsContext_windows.h"
"../../../../../modules/juce_graphics/native/juce_Direct2DHelpers_windows.cpp"
"../../../../../modules/juce_graphics/native/juce_Direct2DHwndContext_windows.cpp"
"../../../../../modules/juce_graphics/native/juce_Direct2DHwndContext_windows.h"
"../../../../../modules/juce_graphics/native/juce_Direct2DImage_windows.cpp"
"../../../../../modules/juce_graphics/native/juce_Direct2DImage_windows.h"
"../../../../../modules/juce_graphics/native/juce_Direct2DImageContext_windows.cpp"
"../../../../../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_Direct2DResources_windows.cpp"
"../../../../../modules/juce_graphics/native/juce_DirectWriteTypeface_windows.cpp"
"../../../../../modules/juce_graphics/native/juce_DirectWriteTypeLayout_windows.cpp"
"../../../../../modules/juce_graphics/native/juce_DirectX_windows.h"
"../../../../../modules/juce_graphics/native/juce_EventTracing.h"
"../../../../../modules/juce_graphics/native/juce_Fonts_android.cpp"
"../../../../../modules/juce_graphics/native/juce_Fonts_freetype.cpp"
"../../../../../modules/juce_graphics/native/juce_Fonts_linux.cpp"
@ -1942,6 +1954,7 @@ add_library( ${BINARY_NAME}
"../../../../../modules/juce_gui_basics/detail/juce_ScopedContentSharerInterface.h"
"../../../../../modules/juce_gui_basics/detail/juce_ScopedMessageBoxImpl.h"
"../../../../../modules/juce_gui_basics/detail/juce_ScopedMessageBoxInterface.h"
"../../../../../modules/juce_gui_basics/detail/juce_StandardCachedComponentImage.h"
"../../../../../modules/juce_gui_basics/detail/juce_ToolbarItemDragAndDropOverlayComponent.h"
"../../../../../modules/juce_gui_basics/detail/juce_TopLevelWindowManager.h"
"../../../../../modules/juce_gui_basics/detail/juce_ViewportHelpers.h"
@ -4159,8 +4172,20 @@ set_source_files_properties(
"../../../../../modules/juce_graphics/native/juce_CoreGraphicsHelpers_mac.h"
"../../../../../modules/juce_graphics/native/juce_Direct2DGraphicsContext_windows.cpp"
"../../../../../modules/juce_graphics/native/juce_Direct2DGraphicsContext_windows.h"
"../../../../../modules/juce_graphics/native/juce_Direct2DHelpers_windows.cpp"
"../../../../../modules/juce_graphics/native/juce_Direct2DHwndContext_windows.cpp"
"../../../../../modules/juce_graphics/native/juce_Direct2DHwndContext_windows.h"
"../../../../../modules/juce_graphics/native/juce_Direct2DImage_windows.cpp"
"../../../../../modules/juce_graphics/native/juce_Direct2DImage_windows.h"
"../../../../../modules/juce_graphics/native/juce_Direct2DImageContext_windows.cpp"
"../../../../../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_Direct2DResources_windows.cpp"
"../../../../../modules/juce_graphics/native/juce_DirectWriteTypeface_windows.cpp"
"../../../../../modules/juce_graphics/native/juce_DirectWriteTypeLayout_windows.cpp"
"../../../../../modules/juce_graphics/native/juce_DirectX_windows.h"
"../../../../../modules/juce_graphics/native/juce_EventTracing.h"
"../../../../../modules/juce_graphics/native/juce_Fonts_android.cpp"
"../../../../../modules/juce_graphics/native/juce_Fonts_freetype.cpp"
"../../../../../modules/juce_graphics/native/juce_Fonts_linux.cpp"
@ -4260,6 +4285,7 @@ set_source_files_properties(
"../../../../../modules/juce_gui_basics/detail/juce_ScopedContentSharerInterface.h"
"../../../../../modules/juce_gui_basics/detail/juce_ScopedMessageBoxImpl.h"
"../../../../../modules/juce_gui_basics/detail/juce_ScopedMessageBoxInterface.h"
"../../../../../modules/juce_gui_basics/detail/juce_StandardCachedComponentImage.h"
"../../../../../modules/juce_gui_basics/detail/juce_ToolbarItemDragAndDropOverlayComponent.h"
"../../../../../modules/juce_gui_basics/detail/juce_TopLevelWindowManager.h"
"../../../../../modules/juce_gui_basics/detail/juce_ViewportHelpers.h"

View file

@ -2178,6 +2178,24 @@
<ClCompile Include="..\..\..\..\modules\juce_graphics\native\juce_Direct2DGraphicsContext_windows.cpp">
<ExcludedFromBuild>true</ExcludedFromBuild>
</ClCompile>
<ClCompile Include="..\..\..\..\modules\juce_graphics\native\juce_Direct2DHelpers_windows.cpp">
<ExcludedFromBuild>true</ExcludedFromBuild>
</ClCompile>
<ClCompile Include="..\..\..\..\modules\juce_graphics\native\juce_Direct2DHwndContext_windows.cpp">
<ExcludedFromBuild>true</ExcludedFromBuild>
</ClCompile>
<ClCompile Include="..\..\..\..\modules\juce_graphics\native\juce_Direct2DImage_windows.cpp">
<ExcludedFromBuild>true</ExcludedFromBuild>
</ClCompile>
<ClCompile Include="..\..\..\..\modules\juce_graphics\native\juce_Direct2DImageContext_windows.cpp">
<ExcludedFromBuild>true</ExcludedFromBuild>
</ClCompile>
<ClCompile Include="..\..\..\..\modules\juce_graphics\native\juce_Direct2DMetrics_windows.cpp">
<ExcludedFromBuild>true</ExcludedFromBuild>
</ClCompile>
<ClCompile Include="..\..\..\..\modules\juce_graphics\native\juce_Direct2DResources_windows.cpp">
<ExcludedFromBuild>true</ExcludedFromBuild>
</ClCompile>
<ClCompile Include="..\..\..\..\modules\juce_graphics\native\juce_DirectWriteTypeface_windows.cpp">
<ExcludedFromBuild>true</ExcludedFromBuild>
</ClCompile>
@ -3924,6 +3942,12 @@
<ClInclude Include="..\..\..\..\modules\juce_graphics\native\juce_CoreGraphicsContext_mac.h"/>
<ClInclude Include="..\..\..\..\modules\juce_graphics\native\juce_CoreGraphicsHelpers_mac.h"/>
<ClInclude Include="..\..\..\..\modules\juce_graphics\native\juce_Direct2DGraphicsContext_windows.h"/>
<ClInclude Include="..\..\..\..\modules\juce_graphics\native\juce_Direct2DHwndContext_windows.h"/>
<ClInclude Include="..\..\..\..\modules\juce_graphics\native\juce_Direct2DImage_windows.h"/>
<ClInclude Include="..\..\..\..\modules\juce_graphics\native\juce_Direct2DImageContext_windows.h"/>
<ClInclude Include="..\..\..\..\modules\juce_graphics\native\juce_Direct2DMetrics_windows.h"/>
<ClInclude Include="..\..\..\..\modules\juce_graphics\native\juce_DirectX_windows.h"/>
<ClInclude Include="..\..\..\..\modules\juce_graphics\native\juce_EventTracing.h"/>
<ClInclude Include="..\..\..\..\modules\juce_graphics\native\juce_RenderingHelpers.h"/>
<ClInclude Include="..\..\..\..\modules\juce_graphics\placement\juce_Justification.h"/>
<ClInclude Include="..\..\..\..\modules\juce_graphics\placement\juce_RectanglePlacement.h"/>
@ -3979,6 +4003,7 @@
<ClInclude Include="..\..\..\..\modules\juce_gui_basics\detail\juce_ScopedContentSharerInterface.h"/>
<ClInclude Include="..\..\..\..\modules\juce_gui_basics\detail\juce_ScopedMessageBoxImpl.h"/>
<ClInclude Include="..\..\..\..\modules\juce_gui_basics\detail\juce_ScopedMessageBoxInterface.h"/>
<ClInclude Include="..\..\..\..\modules\juce_gui_basics\detail\juce_StandardCachedComponentImage.h"/>
<ClInclude Include="..\..\..\..\modules\juce_gui_basics\detail\juce_ToolbarItemDragAndDropOverlayComponent.h"/>
<ClInclude Include="..\..\..\..\modules\juce_gui_basics\detail\juce_TopLevelWindowManager.h"/>
<ClInclude Include="..\..\..\..\modules\juce_gui_basics\detail\juce_ViewportHelpers.h"/>

View file

@ -2854,6 +2854,24 @@
<ClCompile Include="..\..\..\..\modules\juce_graphics\native\juce_Direct2DGraphicsContext_windows.cpp">
<Filter>JUCE Modules\juce_graphics\native</Filter>
</ClCompile>
<ClCompile Include="..\..\..\..\modules\juce_graphics\native\juce_Direct2DHelpers_windows.cpp">
<Filter>JUCE Modules\juce_graphics\native</Filter>
</ClCompile>
<ClCompile Include="..\..\..\..\modules\juce_graphics\native\juce_Direct2DHwndContext_windows.cpp">
<Filter>JUCE Modules\juce_graphics\native</Filter>
</ClCompile>
<ClCompile Include="..\..\..\..\modules\juce_graphics\native\juce_Direct2DImage_windows.cpp">
<Filter>JUCE Modules\juce_graphics\native</Filter>
</ClCompile>
<ClCompile Include="..\..\..\..\modules\juce_graphics\native\juce_Direct2DImageContext_windows.cpp">
<Filter>JUCE Modules\juce_graphics\native</Filter>
</ClCompile>
<ClCompile Include="..\..\..\..\modules\juce_graphics\native\juce_Direct2DMetrics_windows.cpp">
<Filter>JUCE Modules\juce_graphics\native</Filter>
</ClCompile>
<ClCompile Include="..\..\..\..\modules\juce_graphics\native\juce_Direct2DResources_windows.cpp">
<Filter>JUCE Modules\juce_graphics\native</Filter>
</ClCompile>
<ClCompile Include="..\..\..\..\modules\juce_graphics\native\juce_DirectWriteTypeface_windows.cpp">
<Filter>JUCE Modules\juce_graphics\native</Filter>
</ClCompile>
@ -6804,6 +6822,24 @@
<ClInclude Include="..\..\..\..\modules\juce_graphics\native\juce_Direct2DGraphicsContext_windows.h">
<Filter>JUCE Modules\juce_graphics\native</Filter>
</ClInclude>
<ClInclude Include="..\..\..\..\modules\juce_graphics\native\juce_Direct2DHwndContext_windows.h">
<Filter>JUCE Modules\juce_graphics\native</Filter>
</ClInclude>
<ClInclude Include="..\..\..\..\modules\juce_graphics\native\juce_Direct2DImage_windows.h">
<Filter>JUCE Modules\juce_graphics\native</Filter>
</ClInclude>
<ClInclude Include="..\..\..\..\modules\juce_graphics\native\juce_Direct2DImageContext_windows.h">
<Filter>JUCE Modules\juce_graphics\native</Filter>
</ClInclude>
<ClInclude Include="..\..\..\..\modules\juce_graphics\native\juce_Direct2DMetrics_windows.h">
<Filter>JUCE Modules\juce_graphics\native</Filter>
</ClInclude>
<ClInclude Include="..\..\..\..\modules\juce_graphics\native\juce_DirectX_windows.h">
<Filter>JUCE Modules\juce_graphics\native</Filter>
</ClInclude>
<ClInclude Include="..\..\..\..\modules\juce_graphics\native\juce_EventTracing.h">
<Filter>JUCE Modules\juce_graphics\native</Filter>
</ClInclude>
<ClInclude Include="..\..\..\..\modules\juce_graphics\native\juce_RenderingHelpers.h">
<Filter>JUCE Modules\juce_graphics\native</Filter>
</ClInclude>
@ -6969,6 +7005,9 @@
<ClInclude Include="..\..\..\..\modules\juce_gui_basics\detail\juce_ScopedMessageBoxInterface.h">
<Filter>JUCE Modules\juce_gui_basics\detail</Filter>
</ClInclude>
<ClInclude Include="..\..\..\..\modules\juce_gui_basics\detail\juce_StandardCachedComponentImage.h">
<Filter>JUCE Modules\juce_gui_basics\detail</Filter>
</ClInclude>
<ClInclude Include="..\..\..\..\modules\juce_gui_basics\detail\juce_ToolbarItemDragAndDropOverlayComponent.h">
<Filter>JUCE Modules\juce_gui_basics\detail</Filter>
</ClInclude>

View file

@ -2178,6 +2178,24 @@
<ClCompile Include="..\..\..\..\modules\juce_graphics\native\juce_Direct2DGraphicsContext_windows.cpp">
<ExcludedFromBuild>true</ExcludedFromBuild>
</ClCompile>
<ClCompile Include="..\..\..\..\modules\juce_graphics\native\juce_Direct2DHelpers_windows.cpp">
<ExcludedFromBuild>true</ExcludedFromBuild>
</ClCompile>
<ClCompile Include="..\..\..\..\modules\juce_graphics\native\juce_Direct2DHwndContext_windows.cpp">
<ExcludedFromBuild>true</ExcludedFromBuild>
</ClCompile>
<ClCompile Include="..\..\..\..\modules\juce_graphics\native\juce_Direct2DImage_windows.cpp">
<ExcludedFromBuild>true</ExcludedFromBuild>
</ClCompile>
<ClCompile Include="..\..\..\..\modules\juce_graphics\native\juce_Direct2DImageContext_windows.cpp">
<ExcludedFromBuild>true</ExcludedFromBuild>
</ClCompile>
<ClCompile Include="..\..\..\..\modules\juce_graphics\native\juce_Direct2DMetrics_windows.cpp">
<ExcludedFromBuild>true</ExcludedFromBuild>
</ClCompile>
<ClCompile Include="..\..\..\..\modules\juce_graphics\native\juce_Direct2DResources_windows.cpp">
<ExcludedFromBuild>true</ExcludedFromBuild>
</ClCompile>
<ClCompile Include="..\..\..\..\modules\juce_graphics\native\juce_DirectWriteTypeface_windows.cpp">
<ExcludedFromBuild>true</ExcludedFromBuild>
</ClCompile>
@ -3924,6 +3942,12 @@
<ClInclude Include="..\..\..\..\modules\juce_graphics\native\juce_CoreGraphicsContext_mac.h"/>
<ClInclude Include="..\..\..\..\modules\juce_graphics\native\juce_CoreGraphicsHelpers_mac.h"/>
<ClInclude Include="..\..\..\..\modules\juce_graphics\native\juce_Direct2DGraphicsContext_windows.h"/>
<ClInclude Include="..\..\..\..\modules\juce_graphics\native\juce_Direct2DHwndContext_windows.h"/>
<ClInclude Include="..\..\..\..\modules\juce_graphics\native\juce_Direct2DImage_windows.h"/>
<ClInclude Include="..\..\..\..\modules\juce_graphics\native\juce_Direct2DImageContext_windows.h"/>
<ClInclude Include="..\..\..\..\modules\juce_graphics\native\juce_Direct2DMetrics_windows.h"/>
<ClInclude Include="..\..\..\..\modules\juce_graphics\native\juce_DirectX_windows.h"/>
<ClInclude Include="..\..\..\..\modules\juce_graphics\native\juce_EventTracing.h"/>
<ClInclude Include="..\..\..\..\modules\juce_graphics\native\juce_RenderingHelpers.h"/>
<ClInclude Include="..\..\..\..\modules\juce_graphics\placement\juce_Justification.h"/>
<ClInclude Include="..\..\..\..\modules\juce_graphics\placement\juce_RectanglePlacement.h"/>
@ -3979,6 +4003,7 @@
<ClInclude Include="..\..\..\..\modules\juce_gui_basics\detail\juce_ScopedContentSharerInterface.h"/>
<ClInclude Include="..\..\..\..\modules\juce_gui_basics\detail\juce_ScopedMessageBoxImpl.h"/>
<ClInclude Include="..\..\..\..\modules\juce_gui_basics\detail\juce_ScopedMessageBoxInterface.h"/>
<ClInclude Include="..\..\..\..\modules\juce_gui_basics\detail\juce_StandardCachedComponentImage.h"/>
<ClInclude Include="..\..\..\..\modules\juce_gui_basics\detail\juce_ToolbarItemDragAndDropOverlayComponent.h"/>
<ClInclude Include="..\..\..\..\modules\juce_gui_basics\detail\juce_TopLevelWindowManager.h"/>
<ClInclude Include="..\..\..\..\modules\juce_gui_basics\detail\juce_ViewportHelpers.h"/>

View file

@ -2854,6 +2854,24 @@
<ClCompile Include="..\..\..\..\modules\juce_graphics\native\juce_Direct2DGraphicsContext_windows.cpp">
<Filter>JUCE Modules\juce_graphics\native</Filter>
</ClCompile>
<ClCompile Include="..\..\..\..\modules\juce_graphics\native\juce_Direct2DHelpers_windows.cpp">
<Filter>JUCE Modules\juce_graphics\native</Filter>
</ClCompile>
<ClCompile Include="..\..\..\..\modules\juce_graphics\native\juce_Direct2DHwndContext_windows.cpp">
<Filter>JUCE Modules\juce_graphics\native</Filter>
</ClCompile>
<ClCompile Include="..\..\..\..\modules\juce_graphics\native\juce_Direct2DImage_windows.cpp">
<Filter>JUCE Modules\juce_graphics\native</Filter>
</ClCompile>
<ClCompile Include="..\..\..\..\modules\juce_graphics\native\juce_Direct2DImageContext_windows.cpp">
<Filter>JUCE Modules\juce_graphics\native</Filter>
</ClCompile>
<ClCompile Include="..\..\..\..\modules\juce_graphics\native\juce_Direct2DMetrics_windows.cpp">
<Filter>JUCE Modules\juce_graphics\native</Filter>
</ClCompile>
<ClCompile Include="..\..\..\..\modules\juce_graphics\native\juce_Direct2DResources_windows.cpp">
<Filter>JUCE Modules\juce_graphics\native</Filter>
</ClCompile>
<ClCompile Include="..\..\..\..\modules\juce_graphics\native\juce_DirectWriteTypeface_windows.cpp">
<Filter>JUCE Modules\juce_graphics\native</Filter>
</ClCompile>
@ -6804,6 +6822,24 @@
<ClInclude Include="..\..\..\..\modules\juce_graphics\native\juce_Direct2DGraphicsContext_windows.h">
<Filter>JUCE Modules\juce_graphics\native</Filter>
</ClInclude>
<ClInclude Include="..\..\..\..\modules\juce_graphics\native\juce_Direct2DHwndContext_windows.h">
<Filter>JUCE Modules\juce_graphics\native</Filter>
</ClInclude>
<ClInclude Include="..\..\..\..\modules\juce_graphics\native\juce_Direct2DImage_windows.h">
<Filter>JUCE Modules\juce_graphics\native</Filter>
</ClInclude>
<ClInclude Include="..\..\..\..\modules\juce_graphics\native\juce_Direct2DImageContext_windows.h">
<Filter>JUCE Modules\juce_graphics\native</Filter>
</ClInclude>
<ClInclude Include="..\..\..\..\modules\juce_graphics\native\juce_Direct2DMetrics_windows.h">
<Filter>JUCE Modules\juce_graphics\native</Filter>
</ClInclude>
<ClInclude Include="..\..\..\..\modules\juce_graphics\native\juce_DirectX_windows.h">
<Filter>JUCE Modules\juce_graphics\native</Filter>
</ClInclude>
<ClInclude Include="..\..\..\..\modules\juce_graphics\native\juce_EventTracing.h">
<Filter>JUCE Modules\juce_graphics\native</Filter>
</ClInclude>
<ClInclude Include="..\..\..\..\modules\juce_graphics\native\juce_RenderingHelpers.h">
<Filter>JUCE Modules\juce_graphics\native</Filter>
</ClInclude>
@ -6969,6 +7005,9 @@
<ClInclude Include="..\..\..\..\modules\juce_gui_basics\detail\juce_ScopedMessageBoxInterface.h">
<Filter>JUCE Modules\juce_gui_basics\detail</Filter>
</ClInclude>
<ClInclude Include="..\..\..\..\modules\juce_gui_basics\detail\juce_StandardCachedComponentImage.h">
<Filter>JUCE Modules\juce_gui_basics\detail</Filter>
</ClInclude>
<ClInclude Include="..\..\..\..\modules\juce_gui_basics\detail\juce_ToolbarItemDragAndDropOverlayComponent.h">
<Filter>JUCE Modules\juce_gui_basics\detail</Filter>
</ClInclude>

View file

@ -2178,6 +2178,24 @@
<ClCompile Include="..\..\..\..\modules\juce_graphics\native\juce_Direct2DGraphicsContext_windows.cpp">
<ExcludedFromBuild>true</ExcludedFromBuild>
</ClCompile>
<ClCompile Include="..\..\..\..\modules\juce_graphics\native\juce_Direct2DHelpers_windows.cpp">
<ExcludedFromBuild>true</ExcludedFromBuild>
</ClCompile>
<ClCompile Include="..\..\..\..\modules\juce_graphics\native\juce_Direct2DHwndContext_windows.cpp">
<ExcludedFromBuild>true</ExcludedFromBuild>
</ClCompile>
<ClCompile Include="..\..\..\..\modules\juce_graphics\native\juce_Direct2DImage_windows.cpp">
<ExcludedFromBuild>true</ExcludedFromBuild>
</ClCompile>
<ClCompile Include="..\..\..\..\modules\juce_graphics\native\juce_Direct2DImageContext_windows.cpp">
<ExcludedFromBuild>true</ExcludedFromBuild>
</ClCompile>
<ClCompile Include="..\..\..\..\modules\juce_graphics\native\juce_Direct2DMetrics_windows.cpp">
<ExcludedFromBuild>true</ExcludedFromBuild>
</ClCompile>
<ClCompile Include="..\..\..\..\modules\juce_graphics\native\juce_Direct2DResources_windows.cpp">
<ExcludedFromBuild>true</ExcludedFromBuild>
</ClCompile>
<ClCompile Include="..\..\..\..\modules\juce_graphics\native\juce_DirectWriteTypeface_windows.cpp">
<ExcludedFromBuild>true</ExcludedFromBuild>
</ClCompile>
@ -3924,6 +3942,12 @@
<ClInclude Include="..\..\..\..\modules\juce_graphics\native\juce_CoreGraphicsContext_mac.h"/>
<ClInclude Include="..\..\..\..\modules\juce_graphics\native\juce_CoreGraphicsHelpers_mac.h"/>
<ClInclude Include="..\..\..\..\modules\juce_graphics\native\juce_Direct2DGraphicsContext_windows.h"/>
<ClInclude Include="..\..\..\..\modules\juce_graphics\native\juce_Direct2DHwndContext_windows.h"/>
<ClInclude Include="..\..\..\..\modules\juce_graphics\native\juce_Direct2DImage_windows.h"/>
<ClInclude Include="..\..\..\..\modules\juce_graphics\native\juce_Direct2DImageContext_windows.h"/>
<ClInclude Include="..\..\..\..\modules\juce_graphics\native\juce_Direct2DMetrics_windows.h"/>
<ClInclude Include="..\..\..\..\modules\juce_graphics\native\juce_DirectX_windows.h"/>
<ClInclude Include="..\..\..\..\modules\juce_graphics\native\juce_EventTracing.h"/>
<ClInclude Include="..\..\..\..\modules\juce_graphics\native\juce_RenderingHelpers.h"/>
<ClInclude Include="..\..\..\..\modules\juce_graphics\placement\juce_Justification.h"/>
<ClInclude Include="..\..\..\..\modules\juce_graphics\placement\juce_RectanglePlacement.h"/>
@ -3979,6 +4003,7 @@
<ClInclude Include="..\..\..\..\modules\juce_gui_basics\detail\juce_ScopedContentSharerInterface.h"/>
<ClInclude Include="..\..\..\..\modules\juce_gui_basics\detail\juce_ScopedMessageBoxImpl.h"/>
<ClInclude Include="..\..\..\..\modules\juce_gui_basics\detail\juce_ScopedMessageBoxInterface.h"/>
<ClInclude Include="..\..\..\..\modules\juce_gui_basics\detail\juce_StandardCachedComponentImage.h"/>
<ClInclude Include="..\..\..\..\modules\juce_gui_basics\detail\juce_ToolbarItemDragAndDropOverlayComponent.h"/>
<ClInclude Include="..\..\..\..\modules\juce_gui_basics\detail\juce_TopLevelWindowManager.h"/>
<ClInclude Include="..\..\..\..\modules\juce_gui_basics\detail\juce_ViewportHelpers.h"/>

View file

@ -2854,6 +2854,24 @@
<ClCompile Include="..\..\..\..\modules\juce_graphics\native\juce_Direct2DGraphicsContext_windows.cpp">
<Filter>JUCE Modules\juce_graphics\native</Filter>
</ClCompile>
<ClCompile Include="..\..\..\..\modules\juce_graphics\native\juce_Direct2DHelpers_windows.cpp">
<Filter>JUCE Modules\juce_graphics\native</Filter>
</ClCompile>
<ClCompile Include="..\..\..\..\modules\juce_graphics\native\juce_Direct2DHwndContext_windows.cpp">
<Filter>JUCE Modules\juce_graphics\native</Filter>
</ClCompile>
<ClCompile Include="..\..\..\..\modules\juce_graphics\native\juce_Direct2DImage_windows.cpp">
<Filter>JUCE Modules\juce_graphics\native</Filter>
</ClCompile>
<ClCompile Include="..\..\..\..\modules\juce_graphics\native\juce_Direct2DImageContext_windows.cpp">
<Filter>JUCE Modules\juce_graphics\native</Filter>
</ClCompile>
<ClCompile Include="..\..\..\..\modules\juce_graphics\native\juce_Direct2DMetrics_windows.cpp">
<Filter>JUCE Modules\juce_graphics\native</Filter>
</ClCompile>
<ClCompile Include="..\..\..\..\modules\juce_graphics\native\juce_Direct2DResources_windows.cpp">
<Filter>JUCE Modules\juce_graphics\native</Filter>
</ClCompile>
<ClCompile Include="..\..\..\..\modules\juce_graphics\native\juce_DirectWriteTypeface_windows.cpp">
<Filter>JUCE Modules\juce_graphics\native</Filter>
</ClCompile>
@ -6804,6 +6822,24 @@
<ClInclude Include="..\..\..\..\modules\juce_graphics\native\juce_Direct2DGraphicsContext_windows.h">
<Filter>JUCE Modules\juce_graphics\native</Filter>
</ClInclude>
<ClInclude Include="..\..\..\..\modules\juce_graphics\native\juce_Direct2DHwndContext_windows.h">
<Filter>JUCE Modules\juce_graphics\native</Filter>
</ClInclude>
<ClInclude Include="..\..\..\..\modules\juce_graphics\native\juce_Direct2DImage_windows.h">
<Filter>JUCE Modules\juce_graphics\native</Filter>
</ClInclude>
<ClInclude Include="..\..\..\..\modules\juce_graphics\native\juce_Direct2DImageContext_windows.h">
<Filter>JUCE Modules\juce_graphics\native</Filter>
</ClInclude>
<ClInclude Include="..\..\..\..\modules\juce_graphics\native\juce_Direct2DMetrics_windows.h">
<Filter>JUCE Modules\juce_graphics\native</Filter>
</ClInclude>
<ClInclude Include="..\..\..\..\modules\juce_graphics\native\juce_DirectX_windows.h">
<Filter>JUCE Modules\juce_graphics\native</Filter>
</ClInclude>
<ClInclude Include="..\..\..\..\modules\juce_graphics\native\juce_EventTracing.h">
<Filter>JUCE Modules\juce_graphics\native</Filter>
</ClInclude>
<ClInclude Include="..\..\..\..\modules\juce_graphics\native\juce_RenderingHelpers.h">
<Filter>JUCE Modules\juce_graphics\native</Filter>
</ClInclude>
@ -6969,6 +7005,9 @@
<ClInclude Include="..\..\..\..\modules\juce_gui_basics\detail\juce_ScopedMessageBoxInterface.h">
<Filter>JUCE Modules\juce_gui_basics\detail</Filter>
</ClInclude>
<ClInclude Include="..\..\..\..\modules\juce_gui_basics\detail\juce_StandardCachedComponentImage.h">
<Filter>JUCE Modules\juce_gui_basics\detail</Filter>
</ClInclude>
<ClInclude Include="..\..\..\..\modules\juce_gui_basics\detail\juce_ToolbarItemDragAndDropOverlayComponent.h">
<Filter>JUCE Modules\juce_gui_basics\detail</Filter>
</ClInclude>

View file

@ -1730,8 +1730,20 @@ add_library( ${BINARY_NAME}
"../../../../../modules/juce_graphics/native/juce_CoreGraphicsHelpers_mac.h"
"../../../../../modules/juce_graphics/native/juce_Direct2DGraphicsContext_windows.cpp"
"../../../../../modules/juce_graphics/native/juce_Direct2DGraphicsContext_windows.h"
"../../../../../modules/juce_graphics/native/juce_Direct2DHelpers_windows.cpp"
"../../../../../modules/juce_graphics/native/juce_Direct2DHwndContext_windows.cpp"
"../../../../../modules/juce_graphics/native/juce_Direct2DHwndContext_windows.h"
"../../../../../modules/juce_graphics/native/juce_Direct2DImage_windows.cpp"
"../../../../../modules/juce_graphics/native/juce_Direct2DImage_windows.h"
"../../../../../modules/juce_graphics/native/juce_Direct2DImageContext_windows.cpp"
"../../../../../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_Direct2DResources_windows.cpp"
"../../../../../modules/juce_graphics/native/juce_DirectWriteTypeface_windows.cpp"
"../../../../../modules/juce_graphics/native/juce_DirectWriteTypeLayout_windows.cpp"
"../../../../../modules/juce_graphics/native/juce_DirectX_windows.h"
"../../../../../modules/juce_graphics/native/juce_EventTracing.h"
"../../../../../modules/juce_graphics/native/juce_Fonts_android.cpp"
"../../../../../modules/juce_graphics/native/juce_Fonts_freetype.cpp"
"../../../../../modules/juce_graphics/native/juce_Fonts_linux.cpp"
@ -1831,6 +1843,7 @@ add_library( ${BINARY_NAME}
"../../../../../modules/juce_gui_basics/detail/juce_ScopedContentSharerInterface.h"
"../../../../../modules/juce_gui_basics/detail/juce_ScopedMessageBoxImpl.h"
"../../../../../modules/juce_gui_basics/detail/juce_ScopedMessageBoxInterface.h"
"../../../../../modules/juce_gui_basics/detail/juce_StandardCachedComponentImage.h"
"../../../../../modules/juce_gui_basics/detail/juce_ToolbarItemDragAndDropOverlayComponent.h"
"../../../../../modules/juce_gui_basics/detail/juce_TopLevelWindowManager.h"
"../../../../../modules/juce_gui_basics/detail/juce_ViewportHelpers.h"
@ -3975,8 +3988,20 @@ set_source_files_properties(
"../../../../../modules/juce_graphics/native/juce_CoreGraphicsHelpers_mac.h"
"../../../../../modules/juce_graphics/native/juce_Direct2DGraphicsContext_windows.cpp"
"../../../../../modules/juce_graphics/native/juce_Direct2DGraphicsContext_windows.h"
"../../../../../modules/juce_graphics/native/juce_Direct2DHelpers_windows.cpp"
"../../../../../modules/juce_graphics/native/juce_Direct2DHwndContext_windows.cpp"
"../../../../../modules/juce_graphics/native/juce_Direct2DHwndContext_windows.h"
"../../../../../modules/juce_graphics/native/juce_Direct2DImage_windows.cpp"
"../../../../../modules/juce_graphics/native/juce_Direct2DImage_windows.h"
"../../../../../modules/juce_graphics/native/juce_Direct2DImageContext_windows.cpp"
"../../../../../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_Direct2DResources_windows.cpp"
"../../../../../modules/juce_graphics/native/juce_DirectWriteTypeface_windows.cpp"
"../../../../../modules/juce_graphics/native/juce_DirectWriteTypeLayout_windows.cpp"
"../../../../../modules/juce_graphics/native/juce_DirectX_windows.h"
"../../../../../modules/juce_graphics/native/juce_EventTracing.h"
"../../../../../modules/juce_graphics/native/juce_Fonts_android.cpp"
"../../../../../modules/juce_graphics/native/juce_Fonts_freetype.cpp"
"../../../../../modules/juce_graphics/native/juce_Fonts_linux.cpp"
@ -4076,6 +4101,7 @@ set_source_files_properties(
"../../../../../modules/juce_gui_basics/detail/juce_ScopedContentSharerInterface.h"
"../../../../../modules/juce_gui_basics/detail/juce_ScopedMessageBoxImpl.h"
"../../../../../modules/juce_gui_basics/detail/juce_ScopedMessageBoxInterface.h"
"../../../../../modules/juce_gui_basics/detail/juce_StandardCachedComponentImage.h"
"../../../../../modules/juce_gui_basics/detail/juce_ToolbarItemDragAndDropOverlayComponent.h"
"../../../../../modules/juce_gui_basics/detail/juce_TopLevelWindowManager.h"
"../../../../../modules/juce_gui_basics/detail/juce_ViewportHelpers.h"

View file

@ -2065,6 +2065,24 @@
<ClCompile Include="..\..\..\..\modules\juce_graphics\native\juce_Direct2DGraphicsContext_windows.cpp">
<ExcludedFromBuild>true</ExcludedFromBuild>
</ClCompile>
<ClCompile Include="..\..\..\..\modules\juce_graphics\native\juce_Direct2DHelpers_windows.cpp">
<ExcludedFromBuild>true</ExcludedFromBuild>
</ClCompile>
<ClCompile Include="..\..\..\..\modules\juce_graphics\native\juce_Direct2DHwndContext_windows.cpp">
<ExcludedFromBuild>true</ExcludedFromBuild>
</ClCompile>
<ClCompile Include="..\..\..\..\modules\juce_graphics\native\juce_Direct2DImage_windows.cpp">
<ExcludedFromBuild>true</ExcludedFromBuild>
</ClCompile>
<ClCompile Include="..\..\..\..\modules\juce_graphics\native\juce_Direct2DImageContext_windows.cpp">
<ExcludedFromBuild>true</ExcludedFromBuild>
</ClCompile>
<ClCompile Include="..\..\..\..\modules\juce_graphics\native\juce_Direct2DMetrics_windows.cpp">
<ExcludedFromBuild>true</ExcludedFromBuild>
</ClCompile>
<ClCompile Include="..\..\..\..\modules\juce_graphics\native\juce_Direct2DResources_windows.cpp">
<ExcludedFromBuild>true</ExcludedFromBuild>
</ClCompile>
<ClCompile Include="..\..\..\..\modules\juce_graphics\native\juce_DirectWriteTypeface_windows.cpp">
<ExcludedFromBuild>true</ExcludedFromBuild>
</ClCompile>
@ -3789,6 +3807,12 @@
<ClInclude Include="..\..\..\..\modules\juce_graphics\native\juce_CoreGraphicsContext_mac.h"/>
<ClInclude Include="..\..\..\..\modules\juce_graphics\native\juce_CoreGraphicsHelpers_mac.h"/>
<ClInclude Include="..\..\..\..\modules\juce_graphics\native\juce_Direct2DGraphicsContext_windows.h"/>
<ClInclude Include="..\..\..\..\modules\juce_graphics\native\juce_Direct2DHwndContext_windows.h"/>
<ClInclude Include="..\..\..\..\modules\juce_graphics\native\juce_Direct2DImage_windows.h"/>
<ClInclude Include="..\..\..\..\modules\juce_graphics\native\juce_Direct2DImageContext_windows.h"/>
<ClInclude Include="..\..\..\..\modules\juce_graphics\native\juce_Direct2DMetrics_windows.h"/>
<ClInclude Include="..\..\..\..\modules\juce_graphics\native\juce_DirectX_windows.h"/>
<ClInclude Include="..\..\..\..\modules\juce_graphics\native\juce_EventTracing.h"/>
<ClInclude Include="..\..\..\..\modules\juce_graphics\native\juce_RenderingHelpers.h"/>
<ClInclude Include="..\..\..\..\modules\juce_graphics\placement\juce_Justification.h"/>
<ClInclude Include="..\..\..\..\modules\juce_graphics\placement\juce_RectanglePlacement.h"/>
@ -3844,6 +3868,7 @@
<ClInclude Include="..\..\..\..\modules\juce_gui_basics\detail\juce_ScopedContentSharerInterface.h"/>
<ClInclude Include="..\..\..\..\modules\juce_gui_basics\detail\juce_ScopedMessageBoxImpl.h"/>
<ClInclude Include="..\..\..\..\modules\juce_gui_basics\detail\juce_ScopedMessageBoxInterface.h"/>
<ClInclude Include="..\..\..\..\modules\juce_gui_basics\detail\juce_StandardCachedComponentImage.h"/>
<ClInclude Include="..\..\..\..\modules\juce_gui_basics\detail\juce_ToolbarItemDragAndDropOverlayComponent.h"/>
<ClInclude Include="..\..\..\..\modules\juce_gui_basics\detail\juce_TopLevelWindowManager.h"/>
<ClInclude Include="..\..\..\..\modules\juce_gui_basics\detail\juce_ViewportHelpers.h"/>

View file

@ -2701,6 +2701,24 @@
<ClCompile Include="..\..\..\..\modules\juce_graphics\native\juce_Direct2DGraphicsContext_windows.cpp">
<Filter>JUCE Modules\juce_graphics\native</Filter>
</ClCompile>
<ClCompile Include="..\..\..\..\modules\juce_graphics\native\juce_Direct2DHelpers_windows.cpp">
<Filter>JUCE Modules\juce_graphics\native</Filter>
</ClCompile>
<ClCompile Include="..\..\..\..\modules\juce_graphics\native\juce_Direct2DHwndContext_windows.cpp">
<Filter>JUCE Modules\juce_graphics\native</Filter>
</ClCompile>
<ClCompile Include="..\..\..\..\modules\juce_graphics\native\juce_Direct2DImage_windows.cpp">
<Filter>JUCE Modules\juce_graphics\native</Filter>
</ClCompile>
<ClCompile Include="..\..\..\..\modules\juce_graphics\native\juce_Direct2DImageContext_windows.cpp">
<Filter>JUCE Modules\juce_graphics\native</Filter>
</ClCompile>
<ClCompile Include="..\..\..\..\modules\juce_graphics\native\juce_Direct2DMetrics_windows.cpp">
<Filter>JUCE Modules\juce_graphics\native</Filter>
</ClCompile>
<ClCompile Include="..\..\..\..\modules\juce_graphics\native\juce_Direct2DResources_windows.cpp">
<Filter>JUCE Modules\juce_graphics\native</Filter>
</ClCompile>
<ClCompile Include="..\..\..\..\modules\juce_graphics\native\juce_DirectWriteTypeface_windows.cpp">
<Filter>JUCE Modules\juce_graphics\native</Filter>
</ClCompile>
@ -6531,6 +6549,24 @@
<ClInclude Include="..\..\..\..\modules\juce_graphics\native\juce_Direct2DGraphicsContext_windows.h">
<Filter>JUCE Modules\juce_graphics\native</Filter>
</ClInclude>
<ClInclude Include="..\..\..\..\modules\juce_graphics\native\juce_Direct2DHwndContext_windows.h">
<Filter>JUCE Modules\juce_graphics\native</Filter>
</ClInclude>
<ClInclude Include="..\..\..\..\modules\juce_graphics\native\juce_Direct2DImage_windows.h">
<Filter>JUCE Modules\juce_graphics\native</Filter>
</ClInclude>
<ClInclude Include="..\..\..\..\modules\juce_graphics\native\juce_Direct2DImageContext_windows.h">
<Filter>JUCE Modules\juce_graphics\native</Filter>
</ClInclude>
<ClInclude Include="..\..\..\..\modules\juce_graphics\native\juce_Direct2DMetrics_windows.h">
<Filter>JUCE Modules\juce_graphics\native</Filter>
</ClInclude>
<ClInclude Include="..\..\..\..\modules\juce_graphics\native\juce_DirectX_windows.h">
<Filter>JUCE Modules\juce_graphics\native</Filter>
</ClInclude>
<ClInclude Include="..\..\..\..\modules\juce_graphics\native\juce_EventTracing.h">
<Filter>JUCE Modules\juce_graphics\native</Filter>
</ClInclude>
<ClInclude Include="..\..\..\..\modules\juce_graphics\native\juce_RenderingHelpers.h">
<Filter>JUCE Modules\juce_graphics\native</Filter>
</ClInclude>
@ -6696,6 +6732,9 @@
<ClInclude Include="..\..\..\..\modules\juce_gui_basics\detail\juce_ScopedMessageBoxInterface.h">
<Filter>JUCE Modules\juce_gui_basics\detail</Filter>
</ClInclude>
<ClInclude Include="..\..\..\..\modules\juce_gui_basics\detail\juce_StandardCachedComponentImage.h">
<Filter>JUCE Modules\juce_gui_basics\detail</Filter>
</ClInclude>
<ClInclude Include="..\..\..\..\modules\juce_gui_basics\detail\juce_ToolbarItemDragAndDropOverlayComponent.h">
<Filter>JUCE Modules\juce_gui_basics\detail</Filter>
</ClInclude>

View file

@ -307,9 +307,10 @@ public:
}
//==============================================================================
bool isVectorDevice() const override { return true; }
float getPhysicalPixelScaleFactor() override { return 1.0f; }
void setOrigin (Point<int> o) override { addTransform (AffineTransform::translation ((float) o.x, (float) o.y)); }
bool isVectorDevice() const override { return true; }
float getPhysicalPixelScaleFactor() const override { return 1.0f; }
uint64_t getFrameId() const override { return 0; }
void setOrigin (Point<int> o) override { addTransform (AffineTransform::translation ((float) o.x, (float) o.y)); }
void addTransform (const AffineTransform& t) override
{

View file

@ -1247,6 +1247,24 @@
<ClCompile Include="..\..\..\..\modules\juce_graphics\native\juce_Direct2DGraphicsContext_windows.cpp">
<ExcludedFromBuild>true</ExcludedFromBuild>
</ClCompile>
<ClCompile Include="..\..\..\..\modules\juce_graphics\native\juce_Direct2DHelpers_windows.cpp">
<ExcludedFromBuild>true</ExcludedFromBuild>
</ClCompile>
<ClCompile Include="..\..\..\..\modules\juce_graphics\native\juce_Direct2DHwndContext_windows.cpp">
<ExcludedFromBuild>true</ExcludedFromBuild>
</ClCompile>
<ClCompile Include="..\..\..\..\modules\juce_graphics\native\juce_Direct2DImage_windows.cpp">
<ExcludedFromBuild>true</ExcludedFromBuild>
</ClCompile>
<ClCompile Include="..\..\..\..\modules\juce_graphics\native\juce_Direct2DImageContext_windows.cpp">
<ExcludedFromBuild>true</ExcludedFromBuild>
</ClCompile>
<ClCompile Include="..\..\..\..\modules\juce_graphics\native\juce_Direct2DMetrics_windows.cpp">
<ExcludedFromBuild>true</ExcludedFromBuild>
</ClCompile>
<ClCompile Include="..\..\..\..\modules\juce_graphics\native\juce_Direct2DResources_windows.cpp">
<ExcludedFromBuild>true</ExcludedFromBuild>
</ClCompile>
<ClCompile Include="..\..\..\..\modules\juce_graphics\native\juce_DirectWriteTypeface_windows.cpp">
<ExcludedFromBuild>true</ExcludedFromBuild>
</ClCompile>
@ -2606,6 +2624,12 @@
<ClInclude Include="..\..\..\..\modules\juce_graphics\native\juce_CoreGraphicsContext_mac.h"/>
<ClInclude Include="..\..\..\..\modules\juce_graphics\native\juce_CoreGraphicsHelpers_mac.h"/>
<ClInclude Include="..\..\..\..\modules\juce_graphics\native\juce_Direct2DGraphicsContext_windows.h"/>
<ClInclude Include="..\..\..\..\modules\juce_graphics\native\juce_Direct2DHwndContext_windows.h"/>
<ClInclude Include="..\..\..\..\modules\juce_graphics\native\juce_Direct2DImage_windows.h"/>
<ClInclude Include="..\..\..\..\modules\juce_graphics\native\juce_Direct2DImageContext_windows.h"/>
<ClInclude Include="..\..\..\..\modules\juce_graphics\native\juce_Direct2DMetrics_windows.h"/>
<ClInclude Include="..\..\..\..\modules\juce_graphics\native\juce_DirectX_windows.h"/>
<ClInclude Include="..\..\..\..\modules\juce_graphics\native\juce_EventTracing.h"/>
<ClInclude Include="..\..\..\..\modules\juce_graphics\native\juce_RenderingHelpers.h"/>
<ClInclude Include="..\..\..\..\modules\juce_graphics\placement\juce_Justification.h"/>
<ClInclude Include="..\..\..\..\modules\juce_graphics\placement\juce_RectanglePlacement.h"/>
@ -2661,6 +2685,7 @@
<ClInclude Include="..\..\..\..\modules\juce_gui_basics\detail\juce_ScopedContentSharerInterface.h"/>
<ClInclude Include="..\..\..\..\modules\juce_gui_basics\detail\juce_ScopedMessageBoxImpl.h"/>
<ClInclude Include="..\..\..\..\modules\juce_gui_basics\detail\juce_ScopedMessageBoxInterface.h"/>
<ClInclude Include="..\..\..\..\modules\juce_gui_basics\detail\juce_StandardCachedComponentImage.h"/>
<ClInclude Include="..\..\..\..\modules\juce_gui_basics\detail\juce_ToolbarItemDragAndDropOverlayComponent.h"/>
<ClInclude Include="..\..\..\..\modules\juce_gui_basics\detail\juce_TopLevelWindowManager.h"/>
<ClInclude Include="..\..\..\..\modules\juce_gui_basics\detail\juce_ViewportHelpers.h"/>

View file

@ -1645,6 +1645,24 @@
<ClCompile Include="..\..\..\..\modules\juce_graphics\native\juce_Direct2DGraphicsContext_windows.cpp">
<Filter>JUCE Modules\juce_graphics\native</Filter>
</ClCompile>
<ClCompile Include="..\..\..\..\modules\juce_graphics\native\juce_Direct2DHelpers_windows.cpp">
<Filter>JUCE Modules\juce_graphics\native</Filter>
</ClCompile>
<ClCompile Include="..\..\..\..\modules\juce_graphics\native\juce_Direct2DHwndContext_windows.cpp">
<Filter>JUCE Modules\juce_graphics\native</Filter>
</ClCompile>
<ClCompile Include="..\..\..\..\modules\juce_graphics\native\juce_Direct2DImage_windows.cpp">
<Filter>JUCE Modules\juce_graphics\native</Filter>
</ClCompile>
<ClCompile Include="..\..\..\..\modules\juce_graphics\native\juce_Direct2DImageContext_windows.cpp">
<Filter>JUCE Modules\juce_graphics\native</Filter>
</ClCompile>
<ClCompile Include="..\..\..\..\modules\juce_graphics\native\juce_Direct2DMetrics_windows.cpp">
<Filter>JUCE Modules\juce_graphics\native</Filter>
</ClCompile>
<ClCompile Include="..\..\..\..\modules\juce_graphics\native\juce_Direct2DResources_windows.cpp">
<Filter>JUCE Modules\juce_graphics\native</Filter>
</ClCompile>
<ClCompile Include="..\..\..\..\modules\juce_graphics\native\juce_DirectWriteTypeface_windows.cpp">
<Filter>JUCE Modules\juce_graphics\native</Filter>
</ClCompile>
@ -4509,6 +4527,24 @@
<ClInclude Include="..\..\..\..\modules\juce_graphics\native\juce_Direct2DGraphicsContext_windows.h">
<Filter>JUCE Modules\juce_graphics\native</Filter>
</ClInclude>
<ClInclude Include="..\..\..\..\modules\juce_graphics\native\juce_Direct2DHwndContext_windows.h">
<Filter>JUCE Modules\juce_graphics\native</Filter>
</ClInclude>
<ClInclude Include="..\..\..\..\modules\juce_graphics\native\juce_Direct2DImage_windows.h">
<Filter>JUCE Modules\juce_graphics\native</Filter>
</ClInclude>
<ClInclude Include="..\..\..\..\modules\juce_graphics\native\juce_Direct2DImageContext_windows.h">
<Filter>JUCE Modules\juce_graphics\native</Filter>
</ClInclude>
<ClInclude Include="..\..\..\..\modules\juce_graphics\native\juce_Direct2DMetrics_windows.h">
<Filter>JUCE Modules\juce_graphics\native</Filter>
</ClInclude>
<ClInclude Include="..\..\..\..\modules\juce_graphics\native\juce_DirectX_windows.h">
<Filter>JUCE Modules\juce_graphics\native</Filter>
</ClInclude>
<ClInclude Include="..\..\..\..\modules\juce_graphics\native\juce_EventTracing.h">
<Filter>JUCE Modules\juce_graphics\native</Filter>
</ClInclude>
<ClInclude Include="..\..\..\..\modules\juce_graphics\native\juce_RenderingHelpers.h">
<Filter>JUCE Modules\juce_graphics\native</Filter>
</ClInclude>
@ -4674,6 +4710,9 @@
<ClInclude Include="..\..\..\..\modules\juce_gui_basics\detail\juce_ScopedMessageBoxInterface.h">
<Filter>JUCE Modules\juce_gui_basics\detail</Filter>
</ClInclude>
<ClInclude Include="..\..\..\..\modules\juce_gui_basics\detail\juce_StandardCachedComponentImage.h">
<Filter>JUCE Modules\juce_gui_basics\detail</Filter>
</ClInclude>
<ClInclude Include="..\..\..\..\modules\juce_gui_basics\detail\juce_ToolbarItemDragAndDropOverlayComponent.h">
<Filter>JUCE Modules\juce_gui_basics\detail</Filter>
</ClInclude>

View file

@ -1247,6 +1247,24 @@
<ClCompile Include="..\..\..\..\modules\juce_graphics\native\juce_Direct2DGraphicsContext_windows.cpp">
<ExcludedFromBuild>true</ExcludedFromBuild>
</ClCompile>
<ClCompile Include="..\..\..\..\modules\juce_graphics\native\juce_Direct2DHelpers_windows.cpp">
<ExcludedFromBuild>true</ExcludedFromBuild>
</ClCompile>
<ClCompile Include="..\..\..\..\modules\juce_graphics\native\juce_Direct2DHwndContext_windows.cpp">
<ExcludedFromBuild>true</ExcludedFromBuild>
</ClCompile>
<ClCompile Include="..\..\..\..\modules\juce_graphics\native\juce_Direct2DImage_windows.cpp">
<ExcludedFromBuild>true</ExcludedFromBuild>
</ClCompile>
<ClCompile Include="..\..\..\..\modules\juce_graphics\native\juce_Direct2DImageContext_windows.cpp">
<ExcludedFromBuild>true</ExcludedFromBuild>
</ClCompile>
<ClCompile Include="..\..\..\..\modules\juce_graphics\native\juce_Direct2DMetrics_windows.cpp">
<ExcludedFromBuild>true</ExcludedFromBuild>
</ClCompile>
<ClCompile Include="..\..\..\..\modules\juce_graphics\native\juce_Direct2DResources_windows.cpp">
<ExcludedFromBuild>true</ExcludedFromBuild>
</ClCompile>
<ClCompile Include="..\..\..\..\modules\juce_graphics\native\juce_DirectWriteTypeface_windows.cpp">
<ExcludedFromBuild>true</ExcludedFromBuild>
</ClCompile>
@ -2606,6 +2624,12 @@
<ClInclude Include="..\..\..\..\modules\juce_graphics\native\juce_CoreGraphicsContext_mac.h"/>
<ClInclude Include="..\..\..\..\modules\juce_graphics\native\juce_CoreGraphicsHelpers_mac.h"/>
<ClInclude Include="..\..\..\..\modules\juce_graphics\native\juce_Direct2DGraphicsContext_windows.h"/>
<ClInclude Include="..\..\..\..\modules\juce_graphics\native\juce_Direct2DHwndContext_windows.h"/>
<ClInclude Include="..\..\..\..\modules\juce_graphics\native\juce_Direct2DImage_windows.h"/>
<ClInclude Include="..\..\..\..\modules\juce_graphics\native\juce_Direct2DImageContext_windows.h"/>
<ClInclude Include="..\..\..\..\modules\juce_graphics\native\juce_Direct2DMetrics_windows.h"/>
<ClInclude Include="..\..\..\..\modules\juce_graphics\native\juce_DirectX_windows.h"/>
<ClInclude Include="..\..\..\..\modules\juce_graphics\native\juce_EventTracing.h"/>
<ClInclude Include="..\..\..\..\modules\juce_graphics\native\juce_RenderingHelpers.h"/>
<ClInclude Include="..\..\..\..\modules\juce_graphics\placement\juce_Justification.h"/>
<ClInclude Include="..\..\..\..\modules\juce_graphics\placement\juce_RectanglePlacement.h"/>
@ -2661,6 +2685,7 @@
<ClInclude Include="..\..\..\..\modules\juce_gui_basics\detail\juce_ScopedContentSharerInterface.h"/>
<ClInclude Include="..\..\..\..\modules\juce_gui_basics\detail\juce_ScopedMessageBoxImpl.h"/>
<ClInclude Include="..\..\..\..\modules\juce_gui_basics\detail\juce_ScopedMessageBoxInterface.h"/>
<ClInclude Include="..\..\..\..\modules\juce_gui_basics\detail\juce_StandardCachedComponentImage.h"/>
<ClInclude Include="..\..\..\..\modules\juce_gui_basics\detail\juce_ToolbarItemDragAndDropOverlayComponent.h"/>
<ClInclude Include="..\..\..\..\modules\juce_gui_basics\detail\juce_TopLevelWindowManager.h"/>
<ClInclude Include="..\..\..\..\modules\juce_gui_basics\detail\juce_ViewportHelpers.h"/>

View file

@ -1645,6 +1645,24 @@
<ClCompile Include="..\..\..\..\modules\juce_graphics\native\juce_Direct2DGraphicsContext_windows.cpp">
<Filter>JUCE Modules\juce_graphics\native</Filter>
</ClCompile>
<ClCompile Include="..\..\..\..\modules\juce_graphics\native\juce_Direct2DHelpers_windows.cpp">
<Filter>JUCE Modules\juce_graphics\native</Filter>
</ClCompile>
<ClCompile Include="..\..\..\..\modules\juce_graphics\native\juce_Direct2DHwndContext_windows.cpp">
<Filter>JUCE Modules\juce_graphics\native</Filter>
</ClCompile>
<ClCompile Include="..\..\..\..\modules\juce_graphics\native\juce_Direct2DImage_windows.cpp">
<Filter>JUCE Modules\juce_graphics\native</Filter>
</ClCompile>
<ClCompile Include="..\..\..\..\modules\juce_graphics\native\juce_Direct2DImageContext_windows.cpp">
<Filter>JUCE Modules\juce_graphics\native</Filter>
</ClCompile>
<ClCompile Include="..\..\..\..\modules\juce_graphics\native\juce_Direct2DMetrics_windows.cpp">
<Filter>JUCE Modules\juce_graphics\native</Filter>
</ClCompile>
<ClCompile Include="..\..\..\..\modules\juce_graphics\native\juce_Direct2DResources_windows.cpp">
<Filter>JUCE Modules\juce_graphics\native</Filter>
</ClCompile>
<ClCompile Include="..\..\..\..\modules\juce_graphics\native\juce_DirectWriteTypeface_windows.cpp">
<Filter>JUCE Modules\juce_graphics\native</Filter>
</ClCompile>
@ -4509,6 +4527,24 @@
<ClInclude Include="..\..\..\..\modules\juce_graphics\native\juce_Direct2DGraphicsContext_windows.h">
<Filter>JUCE Modules\juce_graphics\native</Filter>
</ClInclude>
<ClInclude Include="..\..\..\..\modules\juce_graphics\native\juce_Direct2DHwndContext_windows.h">
<Filter>JUCE Modules\juce_graphics\native</Filter>
</ClInclude>
<ClInclude Include="..\..\..\..\modules\juce_graphics\native\juce_Direct2DImage_windows.h">
<Filter>JUCE Modules\juce_graphics\native</Filter>
</ClInclude>
<ClInclude Include="..\..\..\..\modules\juce_graphics\native\juce_Direct2DImageContext_windows.h">
<Filter>JUCE Modules\juce_graphics\native</Filter>
</ClInclude>
<ClInclude Include="..\..\..\..\modules\juce_graphics\native\juce_Direct2DMetrics_windows.h">
<Filter>JUCE Modules\juce_graphics\native</Filter>
</ClInclude>
<ClInclude Include="..\..\..\..\modules\juce_graphics\native\juce_DirectX_windows.h">
<Filter>JUCE Modules\juce_graphics\native</Filter>
</ClInclude>
<ClInclude Include="..\..\..\..\modules\juce_graphics\native\juce_EventTracing.h">
<Filter>JUCE Modules\juce_graphics\native</Filter>
</ClInclude>
<ClInclude Include="..\..\..\..\modules\juce_graphics\native\juce_RenderingHelpers.h">
<Filter>JUCE Modules\juce_graphics\native</Filter>
</ClInclude>
@ -4674,6 +4710,9 @@
<ClInclude Include="..\..\..\..\modules\juce_gui_basics\detail\juce_ScopedMessageBoxInterface.h">
<Filter>JUCE Modules\juce_gui_basics\detail</Filter>
</ClInclude>
<ClInclude Include="..\..\..\..\modules\juce_gui_basics\detail\juce_StandardCachedComponentImage.h">
<Filter>JUCE Modules\juce_gui_basics\detail</Filter>
</ClInclude>
<ClInclude Include="..\..\..\..\modules\juce_gui_basics\detail\juce_ToolbarItemDragAndDropOverlayComponent.h">
<Filter>JUCE Modules\juce_gui_basics\detail</Filter>
</ClInclude>

View file

@ -1247,6 +1247,24 @@
<ClCompile Include="..\..\..\..\modules\juce_graphics\native\juce_Direct2DGraphicsContext_windows.cpp">
<ExcludedFromBuild>true</ExcludedFromBuild>
</ClCompile>
<ClCompile Include="..\..\..\..\modules\juce_graphics\native\juce_Direct2DHelpers_windows.cpp">
<ExcludedFromBuild>true</ExcludedFromBuild>
</ClCompile>
<ClCompile Include="..\..\..\..\modules\juce_graphics\native\juce_Direct2DHwndContext_windows.cpp">
<ExcludedFromBuild>true</ExcludedFromBuild>
</ClCompile>
<ClCompile Include="..\..\..\..\modules\juce_graphics\native\juce_Direct2DImage_windows.cpp">
<ExcludedFromBuild>true</ExcludedFromBuild>
</ClCompile>
<ClCompile Include="..\..\..\..\modules\juce_graphics\native\juce_Direct2DImageContext_windows.cpp">
<ExcludedFromBuild>true</ExcludedFromBuild>
</ClCompile>
<ClCompile Include="..\..\..\..\modules\juce_graphics\native\juce_Direct2DMetrics_windows.cpp">
<ExcludedFromBuild>true</ExcludedFromBuild>
</ClCompile>
<ClCompile Include="..\..\..\..\modules\juce_graphics\native\juce_Direct2DResources_windows.cpp">
<ExcludedFromBuild>true</ExcludedFromBuild>
</ClCompile>
<ClCompile Include="..\..\..\..\modules\juce_graphics\native\juce_DirectWriteTypeface_windows.cpp">
<ExcludedFromBuild>true</ExcludedFromBuild>
</ClCompile>
@ -2606,6 +2624,12 @@
<ClInclude Include="..\..\..\..\modules\juce_graphics\native\juce_CoreGraphicsContext_mac.h"/>
<ClInclude Include="..\..\..\..\modules\juce_graphics\native\juce_CoreGraphicsHelpers_mac.h"/>
<ClInclude Include="..\..\..\..\modules\juce_graphics\native\juce_Direct2DGraphicsContext_windows.h"/>
<ClInclude Include="..\..\..\..\modules\juce_graphics\native\juce_Direct2DHwndContext_windows.h"/>
<ClInclude Include="..\..\..\..\modules\juce_graphics\native\juce_Direct2DImage_windows.h"/>
<ClInclude Include="..\..\..\..\modules\juce_graphics\native\juce_Direct2DImageContext_windows.h"/>
<ClInclude Include="..\..\..\..\modules\juce_graphics\native\juce_Direct2DMetrics_windows.h"/>
<ClInclude Include="..\..\..\..\modules\juce_graphics\native\juce_DirectX_windows.h"/>
<ClInclude Include="..\..\..\..\modules\juce_graphics\native\juce_EventTracing.h"/>
<ClInclude Include="..\..\..\..\modules\juce_graphics\native\juce_RenderingHelpers.h"/>
<ClInclude Include="..\..\..\..\modules\juce_graphics\placement\juce_Justification.h"/>
<ClInclude Include="..\..\..\..\modules\juce_graphics\placement\juce_RectanglePlacement.h"/>
@ -2661,6 +2685,7 @@
<ClInclude Include="..\..\..\..\modules\juce_gui_basics\detail\juce_ScopedContentSharerInterface.h"/>
<ClInclude Include="..\..\..\..\modules\juce_gui_basics\detail\juce_ScopedMessageBoxImpl.h"/>
<ClInclude Include="..\..\..\..\modules\juce_gui_basics\detail\juce_ScopedMessageBoxInterface.h"/>
<ClInclude Include="..\..\..\..\modules\juce_gui_basics\detail\juce_StandardCachedComponentImage.h"/>
<ClInclude Include="..\..\..\..\modules\juce_gui_basics\detail\juce_ToolbarItemDragAndDropOverlayComponent.h"/>
<ClInclude Include="..\..\..\..\modules\juce_gui_basics\detail\juce_TopLevelWindowManager.h"/>
<ClInclude Include="..\..\..\..\modules\juce_gui_basics\detail\juce_ViewportHelpers.h"/>

View file

@ -1645,6 +1645,24 @@
<ClCompile Include="..\..\..\..\modules\juce_graphics\native\juce_Direct2DGraphicsContext_windows.cpp">
<Filter>JUCE Modules\juce_graphics\native</Filter>
</ClCompile>
<ClCompile Include="..\..\..\..\modules\juce_graphics\native\juce_Direct2DHelpers_windows.cpp">
<Filter>JUCE Modules\juce_graphics\native</Filter>
</ClCompile>
<ClCompile Include="..\..\..\..\modules\juce_graphics\native\juce_Direct2DHwndContext_windows.cpp">
<Filter>JUCE Modules\juce_graphics\native</Filter>
</ClCompile>
<ClCompile Include="..\..\..\..\modules\juce_graphics\native\juce_Direct2DImage_windows.cpp">
<Filter>JUCE Modules\juce_graphics\native</Filter>
</ClCompile>
<ClCompile Include="..\..\..\..\modules\juce_graphics\native\juce_Direct2DImageContext_windows.cpp">
<Filter>JUCE Modules\juce_graphics\native</Filter>
</ClCompile>
<ClCompile Include="..\..\..\..\modules\juce_graphics\native\juce_Direct2DMetrics_windows.cpp">
<Filter>JUCE Modules\juce_graphics\native</Filter>
</ClCompile>
<ClCompile Include="..\..\..\..\modules\juce_graphics\native\juce_Direct2DResources_windows.cpp">
<Filter>JUCE Modules\juce_graphics\native</Filter>
</ClCompile>
<ClCompile Include="..\..\..\..\modules\juce_graphics\native\juce_DirectWriteTypeface_windows.cpp">
<Filter>JUCE Modules\juce_graphics\native</Filter>
</ClCompile>
@ -4509,6 +4527,24 @@
<ClInclude Include="..\..\..\..\modules\juce_graphics\native\juce_Direct2DGraphicsContext_windows.h">
<Filter>JUCE Modules\juce_graphics\native</Filter>
</ClInclude>
<ClInclude Include="..\..\..\..\modules\juce_graphics\native\juce_Direct2DHwndContext_windows.h">
<Filter>JUCE Modules\juce_graphics\native</Filter>
</ClInclude>
<ClInclude Include="..\..\..\..\modules\juce_graphics\native\juce_Direct2DImage_windows.h">
<Filter>JUCE Modules\juce_graphics\native</Filter>
</ClInclude>
<ClInclude Include="..\..\..\..\modules\juce_graphics\native\juce_Direct2DImageContext_windows.h">
<Filter>JUCE Modules\juce_graphics\native</Filter>
</ClInclude>
<ClInclude Include="..\..\..\..\modules\juce_graphics\native\juce_Direct2DMetrics_windows.h">
<Filter>JUCE Modules\juce_graphics\native</Filter>
</ClInclude>
<ClInclude Include="..\..\..\..\modules\juce_graphics\native\juce_DirectX_windows.h">
<Filter>JUCE Modules\juce_graphics\native</Filter>
</ClInclude>
<ClInclude Include="..\..\..\..\modules\juce_graphics\native\juce_EventTracing.h">
<Filter>JUCE Modules\juce_graphics\native</Filter>
</ClInclude>
<ClInclude Include="..\..\..\..\modules\juce_graphics\native\juce_RenderingHelpers.h">
<Filter>JUCE Modules\juce_graphics\native</Filter>
</ClInclude>
@ -4674,6 +4710,9 @@
<ClInclude Include="..\..\..\..\modules\juce_gui_basics\detail\juce_ScopedMessageBoxInterface.h">
<Filter>JUCE Modules\juce_gui_basics\detail</Filter>
</ClInclude>
<ClInclude Include="..\..\..\..\modules\juce_gui_basics\detail\juce_StandardCachedComponentImage.h">
<Filter>JUCE Modules\juce_gui_basics\detail</Filter>
</ClInclude>
<ClInclude Include="..\..\..\..\modules\juce_gui_basics\detail\juce_ToolbarItemDragAndDropOverlayComponent.h">
<Filter>JUCE Modules\juce_gui_basics\detail</Filter>
</ClInclude>

View file

@ -2186,6 +2186,24 @@
<ClCompile Include="..\..\..\..\modules\juce_graphics\native\juce_Direct2DGraphicsContext_windows.cpp">
<ExcludedFromBuild>true</ExcludedFromBuild>
</ClCompile>
<ClCompile Include="..\..\..\..\modules\juce_graphics\native\juce_Direct2DHelpers_windows.cpp">
<ExcludedFromBuild>true</ExcludedFromBuild>
</ClCompile>
<ClCompile Include="..\..\..\..\modules\juce_graphics\native\juce_Direct2DHwndContext_windows.cpp">
<ExcludedFromBuild>true</ExcludedFromBuild>
</ClCompile>
<ClCompile Include="..\..\..\..\modules\juce_graphics\native\juce_Direct2DImage_windows.cpp">
<ExcludedFromBuild>true</ExcludedFromBuild>
</ClCompile>
<ClCompile Include="..\..\..\..\modules\juce_graphics\native\juce_Direct2DImageContext_windows.cpp">
<ExcludedFromBuild>true</ExcludedFromBuild>
</ClCompile>
<ClCompile Include="..\..\..\..\modules\juce_graphics\native\juce_Direct2DMetrics_windows.cpp">
<ExcludedFromBuild>true</ExcludedFromBuild>
</ClCompile>
<ClCompile Include="..\..\..\..\modules\juce_graphics\native\juce_Direct2DResources_windows.cpp">
<ExcludedFromBuild>true</ExcludedFromBuild>
</ClCompile>
<ClCompile Include="..\..\..\..\modules\juce_graphics\native\juce_DirectWriteTypeface_windows.cpp">
<ExcludedFromBuild>true</ExcludedFromBuild>
</ClCompile>
@ -4020,6 +4038,12 @@
<ClInclude Include="..\..\..\..\modules\juce_graphics\native\juce_CoreGraphicsContext_mac.h"/>
<ClInclude Include="..\..\..\..\modules\juce_graphics\native\juce_CoreGraphicsHelpers_mac.h"/>
<ClInclude Include="..\..\..\..\modules\juce_graphics\native\juce_Direct2DGraphicsContext_windows.h"/>
<ClInclude Include="..\..\..\..\modules\juce_graphics\native\juce_Direct2DHwndContext_windows.h"/>
<ClInclude Include="..\..\..\..\modules\juce_graphics\native\juce_Direct2DImage_windows.h"/>
<ClInclude Include="..\..\..\..\modules\juce_graphics\native\juce_Direct2DImageContext_windows.h"/>
<ClInclude Include="..\..\..\..\modules\juce_graphics\native\juce_Direct2DMetrics_windows.h"/>
<ClInclude Include="..\..\..\..\modules\juce_graphics\native\juce_DirectX_windows.h"/>
<ClInclude Include="..\..\..\..\modules\juce_graphics\native\juce_EventTracing.h"/>
<ClInclude Include="..\..\..\..\modules\juce_graphics\native\juce_RenderingHelpers.h"/>
<ClInclude Include="..\..\..\..\modules\juce_graphics\placement\juce_Justification.h"/>
<ClInclude Include="..\..\..\..\modules\juce_graphics\placement\juce_RectanglePlacement.h"/>
@ -4075,6 +4099,7 @@
<ClInclude Include="..\..\..\..\modules\juce_gui_basics\detail\juce_ScopedContentSharerInterface.h"/>
<ClInclude Include="..\..\..\..\modules\juce_gui_basics\detail\juce_ScopedMessageBoxImpl.h"/>
<ClInclude Include="..\..\..\..\modules\juce_gui_basics\detail\juce_ScopedMessageBoxInterface.h"/>
<ClInclude Include="..\..\..\..\modules\juce_gui_basics\detail\juce_StandardCachedComponentImage.h"/>
<ClInclude Include="..\..\..\..\modules\juce_gui_basics\detail\juce_ToolbarItemDragAndDropOverlayComponent.h"/>
<ClInclude Include="..\..\..\..\modules\juce_gui_basics\detail\juce_TopLevelWindowManager.h"/>
<ClInclude Include="..\..\..\..\modules\juce_gui_basics\detail\juce_ViewportHelpers.h"/>

View file

@ -2875,6 +2875,24 @@
<ClCompile Include="..\..\..\..\modules\juce_graphics\native\juce_Direct2DGraphicsContext_windows.cpp">
<Filter>JUCE Modules\juce_graphics\native</Filter>
</ClCompile>
<ClCompile Include="..\..\..\..\modules\juce_graphics\native\juce_Direct2DHelpers_windows.cpp">
<Filter>JUCE Modules\juce_graphics\native</Filter>
</ClCompile>
<ClCompile Include="..\..\..\..\modules\juce_graphics\native\juce_Direct2DHwndContext_windows.cpp">
<Filter>JUCE Modules\juce_graphics\native</Filter>
</ClCompile>
<ClCompile Include="..\..\..\..\modules\juce_graphics\native\juce_Direct2DImage_windows.cpp">
<Filter>JUCE Modules\juce_graphics\native</Filter>
</ClCompile>
<ClCompile Include="..\..\..\..\modules\juce_graphics\native\juce_Direct2DImageContext_windows.cpp">
<Filter>JUCE Modules\juce_graphics\native</Filter>
</ClCompile>
<ClCompile Include="..\..\..\..\modules\juce_graphics\native\juce_Direct2DMetrics_windows.cpp">
<Filter>JUCE Modules\juce_graphics\native</Filter>
</ClCompile>
<ClCompile Include="..\..\..\..\modules\juce_graphics\native\juce_Direct2DResources_windows.cpp">
<Filter>JUCE Modules\juce_graphics\native</Filter>
</ClCompile>
<ClCompile Include="..\..\..\..\modules\juce_graphics\native\juce_DirectWriteTypeface_windows.cpp">
<Filter>JUCE Modules\juce_graphics\native</Filter>
</ClCompile>
@ -6918,6 +6936,24 @@
<ClInclude Include="..\..\..\..\modules\juce_graphics\native\juce_Direct2DGraphicsContext_windows.h">
<Filter>JUCE Modules\juce_graphics\native</Filter>
</ClInclude>
<ClInclude Include="..\..\..\..\modules\juce_graphics\native\juce_Direct2DHwndContext_windows.h">
<Filter>JUCE Modules\juce_graphics\native</Filter>
</ClInclude>
<ClInclude Include="..\..\..\..\modules\juce_graphics\native\juce_Direct2DImage_windows.h">
<Filter>JUCE Modules\juce_graphics\native</Filter>
</ClInclude>
<ClInclude Include="..\..\..\..\modules\juce_graphics\native\juce_Direct2DImageContext_windows.h">
<Filter>JUCE Modules\juce_graphics\native</Filter>
</ClInclude>
<ClInclude Include="..\..\..\..\modules\juce_graphics\native\juce_Direct2DMetrics_windows.h">
<Filter>JUCE Modules\juce_graphics\native</Filter>
</ClInclude>
<ClInclude Include="..\..\..\..\modules\juce_graphics\native\juce_DirectX_windows.h">
<Filter>JUCE Modules\juce_graphics\native</Filter>
</ClInclude>
<ClInclude Include="..\..\..\..\modules\juce_graphics\native\juce_EventTracing.h">
<Filter>JUCE Modules\juce_graphics\native</Filter>
</ClInclude>
<ClInclude Include="..\..\..\..\modules\juce_graphics\native\juce_RenderingHelpers.h">
<Filter>JUCE Modules\juce_graphics\native</Filter>
</ClInclude>
@ -7083,6 +7119,9 @@
<ClInclude Include="..\..\..\..\modules\juce_gui_basics\detail\juce_ScopedMessageBoxInterface.h">
<Filter>JUCE Modules\juce_gui_basics\detail</Filter>
</ClInclude>
<ClInclude Include="..\..\..\..\modules\juce_gui_basics\detail\juce_StandardCachedComponentImage.h">
<Filter>JUCE Modules\juce_gui_basics\detail</Filter>
</ClInclude>
<ClInclude Include="..\..\..\..\modules\juce_gui_basics\detail\juce_ToolbarItemDragAndDropOverlayComponent.h">
<Filter>JUCE Modules\juce_gui_basics\detail</Filter>
</ClInclude>

View file

@ -2186,6 +2186,24 @@
<ClCompile Include="..\..\..\..\modules\juce_graphics\native\juce_Direct2DGraphicsContext_windows.cpp">
<ExcludedFromBuild>true</ExcludedFromBuild>
</ClCompile>
<ClCompile Include="..\..\..\..\modules\juce_graphics\native\juce_Direct2DHelpers_windows.cpp">
<ExcludedFromBuild>true</ExcludedFromBuild>
</ClCompile>
<ClCompile Include="..\..\..\..\modules\juce_graphics\native\juce_Direct2DHwndContext_windows.cpp">
<ExcludedFromBuild>true</ExcludedFromBuild>
</ClCompile>
<ClCompile Include="..\..\..\..\modules\juce_graphics\native\juce_Direct2DImage_windows.cpp">
<ExcludedFromBuild>true</ExcludedFromBuild>
</ClCompile>
<ClCompile Include="..\..\..\..\modules\juce_graphics\native\juce_Direct2DImageContext_windows.cpp">
<ExcludedFromBuild>true</ExcludedFromBuild>
</ClCompile>
<ClCompile Include="..\..\..\..\modules\juce_graphics\native\juce_Direct2DMetrics_windows.cpp">
<ExcludedFromBuild>true</ExcludedFromBuild>
</ClCompile>
<ClCompile Include="..\..\..\..\modules\juce_graphics\native\juce_Direct2DResources_windows.cpp">
<ExcludedFromBuild>true</ExcludedFromBuild>
</ClCompile>
<ClCompile Include="..\..\..\..\modules\juce_graphics\native\juce_DirectWriteTypeface_windows.cpp">
<ExcludedFromBuild>true</ExcludedFromBuild>
</ClCompile>
@ -4020,6 +4038,12 @@
<ClInclude Include="..\..\..\..\modules\juce_graphics\native\juce_CoreGraphicsContext_mac.h"/>
<ClInclude Include="..\..\..\..\modules\juce_graphics\native\juce_CoreGraphicsHelpers_mac.h"/>
<ClInclude Include="..\..\..\..\modules\juce_graphics\native\juce_Direct2DGraphicsContext_windows.h"/>
<ClInclude Include="..\..\..\..\modules\juce_graphics\native\juce_Direct2DHwndContext_windows.h"/>
<ClInclude Include="..\..\..\..\modules\juce_graphics\native\juce_Direct2DImage_windows.h"/>
<ClInclude Include="..\..\..\..\modules\juce_graphics\native\juce_Direct2DImageContext_windows.h"/>
<ClInclude Include="..\..\..\..\modules\juce_graphics\native\juce_Direct2DMetrics_windows.h"/>
<ClInclude Include="..\..\..\..\modules\juce_graphics\native\juce_DirectX_windows.h"/>
<ClInclude Include="..\..\..\..\modules\juce_graphics\native\juce_EventTracing.h"/>
<ClInclude Include="..\..\..\..\modules\juce_graphics\native\juce_RenderingHelpers.h"/>
<ClInclude Include="..\..\..\..\modules\juce_graphics\placement\juce_Justification.h"/>
<ClInclude Include="..\..\..\..\modules\juce_graphics\placement\juce_RectanglePlacement.h"/>
@ -4075,6 +4099,7 @@
<ClInclude Include="..\..\..\..\modules\juce_gui_basics\detail\juce_ScopedContentSharerInterface.h"/>
<ClInclude Include="..\..\..\..\modules\juce_gui_basics\detail\juce_ScopedMessageBoxImpl.h"/>
<ClInclude Include="..\..\..\..\modules\juce_gui_basics\detail\juce_ScopedMessageBoxInterface.h"/>
<ClInclude Include="..\..\..\..\modules\juce_gui_basics\detail\juce_StandardCachedComponentImage.h"/>
<ClInclude Include="..\..\..\..\modules\juce_gui_basics\detail\juce_ToolbarItemDragAndDropOverlayComponent.h"/>
<ClInclude Include="..\..\..\..\modules\juce_gui_basics\detail\juce_TopLevelWindowManager.h"/>
<ClInclude Include="..\..\..\..\modules\juce_gui_basics\detail\juce_ViewportHelpers.h"/>

View file

@ -2875,6 +2875,24 @@
<ClCompile Include="..\..\..\..\modules\juce_graphics\native\juce_Direct2DGraphicsContext_windows.cpp">
<Filter>JUCE Modules\juce_graphics\native</Filter>
</ClCompile>
<ClCompile Include="..\..\..\..\modules\juce_graphics\native\juce_Direct2DHelpers_windows.cpp">
<Filter>JUCE Modules\juce_graphics\native</Filter>
</ClCompile>
<ClCompile Include="..\..\..\..\modules\juce_graphics\native\juce_Direct2DHwndContext_windows.cpp">
<Filter>JUCE Modules\juce_graphics\native</Filter>
</ClCompile>
<ClCompile Include="..\..\..\..\modules\juce_graphics\native\juce_Direct2DImage_windows.cpp">
<Filter>JUCE Modules\juce_graphics\native</Filter>
</ClCompile>
<ClCompile Include="..\..\..\..\modules\juce_graphics\native\juce_Direct2DImageContext_windows.cpp">
<Filter>JUCE Modules\juce_graphics\native</Filter>
</ClCompile>
<ClCompile Include="..\..\..\..\modules\juce_graphics\native\juce_Direct2DMetrics_windows.cpp">
<Filter>JUCE Modules\juce_graphics\native</Filter>
</ClCompile>
<ClCompile Include="..\..\..\..\modules\juce_graphics\native\juce_Direct2DResources_windows.cpp">
<Filter>JUCE Modules\juce_graphics\native</Filter>
</ClCompile>
<ClCompile Include="..\..\..\..\modules\juce_graphics\native\juce_DirectWriteTypeface_windows.cpp">
<Filter>JUCE Modules\juce_graphics\native</Filter>
</ClCompile>
@ -6918,6 +6936,24 @@
<ClInclude Include="..\..\..\..\modules\juce_graphics\native\juce_Direct2DGraphicsContext_windows.h">
<Filter>JUCE Modules\juce_graphics\native</Filter>
</ClInclude>
<ClInclude Include="..\..\..\..\modules\juce_graphics\native\juce_Direct2DHwndContext_windows.h">
<Filter>JUCE Modules\juce_graphics\native</Filter>
</ClInclude>
<ClInclude Include="..\..\..\..\modules\juce_graphics\native\juce_Direct2DImage_windows.h">
<Filter>JUCE Modules\juce_graphics\native</Filter>
</ClInclude>
<ClInclude Include="..\..\..\..\modules\juce_graphics\native\juce_Direct2DImageContext_windows.h">
<Filter>JUCE Modules\juce_graphics\native</Filter>
</ClInclude>
<ClInclude Include="..\..\..\..\modules\juce_graphics\native\juce_Direct2DMetrics_windows.h">
<Filter>JUCE Modules\juce_graphics\native</Filter>
</ClInclude>
<ClInclude Include="..\..\..\..\modules\juce_graphics\native\juce_DirectX_windows.h">
<Filter>JUCE Modules\juce_graphics\native</Filter>
</ClInclude>
<ClInclude Include="..\..\..\..\modules\juce_graphics\native\juce_EventTracing.h">
<Filter>JUCE Modules\juce_graphics\native</Filter>
</ClInclude>
<ClInclude Include="..\..\..\..\modules\juce_graphics\native\juce_RenderingHelpers.h">
<Filter>JUCE Modules\juce_graphics\native</Filter>
</ClInclude>
@ -7083,6 +7119,9 @@
<ClInclude Include="..\..\..\..\modules\juce_gui_basics\detail\juce_ScopedMessageBoxInterface.h">
<Filter>JUCE Modules\juce_gui_basics\detail</Filter>
</ClInclude>
<ClInclude Include="..\..\..\..\modules\juce_gui_basics\detail\juce_StandardCachedComponentImage.h">
<Filter>JUCE Modules\juce_gui_basics\detail</Filter>
</ClInclude>
<ClInclude Include="..\..\..\..\modules\juce_gui_basics\detail\juce_ToolbarItemDragAndDropOverlayComponent.h">
<Filter>JUCE Modules\juce_gui_basics\detail</Filter>
</ClInclude>

View file

@ -2186,6 +2186,24 @@
<ClCompile Include="..\..\..\..\modules\juce_graphics\native\juce_Direct2DGraphicsContext_windows.cpp">
<ExcludedFromBuild>true</ExcludedFromBuild>
</ClCompile>
<ClCompile Include="..\..\..\..\modules\juce_graphics\native\juce_Direct2DHelpers_windows.cpp">
<ExcludedFromBuild>true</ExcludedFromBuild>
</ClCompile>
<ClCompile Include="..\..\..\..\modules\juce_graphics\native\juce_Direct2DHwndContext_windows.cpp">
<ExcludedFromBuild>true</ExcludedFromBuild>
</ClCompile>
<ClCompile Include="..\..\..\..\modules\juce_graphics\native\juce_Direct2DImage_windows.cpp">
<ExcludedFromBuild>true</ExcludedFromBuild>
</ClCompile>
<ClCompile Include="..\..\..\..\modules\juce_graphics\native\juce_Direct2DImageContext_windows.cpp">
<ExcludedFromBuild>true</ExcludedFromBuild>
</ClCompile>
<ClCompile Include="..\..\..\..\modules\juce_graphics\native\juce_Direct2DMetrics_windows.cpp">
<ExcludedFromBuild>true</ExcludedFromBuild>
</ClCompile>
<ClCompile Include="..\..\..\..\modules\juce_graphics\native\juce_Direct2DResources_windows.cpp">
<ExcludedFromBuild>true</ExcludedFromBuild>
</ClCompile>
<ClCompile Include="..\..\..\..\modules\juce_graphics\native\juce_DirectWriteTypeface_windows.cpp">
<ExcludedFromBuild>true</ExcludedFromBuild>
</ClCompile>
@ -4020,6 +4038,12 @@
<ClInclude Include="..\..\..\..\modules\juce_graphics\native\juce_CoreGraphicsContext_mac.h"/>
<ClInclude Include="..\..\..\..\modules\juce_graphics\native\juce_CoreGraphicsHelpers_mac.h"/>
<ClInclude Include="..\..\..\..\modules\juce_graphics\native\juce_Direct2DGraphicsContext_windows.h"/>
<ClInclude Include="..\..\..\..\modules\juce_graphics\native\juce_Direct2DHwndContext_windows.h"/>
<ClInclude Include="..\..\..\..\modules\juce_graphics\native\juce_Direct2DImage_windows.h"/>
<ClInclude Include="..\..\..\..\modules\juce_graphics\native\juce_Direct2DImageContext_windows.h"/>
<ClInclude Include="..\..\..\..\modules\juce_graphics\native\juce_Direct2DMetrics_windows.h"/>
<ClInclude Include="..\..\..\..\modules\juce_graphics\native\juce_DirectX_windows.h"/>
<ClInclude Include="..\..\..\..\modules\juce_graphics\native\juce_EventTracing.h"/>
<ClInclude Include="..\..\..\..\modules\juce_graphics\native\juce_RenderingHelpers.h"/>
<ClInclude Include="..\..\..\..\modules\juce_graphics\placement\juce_Justification.h"/>
<ClInclude Include="..\..\..\..\modules\juce_graphics\placement\juce_RectanglePlacement.h"/>
@ -4075,6 +4099,7 @@
<ClInclude Include="..\..\..\..\modules\juce_gui_basics\detail\juce_ScopedContentSharerInterface.h"/>
<ClInclude Include="..\..\..\..\modules\juce_gui_basics\detail\juce_ScopedMessageBoxImpl.h"/>
<ClInclude Include="..\..\..\..\modules\juce_gui_basics\detail\juce_ScopedMessageBoxInterface.h"/>
<ClInclude Include="..\..\..\..\modules\juce_gui_basics\detail\juce_StandardCachedComponentImage.h"/>
<ClInclude Include="..\..\..\..\modules\juce_gui_basics\detail\juce_ToolbarItemDragAndDropOverlayComponent.h"/>
<ClInclude Include="..\..\..\..\modules\juce_gui_basics\detail\juce_TopLevelWindowManager.h"/>
<ClInclude Include="..\..\..\..\modules\juce_gui_basics\detail\juce_ViewportHelpers.h"/>

View file

@ -2875,6 +2875,24 @@
<ClCompile Include="..\..\..\..\modules\juce_graphics\native\juce_Direct2DGraphicsContext_windows.cpp">
<Filter>JUCE Modules\juce_graphics\native</Filter>
</ClCompile>
<ClCompile Include="..\..\..\..\modules\juce_graphics\native\juce_Direct2DHelpers_windows.cpp">
<Filter>JUCE Modules\juce_graphics\native</Filter>
</ClCompile>
<ClCompile Include="..\..\..\..\modules\juce_graphics\native\juce_Direct2DHwndContext_windows.cpp">
<Filter>JUCE Modules\juce_graphics\native</Filter>
</ClCompile>
<ClCompile Include="..\..\..\..\modules\juce_graphics\native\juce_Direct2DImage_windows.cpp">
<Filter>JUCE Modules\juce_graphics\native</Filter>
</ClCompile>
<ClCompile Include="..\..\..\..\modules\juce_graphics\native\juce_Direct2DImageContext_windows.cpp">
<Filter>JUCE Modules\juce_graphics\native</Filter>
</ClCompile>
<ClCompile Include="..\..\..\..\modules\juce_graphics\native\juce_Direct2DMetrics_windows.cpp">
<Filter>JUCE Modules\juce_graphics\native</Filter>
</ClCompile>
<ClCompile Include="..\..\..\..\modules\juce_graphics\native\juce_Direct2DResources_windows.cpp">
<Filter>JUCE Modules\juce_graphics\native</Filter>
</ClCompile>
<ClCompile Include="..\..\..\..\modules\juce_graphics\native\juce_DirectWriteTypeface_windows.cpp">
<Filter>JUCE Modules\juce_graphics\native</Filter>
</ClCompile>
@ -6918,6 +6936,24 @@
<ClInclude Include="..\..\..\..\modules\juce_graphics\native\juce_Direct2DGraphicsContext_windows.h">
<Filter>JUCE Modules\juce_graphics\native</Filter>
</ClInclude>
<ClInclude Include="..\..\..\..\modules\juce_graphics\native\juce_Direct2DHwndContext_windows.h">
<Filter>JUCE Modules\juce_graphics\native</Filter>
</ClInclude>
<ClInclude Include="..\..\..\..\modules\juce_graphics\native\juce_Direct2DImage_windows.h">
<Filter>JUCE Modules\juce_graphics\native</Filter>
</ClInclude>
<ClInclude Include="..\..\..\..\modules\juce_graphics\native\juce_Direct2DImageContext_windows.h">
<Filter>JUCE Modules\juce_graphics\native</Filter>
</ClInclude>
<ClInclude Include="..\..\..\..\modules\juce_graphics\native\juce_Direct2DMetrics_windows.h">
<Filter>JUCE Modules\juce_graphics\native</Filter>
</ClInclude>
<ClInclude Include="..\..\..\..\modules\juce_graphics\native\juce_DirectX_windows.h">
<Filter>JUCE Modules\juce_graphics\native</Filter>
</ClInclude>
<ClInclude Include="..\..\..\..\modules\juce_graphics\native\juce_EventTracing.h">
<Filter>JUCE Modules\juce_graphics\native</Filter>
</ClInclude>
<ClInclude Include="..\..\..\..\modules\juce_graphics\native\juce_RenderingHelpers.h">
<Filter>JUCE Modules\juce_graphics\native</Filter>
</ClInclude>
@ -7083,6 +7119,9 @@
<ClInclude Include="..\..\..\..\modules\juce_gui_basics\detail\juce_ScopedMessageBoxInterface.h">
<Filter>JUCE Modules\juce_gui_basics\detail</Filter>
</ClInclude>
<ClInclude Include="..\..\..\..\modules\juce_gui_basics\detail\juce_StandardCachedComponentImage.h">
<Filter>JUCE Modules\juce_gui_basics\detail</Filter>
</ClInclude>
<ClInclude Include="..\..\..\..\modules\juce_gui_basics\detail\juce_ToolbarItemDragAndDropOverlayComponent.h">
<Filter>JUCE Modules\juce_gui_basics\detail</Filter>
</ClInclude>

View file

@ -2064,6 +2064,24 @@
<ClCompile Include="..\..\..\..\modules\juce_graphics\native\juce_Direct2DGraphicsContext_windows.cpp">
<ExcludedFromBuild>true</ExcludedFromBuild>
</ClCompile>
<ClCompile Include="..\..\..\..\modules\juce_graphics\native\juce_Direct2DHelpers_windows.cpp">
<ExcludedFromBuild>true</ExcludedFromBuild>
</ClCompile>
<ClCompile Include="..\..\..\..\modules\juce_graphics\native\juce_Direct2DHwndContext_windows.cpp">
<ExcludedFromBuild>true</ExcludedFromBuild>
</ClCompile>
<ClCompile Include="..\..\..\..\modules\juce_graphics\native\juce_Direct2DImage_windows.cpp">
<ExcludedFromBuild>true</ExcludedFromBuild>
</ClCompile>
<ClCompile Include="..\..\..\..\modules\juce_graphics\native\juce_Direct2DImageContext_windows.cpp">
<ExcludedFromBuild>true</ExcludedFromBuild>
</ClCompile>
<ClCompile Include="..\..\..\..\modules\juce_graphics\native\juce_Direct2DMetrics_windows.cpp">
<ExcludedFromBuild>true</ExcludedFromBuild>
</ClCompile>
<ClCompile Include="..\..\..\..\modules\juce_graphics\native\juce_Direct2DResources_windows.cpp">
<ExcludedFromBuild>true</ExcludedFromBuild>
</ClCompile>
<ClCompile Include="..\..\..\..\modules\juce_graphics\native\juce_DirectWriteTypeface_windows.cpp">
<ExcludedFromBuild>true</ExcludedFromBuild>
</ClCompile>
@ -3765,6 +3783,12 @@
<ClInclude Include="..\..\..\..\modules\juce_graphics\native\juce_CoreGraphicsContext_mac.h"/>
<ClInclude Include="..\..\..\..\modules\juce_graphics\native\juce_CoreGraphicsHelpers_mac.h"/>
<ClInclude Include="..\..\..\..\modules\juce_graphics\native\juce_Direct2DGraphicsContext_windows.h"/>
<ClInclude Include="..\..\..\..\modules\juce_graphics\native\juce_Direct2DHwndContext_windows.h"/>
<ClInclude Include="..\..\..\..\modules\juce_graphics\native\juce_Direct2DImage_windows.h"/>
<ClInclude Include="..\..\..\..\modules\juce_graphics\native\juce_Direct2DImageContext_windows.h"/>
<ClInclude Include="..\..\..\..\modules\juce_graphics\native\juce_Direct2DMetrics_windows.h"/>
<ClInclude Include="..\..\..\..\modules\juce_graphics\native\juce_DirectX_windows.h"/>
<ClInclude Include="..\..\..\..\modules\juce_graphics\native\juce_EventTracing.h"/>
<ClInclude Include="..\..\..\..\modules\juce_graphics\native\juce_RenderingHelpers.h"/>
<ClInclude Include="..\..\..\..\modules\juce_graphics\placement\juce_Justification.h"/>
<ClInclude Include="..\..\..\..\modules\juce_graphics\placement\juce_RectanglePlacement.h"/>
@ -3820,6 +3844,7 @@
<ClInclude Include="..\..\..\..\modules\juce_gui_basics\detail\juce_ScopedContentSharerInterface.h"/>
<ClInclude Include="..\..\..\..\modules\juce_gui_basics\detail\juce_ScopedMessageBoxImpl.h"/>
<ClInclude Include="..\..\..\..\modules\juce_gui_basics\detail\juce_ScopedMessageBoxInterface.h"/>
<ClInclude Include="..\..\..\..\modules\juce_gui_basics\detail\juce_StandardCachedComponentImage.h"/>
<ClInclude Include="..\..\..\..\modules\juce_gui_basics\detail\juce_ToolbarItemDragAndDropOverlayComponent.h"/>
<ClInclude Include="..\..\..\..\modules\juce_gui_basics\detail\juce_TopLevelWindowManager.h"/>
<ClInclude Include="..\..\..\..\modules\juce_gui_basics\detail\juce_ViewportHelpers.h"/>

View file

@ -2698,6 +2698,24 @@
<ClCompile Include="..\..\..\..\modules\juce_graphics\native\juce_Direct2DGraphicsContext_windows.cpp">
<Filter>JUCE Modules\juce_graphics\native</Filter>
</ClCompile>
<ClCompile Include="..\..\..\..\modules\juce_graphics\native\juce_Direct2DHelpers_windows.cpp">
<Filter>JUCE Modules\juce_graphics\native</Filter>
</ClCompile>
<ClCompile Include="..\..\..\..\modules\juce_graphics\native\juce_Direct2DHwndContext_windows.cpp">
<Filter>JUCE Modules\juce_graphics\native</Filter>
</ClCompile>
<ClCompile Include="..\..\..\..\modules\juce_graphics\native\juce_Direct2DImage_windows.cpp">
<Filter>JUCE Modules\juce_graphics\native</Filter>
</ClCompile>
<ClCompile Include="..\..\..\..\modules\juce_graphics\native\juce_Direct2DImageContext_windows.cpp">
<Filter>JUCE Modules\juce_graphics\native</Filter>
</ClCompile>
<ClCompile Include="..\..\..\..\modules\juce_graphics\native\juce_Direct2DMetrics_windows.cpp">
<Filter>JUCE Modules\juce_graphics\native</Filter>
</ClCompile>
<ClCompile Include="..\..\..\..\modules\juce_graphics\native\juce_Direct2DResources_windows.cpp">
<Filter>JUCE Modules\juce_graphics\native</Filter>
</ClCompile>
<ClCompile Include="..\..\..\..\modules\juce_graphics\native\juce_DirectWriteTypeface_windows.cpp">
<Filter>JUCE Modules\juce_graphics\native</Filter>
</ClCompile>
@ -6498,6 +6516,24 @@
<ClInclude Include="..\..\..\..\modules\juce_graphics\native\juce_Direct2DGraphicsContext_windows.h">
<Filter>JUCE Modules\juce_graphics\native</Filter>
</ClInclude>
<ClInclude Include="..\..\..\..\modules\juce_graphics\native\juce_Direct2DHwndContext_windows.h">
<Filter>JUCE Modules\juce_graphics\native</Filter>
</ClInclude>
<ClInclude Include="..\..\..\..\modules\juce_graphics\native\juce_Direct2DImage_windows.h">
<Filter>JUCE Modules\juce_graphics\native</Filter>
</ClInclude>
<ClInclude Include="..\..\..\..\modules\juce_graphics\native\juce_Direct2DImageContext_windows.h">
<Filter>JUCE Modules\juce_graphics\native</Filter>
</ClInclude>
<ClInclude Include="..\..\..\..\modules\juce_graphics\native\juce_Direct2DMetrics_windows.h">
<Filter>JUCE Modules\juce_graphics\native</Filter>
</ClInclude>
<ClInclude Include="..\..\..\..\modules\juce_graphics\native\juce_DirectX_windows.h">
<Filter>JUCE Modules\juce_graphics\native</Filter>
</ClInclude>
<ClInclude Include="..\..\..\..\modules\juce_graphics\native\juce_EventTracing.h">
<Filter>JUCE Modules\juce_graphics\native</Filter>
</ClInclude>
<ClInclude Include="..\..\..\..\modules\juce_graphics\native\juce_RenderingHelpers.h">
<Filter>JUCE Modules\juce_graphics\native</Filter>
</ClInclude>
@ -6663,6 +6699,9 @@
<ClInclude Include="..\..\..\..\modules\juce_gui_basics\detail\juce_ScopedMessageBoxInterface.h">
<Filter>JUCE Modules\juce_gui_basics\detail</Filter>
</ClInclude>
<ClInclude Include="..\..\..\..\modules\juce_gui_basics\detail\juce_StandardCachedComponentImage.h">
<Filter>JUCE Modules\juce_gui_basics\detail</Filter>
</ClInclude>
<ClInclude Include="..\..\..\..\modules\juce_gui_basics\detail\juce_ToolbarItemDragAndDropOverlayComponent.h">
<Filter>JUCE Modules\juce_gui_basics\detail</Filter>
</ClInclude>

View file

@ -100,13 +100,8 @@
#define _WINSOCK_DEPRECATED_NO_WARNINGS 1
#define STRICT 1
#define WIN32_LEAN_AND_MEAN 1
#if JUCE_MINGW
#if ! defined (_WIN32_WINNT)
#define _WIN32_WINNT 0x0600
#endif
#else
#define _WIN32_WINNT 0x0602
#endif
#define WINVER _WIN32_WINNT_WIN10
#define _WIN32_WINNT _WIN32_WINNT_WIN10
#define _UNICODE 1
#define UNICODE 1
#ifndef _WIN32_IE

View file

@ -89,8 +89,6 @@ ColourGradient::ColourGradient (Colour colour1, Point<float> p1,
ColourPoint { 1.0, colour2 });
}
ColourGradient::~ColourGradient() {}
ColourGradient ColourGradient::vertical (Colour c1, float y1, Colour c2, float y2)
{
return { c1, 0, y1, c2, 0, y2, false };
@ -101,17 +99,45 @@ ColourGradient ColourGradient::horizontal (Colour c1, float x1, Colour c2, float
return { c1, x1, 0, c2, x2, 0, false };
}
bool ColourGradient::operator== (const ColourGradient& other) const noexcept
struct PointComparisons
{
return point1 == other.point1 && point2 == other.point2
&& isRadial == other.isRadial
&& colours == other.colours;
auto tie() const { return std::tie (point->x, point->y); }
bool operator== (const PointComparisons& other) const { return tie() == other.tie(); }
bool operator!= (const PointComparisons& other) const { return tie() != other.tie(); }
bool operator< (const PointComparisons& other) const { return tie() < other.tie(); }
const Point<float>* point = nullptr;
};
struct ColourGradient::ColourPointArrayComparisons
{
bool operator== (const ColourPointArrayComparisons& other) const { return *array == *other.array; }
bool operator!= (const ColourPointArrayComparisons& other) const { return *array != *other.array; }
bool operator< (const ColourPointArrayComparisons& other) const
{
return std::lexicographical_compare (array->begin(), array->end(), other.array->begin(), other.array->end());
}
const Array<ColourGradient::ColourPoint>* array = nullptr;
};
auto ColourGradient::tie() const
{
return std::tuple (PointComparisons { &point1 },
PointComparisons { &point2 },
isRadial,
ColourPointArrayComparisons { &colours });
}
bool ColourGradient::operator!= (const ColourGradient& other) const noexcept
{
return ! operator== (other);
}
bool ColourGradient::operator== (const ColourGradient& other) const noexcept { return tie() == other.tie(); }
bool ColourGradient::operator!= (const ColourGradient& other) const noexcept { return tie() != other.tie(); }
bool ColourGradient::operator< (const ColourGradient& other) const noexcept { return tie() < other.tie(); }
bool ColourGradient::operator<= (const ColourGradient& other) const noexcept { return tie() <= other.tie(); }
bool ColourGradient::operator> (const ColourGradient& other) const noexcept { return tie() > other.tie(); }
bool ColourGradient::operator>= (const ColourGradient& other) const noexcept { return tie() >= other.tie(); }
//==============================================================================
void ColourGradient::clearColours()
@ -265,15 +291,4 @@ bool ColourGradient::isInvisible() const noexcept
return true;
}
bool ColourGradient::ColourPoint::operator== (ColourPoint other) const noexcept
{
const auto tie = [] (const ColourPoint& p) { return std::tie (p.position, p.colour); };
return tie (*this) == tie (other);
}
bool ColourGradient::ColourPoint::operator!= (ColourPoint other) const noexcept
{
return ! operator== (other);
}
} // namespace juce

View file

@ -124,9 +124,6 @@ public:
return horizontal (colourLeft, (float) area.getX(), colourRight, (float) area.getRight());
}
/** Destructor */
~ColourGradient();
//==============================================================================
/** Removes any colours that have been added.
@ -224,18 +221,32 @@ public:
bool operator== (const ColourGradient&) const noexcept;
bool operator!= (const ColourGradient&) const noexcept;
/** This comparison, and the other ordered comparisons are provided only for compatibility with
ordered container types like std::set and std::map.
*/
bool operator< (const ColourGradient&) const noexcept;
bool operator<= (const ColourGradient&) const noexcept;
bool operator> (const ColourGradient&) const noexcept;
bool operator>= (const ColourGradient&) const noexcept;
private:
//==============================================================================
struct ColourPoint
{
bool operator== (ColourPoint) const noexcept;
bool operator!= (ColourPoint) const noexcept;
auto tie() const { return std::tuple (position, colour.getPixelARGB().getNativeARGB()); }
bool operator== (ColourPoint other) const noexcept { return tie() == other.tie(); }
bool operator!= (ColourPoint other) const noexcept { return tie() != other.tie(); }
bool operator< (ColourPoint other) const noexcept { return tie() < other.tie(); }
double position;
Colour colour;
};
struct ColourPointArrayComparisons;
auto tie() const;
Array<ColourPoint> colours;
JUCE_LEAK_DETECTOR (ColourGradient)

View file

@ -128,6 +128,8 @@ Graphics::Graphics (LowLevelGraphicsContext& internalContext) noexcept
//==============================================================================
void Graphics::resetToDefaultState()
{
JUCE_SCOPED_TRACE_EVENT_FRAME (etw::resetToDefaultState, etw::graphicsKeyword, context.getFrameId());
saveStateIfPending();
context.setFill (FillType());
context.setFont (FontOptions{}.withMetricsKind (TypefaceMetricsKind::legacy));
@ -141,6 +143,8 @@ bool Graphics::isVectorDevice() const
bool Graphics::reduceClipRegion (Rectangle<int> area)
{
JUCE_SCOPED_TRACE_EVENT_FRAME_RECT_I32 (etw::reduceClipRegionRectangle, etw::graphicsKeyword, context.getFrameId(), area)
saveStateIfPending();
return context.clipToRectangle (area);
}
@ -152,12 +156,16 @@ bool Graphics::reduceClipRegion (int x, int y, int w, int h)
bool Graphics::reduceClipRegion (const RectangleList<int>& clipRegion)
{
JUCE_SCOPED_TRACE_EVENT_FRAME_RECT_I32 (etw::reduceClipRegionRectangleList, etw::graphicsKeyword, context.getFrameId(), clipRegion)
saveStateIfPending();
return context.clipToRectangleList (clipRegion);
}
bool Graphics::reduceClipRegion (const Path& path, const AffineTransform& transform)
{
JUCE_SCOPED_TRACE_EVENT_FRAME (etw::reduceClipRegionPath, etw::graphicsKeyword, context.getFrameId());
saveStateIfPending();
context.clipToPath (path, transform);
return ! context.isClipEmpty();
@ -165,6 +173,8 @@ bool Graphics::reduceClipRegion (const Path& path, const AffineTransform& transf
bool Graphics::reduceClipRegion (const Image& image, const AffineTransform& transform)
{
JUCE_SCOPED_TRACE_EVENT_FRAME (etw::reduceClipRegionImage, etw::graphicsKeyword, context.getFrameId());
saveStateIfPending();
context.clipToImageAlpha (image, transform);
return ! context.isClipEmpty();
@ -172,6 +182,8 @@ bool Graphics::reduceClipRegion (const Image& image, const AffineTransform& tran
void Graphics::excludeClipRegion (Rectangle<int> rectangleToExclude)
{
JUCE_SCOPED_TRACE_EVENT_FRAME_RECT_I32 (etw::excludeClipRegion, etw::graphicsKeyword, context.getFrameId(), rectangleToExclude);
saveStateIfPending();
context.excludeClipRectangle (rectangleToExclude);
}
@ -188,12 +200,16 @@ Rectangle<int> Graphics::getClipBounds() const
void Graphics::saveState()
{
JUCE_SCOPED_TRACE_EVENT_FRAME (etw::saveState, etw::graphicsKeyword, context.getFrameId());
saveStateIfPending();
saveStatePending = true;
}
void Graphics::restoreState()
{
JUCE_SCOPED_TRACE_EVENT_FRAME (etw::restoreState, etw::graphicsKeyword, context.getFrameId());
if (saveStatePending)
saveStatePending = false;
else
@ -204,6 +220,8 @@ void Graphics::saveStateIfPending()
{
if (saveStatePending)
{
JUCE_SCOPED_TRACE_EVENT_FRAME (etw::saveState, etw::graphicsKeyword, context.getFrameId());
saveStatePending = false;
context.saveState();
}
@ -222,6 +240,8 @@ void Graphics::setOrigin (int x, int y)
void Graphics::addTransform (const AffineTransform& transform)
{
JUCE_SCOPED_TRACE_EVENT_FRAME (etw::addTransform, etw::graphicsKeyword, context.getFrameId());
saveStateIfPending();
context.addTransform (transform);
}
@ -233,12 +253,16 @@ bool Graphics::clipRegionIntersects (Rectangle<int> area) const
void Graphics::beginTransparencyLayer (float layerOpacity)
{
JUCE_SCOPED_TRACE_EVENT_FRAME (etw::beginTransparencyLayer, etw::graphicsKeyword, context.getFrameId());
saveStateIfPending();
context.beginTransparencyLayer (layerOpacity);
}
void Graphics::endTransparencyLayer()
{
JUCE_SCOPED_TRACE_EVENT_FRAME (etw::endTransparencyLayer, etw::graphicsKeyword, context.getFrameId());
context.endTransparencyLayer();
}
@ -477,42 +501,62 @@ void Graphics::drawFittedText (const String& text, int x, int y, int width, int
//==============================================================================
void Graphics::fillRect (Rectangle<int> r) const
{
JUCE_SCOPED_TRACE_EVENT_FRAME_RECT_I32 (etw::fillRect, etw::graphicsKeyword, context.getFrameId(), r)
context.fillRect (r, false);
}
void Graphics::fillRect (Rectangle<float> r) const
{
JUCE_SCOPED_TRACE_EVENT_FRAME_RECT_F32 (etw::fillRect, etw::graphicsKeyword, context.getFrameId(), r)
context.fillRect (r);
}
void Graphics::fillRect (int x, int y, int width, int height) const
{
JUCE_SCOPED_TRACE_EVENT_FRAME_RECT_I32 (etw::fillRect, etw::graphicsKeyword, context.getFrameId(), (Rectangle { x, y, width, height }))
context.fillRect (coordsToRectangle (x, y, width, height), false);
}
void Graphics::fillRect (float x, float y, float width, float height) const
{
JUCE_SCOPED_TRACE_EVENT_FRAME_RECT_F32 (etw::fillRect, etw::graphicsKeyword, context.getFrameId(), (Rectangle { x, y, width, height }))
fillRect (coordsToRectangle (x, y, width, height));
}
void Graphics::fillRectList (const RectangleList<float>& rectangles) const
{
JUCE_SCOPED_TRACE_EVENT_FRAME_RECT_F32 (etw::fillRectList, etw::graphicsKeyword, context.getFrameId(), rectangles)
context.fillRectList (rectangles);
}
void Graphics::fillRectList (const RectangleList<int>& rects) const
{
for (auto& r : rects)
context.fillRect (r, false);
JUCE_SCOPED_TRACE_EVENT_FRAME_RECT_I32 (etw::fillRectList, etw::graphicsKeyword, context.getFrameId(), rects)
RectangleList<float> converted;
for (const auto& r : rects)
converted.add (r.toFloat());
context.fillRectList (converted);
}
void Graphics::fillAll() const
{
JUCE_SCOPED_TRACE_EVENT_FRAME (etw::fillAll, etw::graphicsKeyword, context.getFrameId())
context.fillAll();
}
void Graphics::fillAll (Colour colourToUse) const
{
JUCE_SCOPED_TRACE_EVENT_FRAME (etw::fillAll, etw::graphicsKeyword, context.getFrameId())
if (! colourToUse.isTransparent())
{
context.saveState();
@ -522,16 +566,19 @@ void Graphics::fillAll (Colour colourToUse) const
}
}
//==============================================================================
void Graphics::fillPath (const Path& path) const
{
JUCE_SCOPED_TRACE_EVENT_FRAME (etw::fillPath, etw::graphicsKeyword, context.getFrameId());
if (! (context.isClipEmpty() || path.isEmpty()))
context.fillPath (path, AffineTransform());
}
void Graphics::fillPath (const Path& path, const AffineTransform& transform) const
{
JUCE_SCOPED_TRACE_EVENT_FRAME (etw::fillPath, etw::graphicsKeyword, context.getFrameId())
if (! (context.isClipEmpty() || path.isEmpty()))
context.fillPath (path, transform);
}
@ -540,9 +587,10 @@ void Graphics::strokePath (const Path& path,
const PathStrokeType& strokeType,
const AffineTransform& transform) const
{
Path stroke;
strokeType.createStrokedPath (stroke, path, transform, context.getPhysicalPixelScaleFactor());
fillPath (stroke);
JUCE_SCOPED_TRACE_EVENT_FRAME (etw::strokePath, etw::graphicsKeyword, context.getFrameId())
if (! (context.isClipEmpty() || path.isEmpty()))
context.strokePath (path, strokeType, transform);
}
//==============================================================================
@ -563,22 +611,16 @@ void Graphics::drawRect (Rectangle<int> r, int lineThickness) const
void Graphics::drawRect (Rectangle<float> r, const float lineThickness) const
{
jassert (r.getWidth() >= 0.0f && r.getHeight() >= 0.0f);
JUCE_SCOPED_TRACE_EVENT_FRAME_RECT_F32 (etw::drawRect, etw::graphicsKeyword, context.getFrameId(), r)
RectangleList<float> rects;
rects.addWithoutMerging (r.removeFromTop (lineThickness));
rects.addWithoutMerging (r.removeFromBottom (lineThickness));
rects.addWithoutMerging (r.removeFromLeft (lineThickness));
rects.addWithoutMerging (r.removeFromRight (lineThickness));
context.fillRectList (rects);
jassert (r.getWidth() >= 0.0f && r.getHeight() >= 0.0f);
context.drawRect (r, lineThickness);
}
//==============================================================================
void Graphics::fillEllipse (Rectangle<float> area) const
{
Path p;
p.addEllipse (area);
fillPath (p);
context.fillEllipse (area);
}
void Graphics::fillEllipse (float x, float y, float w, float h) const
@ -593,21 +635,7 @@ void Graphics::drawEllipse (float x, float y, float width, float height, float l
void Graphics::drawEllipse (Rectangle<float> area, float lineThickness) const
{
Path p;
if (approximatelyEqual (area.getWidth(), area.getHeight()))
{
// For a circle, we can avoid having to generate a stroke
p.addEllipse (area.expanded (lineThickness * 0.5f));
p.addEllipse (area.reduced (lineThickness * 0.5f));
p.setUsingNonZeroWinding (false);
fillPath (p);
}
else
{
p.addEllipse (area);
strokePath (p, PathStrokeType (lineThickness));
}
context.drawEllipse (area, lineThickness);
}
void Graphics::fillRoundedRectangle (float x, float y, float width, float height, float cornerSize) const
@ -617,9 +645,7 @@ void Graphics::fillRoundedRectangle (float x, float y, float width, float height
void Graphics::fillRoundedRectangle (Rectangle<float> r, const float cornerSize) const
{
Path p;
p.addRoundedRectangle (r, cornerSize);
fillPath (p);
context.fillRoundedRectangle (r, cornerSize);
}
void Graphics::drawRoundedRectangle (float x, float y, float width, float height,
@ -630,9 +656,7 @@ void Graphics::drawRoundedRectangle (float x, float y, float width, float height
void Graphics::drawRoundedRectangle (Rectangle<float> r, float cornerSize, float lineThickness) const
{
Path p;
p.addRoundedRectangle (r, cornerSize);
strokePath (p, PathStrokeType (lineThickness));
context.drawRoundedRectangle (r, cornerSize, lineThickness);
}
void Graphics::drawArrow (Line<float> line, float lineThickness, float arrowheadWidth, float arrowheadLength) const
@ -719,9 +743,7 @@ void Graphics::drawLine (float x1, float y1, float x2, float y2, float lineThick
void Graphics::drawLine (Line<float> line, const float lineThickness) const
{
Path p;
p.addLineSegment (line, lineThickness);
fillPath (p);
context.drawLineWithThickness (line, lineThickness);
}
void Graphics::drawDashedLine (Line<float> line, const float* dashLengths,

View file

@ -71,7 +71,7 @@ public:
*/
virtual void setOrigin (Point<int>) = 0;
virtual void addTransform (const AffineTransform&) = 0;
virtual float getPhysicalPixelScaleFactor() = 0;
virtual float getPhysicalPixelScaleFactor() const = 0;
virtual bool clipToRectangle (const Rectangle<int>&) = 0;
virtual bool clipToRectangleList (const RectangleList<int>&) = 0;
@ -100,9 +100,35 @@ public:
virtual void fillRect (const Rectangle<float>&) = 0;
virtual void fillRectList (const RectangleList<float>&) = 0;
virtual void fillPath (const Path&, const AffineTransform&) = 0;
virtual void drawRect (const Rectangle<float>& rect, float lineThickness)
{
auto r = rect;
RectangleList<float> rects;
rects.addWithoutMerging (r.removeFromTop (lineThickness));
rects.addWithoutMerging (r.removeFromBottom (lineThickness));
rects.addWithoutMerging (r.removeFromLeft (lineThickness));
rects.addWithoutMerging (r.removeFromRight (lineThickness));
fillRectList (rects);
}
virtual void strokePath (const Path& path, const PathStrokeType& strokeType, const AffineTransform& transform)
{
Path stroke;
strokeType.createStrokedPath (stroke, path, transform, getPhysicalPixelScaleFactor());
fillPath (stroke, {});
}
virtual void drawImage (const Image&, const AffineTransform&) = 0;
virtual void drawLine (const Line<float>&) = 0;
virtual void drawLineWithThickness (const Line<float>& line, float lineThickness)
{
Path p;
p.addLineSegment (line, lineThickness);
fillPath (p, {});
}
virtual void setFont (const Font&) = 0;
virtual const Font& getFont() = 0;
@ -110,6 +136,51 @@ public:
virtual void drawGlyphs (Span<const uint16_t>,
Span<const Point<float>>,
const AffineTransform&) = 0;
virtual void drawRoundedRectangle (const Rectangle<float>& r, float cornerSize, float lineThickness)
{
Path p;
p.addRoundedRectangle (r, cornerSize);
strokePath (p, PathStrokeType (lineThickness), {});
}
virtual void fillRoundedRectangle (const Rectangle<float>& r, float cornerSize)
{
Path p;
p.addRoundedRectangle (r, cornerSize);
fillPath (p, {});
}
virtual void drawEllipse (const Rectangle<float>& area, float lineThickness)
{
Path p;
if (approximatelyEqual (area.getWidth(), area.getHeight()))
{
// For a circle, we can avoid having to generate a stroke
p.addEllipse (area.expanded (lineThickness * 0.5f));
p.addEllipse (area.reduced (lineThickness * 0.5f));
p.setUsingNonZeroWinding (false);
fillPath (p, {});
}
else
{
p.addEllipse (area);
strokePath (p, PathStrokeType (lineThickness), {});
}
}
virtual void fillEllipse (const Rectangle<float>& area)
{
Path p;
p.addEllipse (area);
fillPath (p, {});
}
/** Returns an integer that uniquely identifies the current frame.
Useful for debugging/logging.
*/
virtual uint64_t getFrameId() const = 0;
};
} // namespace juce

View file

@ -114,7 +114,7 @@ void LowLevelGraphicsPostScriptRenderer::addTransform (const AffineTransform& /*
jassertfalse;
}
float LowLevelGraphicsPostScriptRenderer::getPhysicalPixelScaleFactor() { return 1.0f; }
float LowLevelGraphicsPostScriptRenderer::getPhysicalPixelScaleFactor() const { return 1.0f; }
bool LowLevelGraphicsPostScriptRenderer::clipToRectangle (const Rectangle<int>& r)
{

View file

@ -55,7 +55,7 @@ public:
bool isVectorDevice() const override;
void setOrigin (Point<int>) override;
void addTransform (const AffineTransform&) override;
float getPhysicalPixelScaleFactor() override;
float getPhysicalPixelScaleFactor() const override;
bool clipToRectangle (const Rectangle<int>&) override;
bool clipToRectangleList (const RectangleList<int>&) override;

View file

@ -39,6 +39,7 @@ LowLevelGraphicsSoftwareRenderer::LowLevelGraphicsSoftwareRenderer (const Image&
: RenderingHelpers::StackBasedLowLevelGraphicsContext<RenderingHelpers::SoftwareRendererSavedState>
(new RenderingHelpers::SoftwareRendererSavedState (image, image.getBounds()))
{
JUCE_TRACE_LOG_PAINT_CALL (etw::startGDIImage, getFrameId());
}
LowLevelGraphicsSoftwareRenderer::LowLevelGraphicsSoftwareRenderer (const Image& image, Point<int> origin,
@ -46,8 +47,13 @@ LowLevelGraphicsSoftwareRenderer::LowLevelGraphicsSoftwareRenderer (const Image&
: RenderingHelpers::StackBasedLowLevelGraphicsContext<RenderingHelpers::SoftwareRendererSavedState>
(new RenderingHelpers::SoftwareRendererSavedState (image, initialClip, origin))
{
JUCE_TRACE_EVENT_INT_RECT_LIST (etw::startGDIFrame, etw::softwareRendererKeyword, getFrameId(), initialClip);
}
LowLevelGraphicsSoftwareRenderer::~LowLevelGraphicsSoftwareRenderer() {}
LowLevelGraphicsSoftwareRenderer::~LowLevelGraphicsSoftwareRenderer()
{
JUCE_TRACE_LOG_PAINT_CALL (etw::endGDIFrame, getFrameId());
}
} // namespace juce

View file

@ -35,47 +35,6 @@
namespace juce
{
static void blurDataTriplets (uint8* d, int num, const int delta) noexcept
{
uint32 last = d[0];
d[0] = (uint8) ((d[0] + d[delta] + 1) / 3);
d += delta;
num -= 2;
do
{
const uint32 newLast = d[0];
d[0] = (uint8) ((last + d[0] + d[delta] + 1) / 3);
d += delta;
last = newLast;
}
while (--num > 0);
d[0] = (uint8) ((last + d[0] + 1) / 3);
}
static void blurSingleChannelImage (uint8* const data, const int width, const int height,
const int lineStride, const int repetitions) noexcept
{
jassert (width > 2 && height > 2);
for (int y = 0; y < height; ++y)
for (int i = repetitions; --i >= 0;)
blurDataTriplets (data + lineStride * y, width, 1);
for (int x = 0; x < width; ++x)
for (int i = repetitions; --i >= 0;)
blurDataTriplets (data + x, height, lineStride);
}
static void blurSingleChannelImage (Image& image, int radius)
{
const Image::BitmapData bm (image, Image::BitmapData::readWrite);
blurSingleChannelImage (bm.data, bm.width, bm.height, bm.lineStride, 2 * radius);
}
//==============================================================================
DropShadow::DropShadow (Colour shadowColour, const int r, Point<int> o) noexcept
: colour (shadowColour), radius (r), offset (o)
{
@ -86,16 +45,15 @@ void DropShadow::drawForImage (Graphics& g, const Image& srcImage) const
{
jassert (radius > 0);
if (srcImage.isValid())
{
Image shadowImage (srcImage.convertedToFormat (Image::SingleChannel));
shadowImage.duplicateIfShared();
if (! srcImage.isValid())
return;
blurSingleChannelImage (shadowImage, radius);
Image blurred;
srcImage.convertedToFormat (Image::SingleChannel)
.applyGaussianBlurEffect ((float) radius, blurred);
g.setColour (colour);
g.drawImageAt (shadowImage, offset.x, offset.y, true);
}
g.setColour (colour);
g.drawImageAt (blurred, offset.x, offset.y, true);
}
void DropShadow::drawForPath (Graphics& g, const Path& path) const
@ -103,24 +61,25 @@ void DropShadow::drawForPath (Graphics& g, const Path& path) const
jassert (radius > 0);
auto area = (path.getBounds().getSmallestIntegerContainer() + offset)
.expanded (radius + 1)
.getIntersection (g.getClipBounds().expanded (radius + 1));
.expanded (radius + 1)
.getIntersection (g.getClipBounds().expanded (radius + 1));
if (area.getWidth() > 2 && area.getHeight() > 2)
{
Image renderedPath (Image::SingleChannel, area.getWidth(), area.getHeight(), true);
Image pathImage { Image::SingleChannel, area.getWidth(), area.getHeight(), true };
{
Graphics g2 (renderedPath);
Graphics g2 (pathImage);
g2.setColour (Colours::white);
g2.fillPath (path, AffineTransform::translation ((float) (offset.x - area.getX()),
(float) (offset.y - area.getY())));
}
blurSingleChannelImage (renderedPath, radius);
Image blurred;
pathImage.applyGaussianBlurEffect ((float) radius, blurred);
g.setColour (colour);
g.drawImageAt (renderedPath, area.getX(), area.getY(), true);
g.drawImageAt (blurred, area.getX(), area.getY(), true);
}
}
@ -167,8 +126,8 @@ void DropShadow::drawForRectangle (Graphics& g, const Rectangle<int>& targetArea
}
//==============================================================================
DropShadowEffect::DropShadowEffect() {}
DropShadowEffect::~DropShadowEffect() {}
DropShadowEffect::DropShadowEffect() = default;
DropShadowEffect::~DropShadowEffect() = default;
void DropShadowEffect::setShadowProperties (const DropShadow& newShadow)
{

View file

@ -35,8 +35,8 @@
namespace juce
{
GlowEffect::GlowEffect() {}
GlowEffect::~GlowEffect() {}
GlowEffect::GlowEffect() = default;
GlowEffect::~GlowEffect() = default;
void GlowEffect::setGlowProperties (float newRadius, Colour newColour, Point<int> pos)
{
@ -47,17 +47,10 @@ void GlowEffect::setGlowProperties (float newRadius, Colour newColour, Point<int
void GlowEffect::applyEffect (Image& image, Graphics& g, float scaleFactor, float alpha)
{
Image temp (image.getFormat(), image.getWidth(), image.getHeight(), true);
ImageConvolutionKernel blurKernel (roundToInt (radius * scaleFactor * 2.0f));
blurKernel.createGaussianBlur (radius);
blurKernel.rescaleAllValues (radius);
blurKernel.applyToImage (temp, image, image.getBounds());
image.applyGaussianBlurEffect (radius * scaleFactor, cachedImage);
g.setColour (colour.withMultipliedAlpha (alpha));
g.drawImageAt (temp, offset.x, offset.y, true);
g.drawImageAt (cachedImage, offset.x, offset.y, true);
g.setOpacity (alpha);
g.drawImageAt (image, offset.x, offset.y, false);

View file

@ -78,6 +78,7 @@ private:
float radius = 2.0f;
Colour colour { Colours::white };
Point<int> offset;
Image cachedImage;
JUCE_LEAK_DETECTOR (GlowEffect)
};

View file

@ -774,6 +774,10 @@ static bool characterNotRendered (uint32_t c)
static bool isFontSuitableForCodepoint (const Font& font, juce_wchar c)
{
const auto& hbFont = font.getNativeDetails().font;
if (hbFont == nullptr)
return false;
hb_codepoint_t glyph{};
return characterNotRendered ((uint32_t) c)

View file

@ -322,12 +322,12 @@ private:
};
/* Returns glyphs in logical order as that favours wrapping. */
static auto lowLevelShape (const String& string,
Range<int64> range,
const Font& font,
TextScript script,
const String& language,
TextDirection direction)
static std::vector<ShapedGlyph> lowLevelShape (const String& string,
Range<int64> range,
const Font& font,
TextScript script,
const String& language,
TextDirection direction)
{
HbBuffer buffer { hb_buffer_create() };
hb_buffer_clear_contents (buffer.get());
@ -431,6 +431,12 @@ static auto lowLevelShape (const String& string,
auto nativeFont = font.getNativeDetails().font;
if (nativeFont == nullptr)
{
jassertfalse;
return {};
}
hb_shape (nativeFont.get(), buffer.get(), features.data(), (unsigned int) features.size());
const auto [infos, positions] = [&buffer]

View file

@ -77,9 +77,7 @@ static bool isMarker (float value, float marker) noexcept
}
//==============================================================================
Path::PathBounds::PathBounds() noexcept
{
}
Path::PathBounds::PathBounds() noexcept = default;
Rectangle<float> Path::PathBounds::getRectangle() const noexcept
{
@ -88,7 +86,7 @@ Rectangle<float> Path::PathBounds::getRectangle() const noexcept
void Path::PathBounds::reset() noexcept
{
pathXMin = pathYMin = pathYMax = pathXMax = 0;
*this = {};
}
void Path::PathBounds::reset (float x, float y) noexcept
@ -107,13 +105,9 @@ void Path::PathBounds::extend (float x, float y) noexcept
}
//==============================================================================
Path::Path()
{
}
Path::Path() = default;
Path::~Path()
{
}
Path::~Path() = default;
Path::Path (const Path& other)
: data (other.data),
@ -124,32 +118,31 @@ Path::Path (const Path& other)
Path& Path::operator= (const Path& other)
{
if (this != &other)
{
data = other.data;
bounds = other.bounds;
useNonZeroWinding = other.useNonZeroWinding;
}
auto copy = other;
*this = std::move (copy);
return *this;
}
Path::Path (Path&& other) noexcept
: data (std::move (other.data)),
bounds (other.bounds),
useNonZeroWinding (other.useNonZeroWinding)
: data (std::exchange (other.data, {})),
bounds (std::exchange (other.bounds, {})),
useNonZeroWinding (std::exchange (other.useNonZeroWinding, {}))
{
}
Path& Path::operator= (Path&& other) noexcept
{
data = std::move (other.data);
bounds = other.bounds;
useNonZeroWinding = other.useNonZeroWinding;
auto copy = std::move (other);
swapWithPath (copy);
return *this;
}
bool Path::operator== (const Path& other) const noexcept { return useNonZeroWinding == other.useNonZeroWinding && data == other.data; }
bool Path::operator== (const Path& other) const noexcept
{
const auto tie = [] (const auto& x) { return std::tie (x.useNonZeroWinding, x.data); };
return tie (*this) == tie (other);
}
bool Path::operator!= (const Path& other) const noexcept { return ! operator== (other); }
void Path::clear() noexcept
@ -161,10 +154,7 @@ void Path::clear() noexcept
void Path::swapWithPath (Path& other) noexcept
{
data.swapWith (other.data);
std::swap (bounds.pathXMin, other.bounds.pathXMin);
std::swap (bounds.pathXMax, other.bounds.pathXMax);
std::swap (bounds.pathYMin, other.bounds.pathYMin);
std::swap (bounds.pathYMax, other.bounds.pathYMax);
std::swap (bounds, other.bounds);
std::swap (useNonZeroWinding, other.useNonZeroWinding);
}
@ -967,8 +957,8 @@ bool Path::contains (float x, float y, float tolerance) const
}
}
return useNonZeroWinding ? (negativeCrossings != positiveCrossings)
: ((negativeCrossings + positiveCrossings) & 1) != 0;
return isUsingNonZeroWinding() ? (negativeCrossings != positiveCrossings)
: ((negativeCrossings + positiveCrossings) & 1) != 0;
}
bool Path::contains (Point<float> point, float tolerance) const
@ -1279,11 +1269,11 @@ void Path::loadPathFromStream (InputStream& source)
break;
case 'n':
useNonZeroWinding = true;
setUsingNonZeroWinding (true);
break;
case 'z':
useNonZeroWinding = false;
setUsingNonZeroWinding (false);
break;
case 'e':
@ -1304,7 +1294,7 @@ void Path::loadPathFromData (const void* const pathData, const size_t numberOfBy
void Path::writePathToStream (OutputStream& dest) const
{
dest.writeByte (useNonZeroWinding ? 'n' : 'z');
dest.writeByte (isUsingNonZeroWinding() ? 'n' : 'z');
for (auto* i = data.begin(); i != data.end();)
{
@ -1352,7 +1342,7 @@ void Path::writePathToStream (OutputStream& dest) const
String Path::toString() const
{
MemoryOutputStream s (2048);
if (! useNonZeroWinding)
if (! isUsingNonZeroWinding())
s << 'a';
float lastMarker = 0.0f;
@ -1489,10 +1479,6 @@ Path::Iterator::Iterator (const Path& p) noexcept
{
}
Path::Iterator::~Iterator() noexcept
{
}
bool Path::Iterator::next() noexcept
{
if (index != path.data.end())

View file

@ -724,7 +724,6 @@ public:
*/
bool isUsingNonZeroWinding() const { return useNonZeroWinding; }
//==============================================================================
/** Iterates the lines and curves that a path contains.
@ -735,7 +734,6 @@ public:
public:
//==============================================================================
Iterator (const Path& path) noexcept;
~Iterator() noexcept;
//==============================================================================
/** Moves onto the next element in the path.

View file

@ -35,6 +35,96 @@
namespace juce
{
struct BitmapDataDetail
{
BitmapDataDetail() = delete;
static void convert (const Image::BitmapData& src, Image::BitmapData& dest)
{
jassert (src.width == dest.width);
jassert (src.height == dest.height);
if (src.pixelStride == dest.pixelStride && src.pixelFormat == dest.pixelFormat)
{
for (int y = 0; y < dest.height; ++y)
memcpy (dest.getLinePointer (y), src.getLinePointer (y), (size_t) dest.pixelStride * (size_t) dest.width);
}
else
{
for (int y = 0; y < dest.height; ++y)
for (int x = 0; x < dest.width; ++x)
dest.setPixelColour (x, y, src.getPixelColour (x, y));
}
}
static Image convert (const Image::BitmapData& src, const ImageType& type)
{
Image result (type.create (src.pixelFormat, src.width, src.height, false));
{
Image::BitmapData dest (result, Image::BitmapData::writeOnly);
BitmapDataDetail::convert (src, dest);
}
return result;
}
};
class SubsectionPixelData : public ImagePixelData
{
public:
SubsectionPixelData (ImagePixelData::Ptr source, Rectangle<int> r)
: ImagePixelData (source->pixelFormat, r.getWidth(), r.getHeight()),
sourceImage (std::move (source)),
area (r)
{
}
std::unique_ptr<LowLevelGraphicsContext> createLowLevelContext() override
{
auto g = sourceImage->createLowLevelContext();
g->clipToRectangle (area);
g->setOrigin (area.getPosition());
return g;
}
void initialiseBitmapData (Image::BitmapData& bitmap, int x, int y, Image::BitmapData::ReadWriteMode mode) override
{
sourceImage->initialiseBitmapData (bitmap, x + area.getX(), y + area.getY(), mode);
if (mode != Image::BitmapData::readOnly)
sendDataChangeMessage();
}
ImagePixelData::Ptr clone() override
{
jassert (getReferenceCount() > 0); // (This method can't be used on an unowned pointer, as it will end up self-deleting)
auto type = createType();
Image newImage (type->create (pixelFormat, area.getWidth(), area.getHeight(), pixelFormat != Image::RGB));
{
Graphics g (newImage);
g.drawImageAt (Image (*this), 0, 0);
}
return *newImage.getPixelData();
}
std::unique_ptr<ImageType> createType() const override { return sourceImage->createType(); }
/* as we always hold a reference to image, don't double count */
int getSharedCount() const noexcept override { return getReferenceCount() + sourceImage->getSharedCount() - 1; }
private:
friend class Image;
const ImagePixelData::Ptr sourceImage;
const Rectangle<int> area;
JUCE_DECLARE_NON_COPYABLE_WITH_LEAK_DETECTOR (SubsectionPixelData)
};
//==============================================================================
ImagePixelData::ImagePixelData (Image::PixelFormat format, int w, int h)
: pixelFormat (format), width (w), height (h)
{
@ -57,9 +147,14 @@ int ImagePixelData::getSharedCount() const noexcept
return getReferenceCount();
}
void ImagePixelData::applyGaussianBlurEffect ([[maybe_unused]] float radius, Image& result)
{
result = {};
}
//==============================================================================
ImageType::ImageType() {}
ImageType::~ImageType() {}
ImageType::ImageType() = default;
ImageType::~ImageType() = default;
Image ImageType::convert (const Image& source) const
{
@ -68,26 +163,14 @@ Image ImageType::convert (const Image& source) const
const Image::BitmapData src (source, Image::BitmapData::readOnly);
Image newImage (create (src.pixelFormat, src.width, src.height, false));
Image::BitmapData dest (newImage, Image::BitmapData::writeOnly);
if (src.data == nullptr)
return {};
if (src.pixelStride == dest.pixelStride && src.pixelFormat == dest.pixelFormat)
{
for (int y = 0; y < dest.height; ++y)
memcpy (dest.getLinePointer (y), src.getLinePointer (y), (size_t) dest.lineStride);
}
else
{
for (int y = 0; y < dest.height; ++y)
for (int x = 0; x < dest.width; ++x)
dest.setPixelColour (x, y, src.getPixelColour (x, y));
}
return newImage;
return BitmapDataDetail::convert (src, *this);
}
//==============================================================================
class SoftwarePixelData final : public ImagePixelData
class SoftwarePixelData : public ImagePixelData
{
public:
SoftwarePixelData (Image::PixelFormat formatToUse, int w, int h, bool clearImage)
@ -133,8 +216,8 @@ private:
JUCE_LEAK_DETECTOR (SoftwarePixelData)
};
SoftwareImageType::SoftwareImageType() {}
SoftwareImageType::~SoftwareImageType() {}
SoftwareImageType::SoftwareImageType() = default;
SoftwareImageType::~SoftwareImageType() = default;
ImagePixelData::Ptr SoftwareImageType::create (Image::PixelFormat format, int width, int height, bool clearImage) const
{
@ -147,15 +230,15 @@ int SoftwareImageType::getTypeID() const
}
//==============================================================================
NativeImageType::NativeImageType() {}
NativeImageType::~NativeImageType() {}
NativeImageType::NativeImageType() = default;
NativeImageType::~NativeImageType() = default;
int NativeImageType::getTypeID() const
{
return 1;
}
#if JUCE_WINDOWS || JUCE_LINUX || JUCE_BSD
#if JUCE_LINUX || JUCE_BSD
ImagePixelData::Ptr NativeImageType::create (Image::PixelFormat format, int width, int height, bool clearImage) const
{
return new SoftwarePixelData (format, width, height, clearImage);
@ -163,58 +246,6 @@ ImagePixelData::Ptr NativeImageType::create (Image::PixelFormat format, int widt
#endif
//==============================================================================
class SubsectionPixelData final : public ImagePixelData
{
public:
SubsectionPixelData (ImagePixelData::Ptr source, Rectangle<int> r)
: ImagePixelData (source->pixelFormat, r.getWidth(), r.getHeight()),
sourceImage (std::move (source)), area (r)
{
}
std::unique_ptr<LowLevelGraphicsContext> createLowLevelContext() override
{
auto g = sourceImage->createLowLevelContext();
g->clipToRectangle (area);
g->setOrigin (area.getPosition());
return g;
}
void initialiseBitmapData (Image::BitmapData& bitmap, int x, int y, Image::BitmapData::ReadWriteMode mode) override
{
sourceImage->initialiseBitmapData (bitmap, x + area.getX(), y + area.getY(), mode);
if (mode != Image::BitmapData::readOnly)
sendDataChangeMessage();
}
ImagePixelData::Ptr clone() override
{
jassert (getReferenceCount() > 0); // (This method can't be used on an unowned pointer, as it will end up self-deleting)
auto type = createType();
Image newImage (type->create (pixelFormat, area.getWidth(), area.getHeight(), pixelFormat != Image::RGB));
{
Graphics g (newImage);
g.drawImageAt (Image (*this), 0, 0);
}
return *newImage.getPixelData();
}
std::unique_ptr<ImageType> createType() const override { return sourceImage->createType(); }
/* as we always hold a reference to image, don't double count */
int getSharedCount() const noexcept override { return getReferenceCount() + sourceImage->getSharedCount() - 1; }
private:
friend class Image;
const ImagePixelData::Ptr sourceImage;
const Rectangle<int> area;
JUCE_DECLARE_NON_COPYABLE_WITH_LEAK_DETECTOR (SubsectionPixelData)
};
Image Image::getClippedImage (const Rectangle<int>& area) const
{
@ -226,14 +257,11 @@ Image Image::getClippedImage (const Rectangle<int>& area) const
if (validArea.isEmpty())
return {};
return Image (*new SubsectionPixelData (image, validArea));
return Image { ImagePixelData::Ptr { new SubsectionPixelData { image, validArea } } };
}
//==============================================================================
Image::Image() noexcept
{
}
Image::Image() noexcept = default;
Image::Image (ReferenceCountedObjectPtr<ImagePixelData> instance) noexcept
: image (std::move (instance))
@ -272,11 +300,44 @@ Image& Image::operator= (Image&& other) noexcept
return *this;
}
Image::~Image()
{
}
Image::~Image() = default;
int Image::getReferenceCount() const noexcept { return image == nullptr ? 0 : image->getSharedCount(); }
void Image::applyGaussianBlurEffect (float radius, Image& result) const
{
if (image == nullptr)
{
result = {};
return;
}
auto copy = result;
image->applyGaussianBlurEffect (radius, copy);
if (copy.isValid())
{
result = std::move (copy);
return;
}
const auto tie = [] (const auto& x) { return std::tuple (x.getFormat(), x.getWidth(), x.getHeight()); };
if (tie (*this) != tie (result))
result = Image { getFormat(), getWidth(), getHeight(), false };
ImageConvolutionKernel blurKernel (roundToInt (radius * 2.0f));
blurKernel.createGaussianBlur (radius);
blurKernel.applyToImage (result, *this, result.getBounds());
}
bool Image::isValid() const noexcept
{
return image != nullptr;
}
int Image::getWidth() const noexcept { return image == nullptr ? 0 : image->width; }
int Image::getHeight() const noexcept { return image == nullptr ? 0 : image->height; }
Rectangle<int> Image::getBounds() const noexcept { return image == nullptr ? Rectangle<int>() : Rectangle<int> (image->width, image->height); }

View file

@ -153,7 +153,7 @@ public:
The isNull() method is the opposite of isValid().
@see isNull
*/
inline bool isValid() const noexcept { return image != nullptr; }
bool isValid() const noexcept;
/** Returns true if this image is not valid.
If you create an Image with the default constructor, it has no size or content, and is null
@ -161,7 +161,7 @@ public:
The isNull() method is the opposite of isValid().
@see isValid
*/
inline bool isNull() const noexcept { return image == nullptr; }
bool isNull() const noexcept { return ! isValid(); }
//==============================================================================
/** Returns the image's width (in pixels). */
@ -416,6 +416,13 @@ public:
*/
int getReferenceCount() const noexcept;
/** Applies a blur to this image, placing the blurred image in the result out-parameter.
If result is already the correct size, then its storage will be reused directly.
Otherwise, new storage may be allocated for the blurred image.
*/
void applyGaussianBlurEffect (float radius, Image& result) const;
//==============================================================================
/** @internal */
ImagePixelData* getPixelData() const noexcept { return image.get(); }
@ -469,9 +476,19 @@ public:
virtual void initialiseBitmapData (Image::BitmapData&, int x, int y, Image::BitmapData::ReadWriteMode) = 0;
/** Returns the number of Image objects which are currently referring to the same internal
shared image data. This is different to the reference count as an instance of ImagePixelData
can internally depend on another ImagePixelData via it's member variables. */
can internally depend on another ImagePixelData via it's member variables.
*/
virtual int getSharedCount() const noexcept;
/** Applies a native blur effect to this image, if available.
Implementations should attempt to re-use the storage provided in the result out-parameter
when possible.
If native blurs are unsupported, or if creating a blur fails for any other reason,
the result out-parameter will be reset to an invalid image.
*/
virtual void applyGaussianBlurEffect (float radius, Image& result);
/** The pixel format of the image data. */
const Image::PixelFormat pixelFormat;

View file

@ -55,19 +55,45 @@
#include <CoreText/CTFont.h>
#elif JUCE_WINDOWS
// get rid of some warnings in Window's own headers
// get rid of some warnings in Window's own headers
JUCE_BEGIN_IGNORE_WARNINGS_MSVC (4458)
#include <d2d1.h>
#include <dwrite_3.h>
/* If you hit a compile error trying to include these files, you may need to update
your version of the Windows SDK to the latest one. The DirectWrite and Direct2D
headers are in the version 8 SDKs.
#if JUCE_MINGW
#include <malloc.h>
#include <cstdio>
#endif
Need Direct2D 1.3 for sprite batching
*/
#include <d2d1_3.h>
#include <d3d11_2.h>
#include <dcomp.h>
#include <dwrite_3.h>
#include <dxgi1_3.h>
#include <processthreadsapi.h>
#if JUCE_ETW_TRACELOGGING
#include <evntrace.h>
#include <TraceLoggingProvider.h>
TRACELOGGING_DEFINE_PROVIDER (JUCETraceLogProvider,
"JUCETraceLogProvider",
// {6A612E78-284D-4DDB-877A-5F521EB33132}
(0x6a612e78, 0x284d, 0x4ddb, 0x87, 0x7a, 0x5f, 0x52, 0x1e, 0xb3, 0x31, 0x32));
#endif
JUCE_END_IGNORE_WARNINGS_MSVC
#if ! JUCE_DONT_AUTOLINK_TO_WIN32_LIBRARIES
#pragma comment(lib, "Dwrite.lib")
#pragma comment(lib, "D2d1.lib")
#pragma comment(lib, "DXGI.lib")
#pragma comment(lib, "D3D11.lib")
#pragma comment(lib, "DComp.lib")
#pragma comment(lib, "dxguid.lib")
#endif
#elif JUCE_IOS
#import <QuartzCore/QuartzCore.h>
#import <CoreText/CoreText.h>
@ -120,6 +146,7 @@
//==============================================================================
#include "fonts/juce_FunctionPointerDestructor.h"
#include "native/juce_EventTracing.h"
#include "unicode/juce_UnicodeScript.h"
#include "unicode/juce_Unicode.h"
@ -179,11 +206,18 @@
#include "native/juce_IconHelpers_mac.cpp"
#elif JUCE_WINDOWS
#include "native/juce_DirectX_windows.h"
#include "native/juce_DirectWriteTypeface_windows.cpp"
#include "native/juce_IconHelpers_windows.cpp"
#if JUCE_DIRECT2D
#include "native/juce_Direct2DGraphicsContext_windows.cpp"
#endif
#include "native/juce_Direct2DHelpers_windows.cpp"
#include "native/juce_Direct2DResources_windows.cpp"
#include "native/juce_Direct2DImage_windows.h"
#include "native/juce_Direct2DGraphicsContext_windows.cpp"
#include "native/juce_Direct2DHwndContext_windows.cpp"
#include "native/juce_Direct2DImageContext_windows.h"
#include "native/juce_Direct2DImageContext_windows.cpp"
#include "native/juce_Direct2DImage_windows.cpp"
#include "native/juce_Direct2DMetrics_windows.cpp"
#elif JUCE_LINUX || JUCE_BSD
#include "native/juce_Fonts_linux.cpp"

View file

@ -78,15 +78,6 @@
#define JUCE_USE_COREIMAGE_LOADER 1
#endif
/** Config: JUCE_USE_DIRECTWRITE
Enabling this flag means that DirectWrite will be used when available for font
management and layout.
*/
#ifndef JUCE_USE_DIRECTWRITE
#define JUCE_USE_DIRECTWRITE 1
#endif
/** Config: JUCE_DISABLE_COREGRAPHICS_FONT_SMOOTHING
Setting this flag will turn off CoreGraphics font smoothing on macOS, which some people
@ -165,6 +156,8 @@ namespace juce
#include "native/juce_CoreGraphicsContext_mac.h"
#endif
#if JUCE_DIRECT2D && JUCE_WINDOWS
#include "native/juce_Direct2DGraphicsContext_windows.h"
#if JUCE_WINDOWS
#include "native/juce_Direct2DMetrics_windows.h"
#include "native/juce_Direct2DGraphicsContext_windows.h"
#include "native/juce_Direct2DHwndContext_windows.h"
#endif

View file

@ -88,7 +88,7 @@ public:
void setOrigin (Point<int>) override;
void addTransform (const AffineTransform&) override;
float getPhysicalPixelScaleFactor() override;
float getPhysicalPixelScaleFactor() const override;
bool clipToRectangle (const Rectangle<int>&) override;
bool clipToRectangleList (const RectangleList<int>&) override;
void excludeClipRectangle (const Rectangle<int>&) override;
@ -125,6 +125,8 @@ public:
Span<const Point<float>>,
const AffineTransform&) override;
uint64_t getFrameId() const override { return 0; }
private:
//==============================================================================
detail::ContextPtr context;

View file

@ -272,7 +272,7 @@ void CoreGraphicsContext::addTransform (const AffineTransform& transform)
jassert (getPhysicalPixelScaleFactor() > 0.0f);
}
float CoreGraphicsContext::getPhysicalPixelScaleFactor()
float CoreGraphicsContext::getPhysicalPixelScaleFactor() const
{
auto t = CGContextGetUserSpaceToDeviceSpaceTransform (context.get());
auto determinant = (t.a * t.d) - (t.c * t.b);

View file

@ -35,23 +35,18 @@
namespace juce
{
#ifndef _WINDEF_
class HWND__; // Forward or never
typedef HWND__* HWND;
#endif
class Direct2DLowLevelGraphicsContext : public LowLevelGraphicsContext
class Direct2DGraphicsContext : public LowLevelGraphicsContext
{
public:
Direct2DLowLevelGraphicsContext (HWND);
~Direct2DLowLevelGraphicsContext();
Direct2DGraphicsContext();
~Direct2DGraphicsContext() override;
//==============================================================================
bool isVectorDevice() const override { return false; }
void setOrigin (Point<int>) override;
void addTransform (const AffineTransform&) override;
float getPhysicalPixelScaleFactor() override;
float getPhysicalPixelScaleFactor() const override;
bool clipToRectangle (const Rectangle<int>&) override;
bool clipToRectangleList (const RectangleList<int>&) override;
void excludeClipRectangle (const Rectangle<int>&) override;
@ -83,29 +78,101 @@ public:
void drawLine (const Line<float>&) override;
void setFont (const Font&) override;
const Font& getFont() override;
void drawGlyph (int glyphNumber, const AffineTransform&) override;
void resized();
void clear();
void start();
void end();
void drawGlyphs (Span<const uint16_t>,
Span<const Point<float>>,
const AffineTransform&) override;
//==============================================================================
private:
// These methods were not originally part of the LowLevelGraphicsContext; they
// were added because Direct2D supports these drawing primitives directly.
// The specialised functions are more efficient than emulating the same behaviour, e.g.
// by drawing paths.
void drawLineWithThickness (const Line<float>&, float) override;
void drawEllipse (const Rectangle<float>& area, float lineThickness) override;
void fillEllipse (const Rectangle<float>& area) override;
void drawRect (const Rectangle<float>&, float) override;
void strokePath (const Path&, const PathStrokeType& strokeType, const AffineTransform&) override;
void drawRoundedRectangle (const Rectangle<float>& area, float cornerSize, float lineThickness) override;
void fillRoundedRectangle (const Rectangle<float>& area, float cornerSize) override;
//==============================================================================
bool startFrame();
void endFrame();
virtual Image createSnapshot() const { return {}; }
uint64_t getFrameId() const override { return frame; }
Direct2DMetrics::Ptr metrics;
//==============================================================================
// Min & max frame sizes; same as Direct3D texture size limits
static int constexpr minFrameSize = 1;
static int constexpr maxFrameSize = 16384;
//==============================================================================
void setPhysicalPixelScaleFactor (float);
protected:
struct SavedState;
SavedState* currentState = nullptr;
HWND hwnd;
class PendingClipList
{
public:
void clipTo (Rectangle<float> i)
{
list.clipTo (i);
}
SavedState* currentState;
OwnedArray<SavedState> states;
template <typename Numeric>
void clipTo (const RectangleList<Numeric>& other)
{
list.clipTo (other);
}
Rectangle<int> bounds;
void subtract (Rectangle<float> i)
{
list.subtract (i);
}
RectangleList<float> getList() const { return list; }
void reset (Rectangle<float> maxBounds)
{
list = maxBounds;
}
private:
RectangleList<float> list;
};
PendingClipList pendingClipList;
struct Pimpl;
std::unique_ptr<Pimpl> pimpl;
virtual Pimpl* getPimpl() const noexcept = 0;
JUCE_DECLARE_NON_COPYABLE_WITH_LEAK_DETECTOR (Direct2DLowLevelGraphicsContext)
void resetPendingClipList();
void applyPendingClipList();
virtual void clearTargetBuffer() = 0;
struct ScopedTransform
{
ScopedTransform (Pimpl&, SavedState*);
ScopedTransform (Pimpl&, SavedState*, const AffineTransform& transform);
~ScopedTransform();
Pimpl& pimpl;
SavedState* state = nullptr;
};
uint64_t frame = 0;
float scale = 1.0f;
JUCE_DECLARE_NON_COPYABLE_WITH_LEAK_DETECTOR (Direct2DGraphicsContext)
};
} // namespace juce

View file

@ -0,0 +1,443 @@
/*
==============================================================================
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
{
class ScopedMultithread
{
public:
explicit ScopedMultithread (ID2D1Multithread* multithreadIn)
: multithread (addComSmartPtrOwner (multithreadIn))
{
multithreadIn->Enter();
}
~ScopedMultithread()
{
multithread->Leave();
}
private:
JUCE_DECLARE_NON_COPYABLE_WITH_LEAK_DETECTOR (ScopedMultithread)
ComSmartPtr<ID2D1Multithread> multithread;
};
/* ScopedGeometryWithSink creates an ID2D1PathGeometry object with an open sink. */
struct ScopedGeometryWithSink
{
ScopedGeometryWithSink (ID2D1Factory* factory, D2D1_FILL_MODE fillMode)
{
if (const auto hr = factory->CreatePathGeometry (geometry.resetAndGetPointerAddress()); FAILED (hr))
return;
if (const auto hr = geometry->Open (sink.resetAndGetPointerAddress()); FAILED (hr))
return;
sink->SetFillMode (fillMode);
}
~ScopedGeometryWithSink()
{
if (sink == nullptr)
return;
const auto hr = sink->Close();
jassertquiet (SUCCEEDED (hr));
}
ComSmartPtr<ID2D1PathGeometry> geometry;
ComSmartPtr<ID2D1GeometrySink> sink;
JUCE_DECLARE_NON_COPYABLE_WITH_LEAK_DETECTOR (ScopedGeometryWithSink)
};
class WindowsScopedEvent
{
public:
explicit WindowsScopedEvent (HANDLE handleIn)
: handle (handleIn)
{
}
WindowsScopedEvent()
: WindowsScopedEvent (CreateEvent (nullptr, FALSE, FALSE, nullptr))
{
}
HANDLE getHandle() const noexcept
{
return handle.get();
}
private:
std::unique_ptr<std::remove_pointer_t<HANDLE>, FunctionPointerDestructor<CloseHandle>> handle;
};
//==============================================================================
struct D2DHelpers
{
static bool isTransformAxisAligned (const AffineTransform& transform)
{
return transform.mat01 == 0.0f && transform.mat10 == 0.0f;
}
static void pathToGeometrySink (const Path& path, ID2D1GeometrySink* sink, const AffineTransform& transform, D2D1_FIGURE_BEGIN figureMode)
{
// Every call to BeginFigure must have a matching call to EndFigure. But - the Path does not necessarily
// have matching startNewSubPath and closePath markers. The figureStarted flag indicates if an extra call
// to BeginFigure or EndFigure is needed during the iteration loop or when exiting this function.
Path::Iterator it (path);
bool figureStarted = false;
while (it.next())
{
switch (it.elementType)
{
case Path::Iterator::cubicTo:
{
jassert (figureStarted);
transform.transformPoint (it.x1, it.y1);
transform.transformPoint (it.x2, it.y2);
transform.transformPoint (it.x3, it.y3);
sink->AddBezier ({ { it.x1, it.y1 }, { it.x2, it.y2 }, { it.x3, it.y3 } });
break;
}
case Path::Iterator::lineTo:
{
jassert (figureStarted);
transform.transformPoint (it.x1, it.y1);
sink->AddLine ({ it.x1, it.y1 });
break;
}
case Path::Iterator::quadraticTo:
{
jassert (figureStarted);
transform.transformPoint (it.x1, it.y1);
transform.transformPoint (it.x2, it.y2);
sink->AddQuadraticBezier ({ { it.x1, it.y1 }, { it.x2, it.y2 } });
break;
}
case Path::Iterator::closePath:
{
if (figureStarted)
{
sink->EndFigure (D2D1_FIGURE_END_CLOSED);
figureStarted = false;
}
break;
}
case Path::Iterator::startNewSubPath:
{
if (figureStarted)
{
sink->EndFigure (D2D1_FIGURE_END_OPEN);
}
transform.transformPoint (it.x1, it.y1);
sink->BeginFigure ({ it.x1, it.y1 }, figureMode);
figureStarted = true;
break;
}
}
}
if (figureStarted)
{
sink->EndFigure (D2D1_FIGURE_END_OPEN);
}
}
static D2D1_POINT_2F pointTransformed (Point<float> pt, const AffineTransform& transform)
{
transform.transformPoint (pt.x, pt.y);
return { (FLOAT) pt.x, (FLOAT) pt.y };
}
static void rectToGeometrySink (const Rectangle<float>& rect,
ID2D1GeometrySink* sink,
const AffineTransform& transform,
D2D1_FIGURE_BEGIN figureMode)
{
const auto a = pointTransformed (rect.getTopLeft(), transform);
const auto b = pointTransformed (rect.getTopRight(), transform);
const auto c = pointTransformed (rect.getBottomRight(), transform);
const auto d = pointTransformed (rect.getBottomLeft(), transform);
sink->BeginFigure (a, figureMode);
sink->AddLine (b);
sink->AddLine (c);
sink->AddLine (d);
sink->EndFigure (D2D1_FIGURE_END_CLOSED);
}
static ComSmartPtr<ID2D1Geometry> rectListToPathGeometry (ID2D1Factory* factory,
const RectangleList<float>& clipRegion,
const AffineTransform& transform,
D2D1_FILL_MODE fillMode,
D2D1_FIGURE_BEGIN figureMode,
[[maybe_unused]] Direct2DMetrics* metrics)
{
JUCE_D2DMETRICS_SCOPED_ELAPSED_TIME (metrics, createGeometryTime)
ScopedGeometryWithSink objects { factory, fillMode };
if (objects.sink == nullptr)
return {};
for (int i = clipRegion.getNumRectangles(); --i >= 0;)
rectToGeometrySink (clipRegion.getRectangle (i), objects.sink, transform, figureMode);
return objects.geometry;
}
static ComSmartPtr<ID2D1Geometry> pathToPathGeometry (ID2D1Factory* factory,
const Path& path,
const AffineTransform& transform,
D2D1_FIGURE_BEGIN figureMode,
[[maybe_unused]] Direct2DMetrics* metrics)
{
JUCE_D2DMETRICS_SCOPED_ELAPSED_TIME (metrics, createGeometryTime)
ScopedGeometryWithSink objects { factory, path.isUsingNonZeroWinding() ? D2D1_FILL_MODE_WINDING : D2D1_FILL_MODE_ALTERNATE };
if (objects.sink == nullptr)
return {};
pathToGeometrySink (path, objects.sink, transform, figureMode);
return objects.geometry;
}
static ComSmartPtr<ID2D1StrokeStyle1> pathStrokeTypeToStrokeStyle (ID2D1Factory1* factory, const PathStrokeType& strokeType)
{
// JUCE JointStyle ID2D1StrokeStyle
// --------------- ----------------
// mitered D2D1_LINE_JOIN_MITER
// curved D2D1_LINE_JOIN_ROUND
// beveled D2D1_LINE_JOIN_BEVEL
//
// JUCE EndCapStyle ID2D1StrokeStyle
// ---------------- ----------------
// butt D2D1_CAP_STYLE_FLAT
// square D2D1_CAP_STYLE_SQUARE
// rounded D2D1_CAP_STYLE_ROUND
auto lineJoin = D2D1_LINE_JOIN_MITER;
switch (strokeType.getJointStyle())
{
case PathStrokeType::JointStyle::mitered:
// already set
break;
case PathStrokeType::JointStyle::curved:
lineJoin = D2D1_LINE_JOIN_ROUND;
break;
case PathStrokeType::JointStyle::beveled:
lineJoin = D2D1_LINE_JOIN_BEVEL;
break;
default:
// invalid EndCapStyle
jassertfalse;
break;
}
auto capStyle = D2D1_CAP_STYLE_FLAT;
switch (strokeType.getEndStyle())
{
case PathStrokeType::EndCapStyle::butt:
// already set
break;
case PathStrokeType::EndCapStyle::square:
capStyle = D2D1_CAP_STYLE_SQUARE;
break;
case PathStrokeType::EndCapStyle::rounded:
capStyle = D2D1_CAP_STYLE_ROUND;
break;
default:
// invalid EndCapStyle
jassertfalse;
break;
}
D2D1_STROKE_STYLE_PROPERTIES1 strokeStyleProperties
{
capStyle,
capStyle,
capStyle,
lineJoin,
strokeType.getStrokeThickness(),
D2D1_DASH_STYLE_SOLID,
0.0f,
D2D1_STROKE_TRANSFORM_TYPE_NORMAL
};
ComSmartPtr<ID2D1StrokeStyle1> strokeStyle;
factory->CreateStrokeStyle (strokeStyleProperties,
nullptr,
0,
strokeStyle.resetAndGetPointerAddress());
return strokeStyle;
}
};
//==============================================================================
/* UpdateRegion extracts the invalid region for a window
UpdateRegion is used to service WM_PAINT to add the invalid region of a window to
deferredRepaints. UpdateRegion marks the region as valid, and the region should be painted on the
next vblank.
This is similar to the invalid region update in HWNDComponentPeer::handlePaintMessage()
*/
class UpdateRegion
{
public:
~UpdateRegion()
{
clear();
}
void findRECTAndValidate (HWND windowHandle)
{
numRect = 0;
auto regionHandle = CreateRectRgn (0, 0, 0, 0);
if (regionHandle)
{
auto regionType = GetUpdateRgn (windowHandle, regionHandle, false);
if (regionType == SIMPLEREGION || regionType == COMPLEXREGION)
{
auto regionDataBytes = GetRegionData (regionHandle, (DWORD) block.getSize(), (RGNDATA*) block.getData());
if (regionDataBytes > block.getSize())
{
block.ensureSize (regionDataBytes);
regionDataBytes = GetRegionData (regionHandle, (DWORD) block.getSize(), (RGNDATA*) block.getData());
}
if (regionDataBytes > 0)
{
auto header = (RGNDATAHEADER const* const) block.getData();
if (header->iType == RDH_RECTANGLES)
numRect = header->nCount;
}
}
if (numRect > 0)
ValidateRgn (windowHandle, regionHandle);
else
ValidateRect (windowHandle, nullptr);
DeleteObject (regionHandle);
regionHandle = nullptr;
return;
}
ValidateRect (windowHandle, nullptr);
}
void clear()
{
numRect = 0;
}
uint32 getNumRECT() const
{
return numRect;
}
RECT* getRECTArray()
{
auto header = (RGNDATAHEADER const* const) block.getData();
return (RECT*) (header + 1);
}
static void forwardInvalidRegionToParent (HWND childHwnd)
{
auto regionHandle = CreateRectRgn (0, 0, 0, 0);
if (regionHandle)
{
GetUpdateRgn (childHwnd, regionHandle, false);
ValidateRgn (childHwnd, regionHandle);
InvalidateRgn (GetParent (childHwnd), regionHandle, FALSE);
DeleteObject (regionHandle);
}
}
private:
MemoryBlock block { 1024 };
uint32 numRect = 0;
};
//==============================================================================
/** Heap storage for a DirectWrite glyph run */
class DirectWriteGlyphRun
{
public:
void replace (Span<const Point<float>> positions, float scale)
{
advances.resize (positions.size(), 0.0f);
offsets.resize (positions.size());
std::transform (positions.begin(), positions.end(), offsets.begin(), [&] (auto& g)
{
return DWRITE_GLYPH_OFFSET { g.x / scale, -g.y };
});
}
auto* getAdvances() const { return advances.data(); }
auto* getOffsets() const { return offsets .data(); }
private:
std::vector<float> advances;
std::vector<DWRITE_GLYPH_OFFSET> offsets;
};
} // namespace juce

View file

@ -0,0 +1,720 @@
/*
==============================================================================
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
{
//==============================================================================
class Presentation
{
public:
SLIST_ENTRY& getListEntry() { return listEntry; }
auto getPresentationBitmap() const
{
jassert (presentationBitmap != nullptr);
return presentationBitmap;
}
auto getPresentationBitmap (const Rectangle<int>& swapSize, ComSmartPtr<ID2D1DeviceContext1> context)
{
if (presentationBitmap != nullptr)
{
const auto size = presentationBitmap->GetPixelSize();
if (size.width != (uint32) swapSize.getWidth() || size.height != (uint32) swapSize.getHeight())
presentationBitmap = nullptr;
}
if (presentationBitmap == nullptr)
{
presentationBitmap = Direct2DBitmap::createBitmap (context,
Image::ARGB,
{ (uint32) swapSize.getWidth(), (uint32) swapSize.getHeight() },
swapSize.getWidth() * 4,
D2D1_BITMAP_OPTIONS_TARGET);
}
return presentationBitmap;
}
void setPaintAreas (RectangleList<int> areas)
{
paintAreas = std::move (areas);
}
auto getPaintAreas() const
{
return paintAreas;
}
void setResult (HRESULT x)
{
hr = x;
}
auto getResult() const
{
return hr;
}
private:
JUCE_ALIGN (MEMORY_ALLOCATION_ALIGNMENT)
SLIST_ENTRY listEntry;
ComSmartPtr<ID2D1Bitmap> presentationBitmap;
RectangleList<int> paintAreas;
HRESULT hr = S_OK;
};
struct Direct2DHwndContext::HwndPimpl : public Direct2DGraphicsContext::Pimpl
{
private:
struct SwapChainThread
{
SwapChainThread (Direct2DHwndContext::HwndPimpl& ownerIn,
ComSmartPtr<ID2D1Multithread> multithreadIn)
: owner (ownerIn),
multithread (multithreadIn),
swapChainEventHandle (ownerIn.swap.swapChainEvent->getHandle())
{
InitializeSListHead (&paintedPresentations);
InitializeSListHead (&retiredPresentations);
for (auto& p : presentations)
InterlockedPushEntrySList (&retiredPresentations, &p.getListEntry());
}
~SwapChainThread()
{
SetEvent (quitEvent.getHandle());
thread.join();
InterlockedFlushSList (&paintedPresentations);
InterlockedFlushSList (&retiredPresentations);
}
Presentation* getFreshPresentation()
{
if (auto listEntry = InterlockedPopEntrySList (&retiredPresentations))
return reinterpret_cast<Presentation*> (listEntry);
return nullptr;
}
void pushPaintedPresentation (Presentation* presentationIn)
{
InterlockedPushEntrySList (&paintedPresentations, &presentationIn->getListEntry());
SetEvent (wakeEvent.getHandle());
}
void retirePresentation (Presentation* presentationIn)
{
InterlockedPushEntrySList (&retiredPresentations, &presentationIn->getListEntry());
}
void notify()
{
SetEvent (wakeEvent.getHandle());
}
private:
void serviceSwapChain()
{
if (swapChainReady)
{
if (auto listEntry = InterlockedPopEntrySList (&paintedPresentations))
{
JUCE_D2DMETRICS_SCOPED_ELAPSED_TIME (owner.owner.metrics, swapChainThreadTime);
auto filledPresentation = reinterpret_cast<Presentation*> (listEntry);
{
ScopedMultithread scopedMultithread { multithread };
owner.present (filledPresentation, 0);
}
swapChainReady = false;
InterlockedPushEntrySList (&retiredPresentations, listEntry);
}
}
}
JUCE_ALIGN (MEMORY_ALLOCATION_ALIGNMENT)
SLIST_HEADER paintedPresentations;
JUCE_ALIGN (MEMORY_ALLOCATION_ALIGNMENT)
SLIST_HEADER retiredPresentations;
Direct2DHwndContext::HwndPimpl& owner;
ComSmartPtr<ID2D1Multithread> multithread;
HANDLE swapChainEventHandle = nullptr;
bool swapChainReady = false;
std::vector<Presentation> presentations = std::vector<Presentation> (2);
WindowsScopedEvent wakeEvent;
WindowsScopedEvent quitEvent;
std::thread thread { [&] { threadLoop(); } };
void threadLoop()
{
Thread::setCurrentThreadName ("swapChainThread");
for (;;)
{
const HANDLE handles[] { swapChainEventHandle, quitEvent.getHandle(), wakeEvent.getHandle() };
const auto waitResult = WaitForMultipleObjects ((DWORD) std::size (handles), handles, FALSE, INFINITE);
switch (waitResult)
{
case WAIT_OBJECT_0:
{
swapChainReady = true;
serviceSwapChain();
break;
}
case WAIT_OBJECT_0 + 1:
return;
case WAIT_OBJECT_0 + 2:
{
serviceSwapChain();
break;
}
case WAIT_FAILED:
default:
jassertfalse;
break;
}
}
}
};
SwapChain swap;
std::unique_ptr<SwapChainThread> swapChainThread;
Presentation* presentation = nullptr;
CompositionTree compositionTree;
UpdateRegion updateRegion;
RectangleList<int> deferredRepaints;
Rectangle<int> frameSize;
std::vector<RECT> dirtyRectangles;
bool resizing = false;
int64 lastFinishFrameTicks = 0;
HWND hwnd = nullptr;
HRESULT prepare() override
{
if (! adapter || ! adapter->direct2DDevice)
{
adapter = directX->adapters.getAdapterForHwnd (hwnd);
if (! adapter)
return E_FAIL;
}
if (! deviceResources.canPaint (adapter))
{
if (auto hr = deviceResources.create (adapter); FAILED (hr))
return hr;
}
if (! hwnd || frameSize.isEmpty())
return E_FAIL;
if (! swap.canPaint())
{
if (auto hr = swap.create (hwnd, frameSize, adapter); FAILED (hr))
return hr;
if (auto hr = swap.createBuffer (deviceResources.deviceContext.context); FAILED (hr))
return hr;
}
if (! swapChainThread)
{
if (swap.swapChainEvent.has_value())
swapChainThread = std::make_unique<SwapChainThread> (*this, directX->getD2DMultithread());
}
if (! compositionTree.canPaint())
{
if (auto hr = compositionTree.create (adapter->dxgiDevice, hwnd, swap.chain); FAILED (hr))
return hr;
}
return S_OK;
}
void teardown() override
{
compositionTree.release();
swapChainThread = nullptr;
swap.release();
Pimpl::teardown();
}
void updatePaintAreas() override
{
// Does the entire buffer need to be filled?
if (swap.state == SwapChain::State::bufferAllocated || resizing)
deferredRepaints = swap.getSize();
// If the window alpha is less than 1.0, clip to the union of the
// deferred repaints so the device context Clear() works correctly
if (targetAlpha < 1.0f || ! opaque)
paintAreas = deferredRepaints.getBounds();
else
paintAreas = deferredRepaints;
}
bool checkPaintReady() override
{
// Try not to saturate the message thread; this is a little crude. Perhaps some kind of credit system...
if (auto now = Time::getHighResolutionTicks(); Time::highResolutionTicksToSeconds (now - lastFinishFrameTicks) < 0.001)
return false;
if (! presentation)
{
presentation = swapChainThread->getFreshPresentation();
if (presentation && FAILED (presentation->getResult()))
teardown();
}
// Paint if:
// resources are allocated
// deferredRepaints has areas to be painted
// the swap chain thread is ready
bool ready = Pimpl::checkPaintReady();
ready &= swap.canPaint();
ready &= compositionTree.canPaint();
ready &= deferredRepaints.getNumRectangles() > 0 || resizing;
ready &= presentation != nullptr;
return ready;
}
JUCE_DECLARE_WEAK_REFERENCEABLE (HwndPimpl)
public:
HwndPimpl (Direct2DHwndContext& ownerIn, HWND hwndIn, bool opaqueIn)
: Pimpl (ownerIn, opaqueIn),
hwnd (hwndIn)
{
adapter = directX->adapters.getAdapterForHwnd (hwndIn);
}
~HwndPimpl() override = default;
HWND getHwnd() const { return hwnd; }
void handleShowWindow()
{
// One of the trickier problems was determining when Direct2D & DXGI resources can be safely created;
// that's not really spelled out in the documentation.
// This method is called when the component peer receives WM_SHOWWINDOW
prepare();
frameSize = getClientRect();
deferredRepaints = frameSize;
}
Rectangle<int> getClientRect() const
{
RECT clientRect;
GetClientRect (hwnd, &clientRect);
return Rectangle<int>::leftTopRightBottom (clientRect.left, clientRect.top, clientRect.right, clientRect.bottom);
}
Rectangle<int> getFrameSize() override
{
return getClientRect();
}
ComSmartPtr<ID2D1Image> getDeviceContextTarget() const override
{
if (presentation != nullptr)
return presentation->getPresentationBitmap (swap.getSize(), deviceResources.deviceContext.context);
return {};
}
void startResizing()
{
resizing = true;
}
void finishResizing()
{
resizing = false;
}
void setSize (Rectangle<int> size)
{
if (size == frameSize)
return;
resizeSwapChain (size);
}
void resizeSwapChain (Rectangle<int> size)
{
if (size.isEmpty())
return;
// Require the entire window to be repainted
frameSize = size;
deferredRepaints = size;
InvalidateRect (hwnd, nullptr, TRUE);
// Resize/scale the swap chain
prepare();
if (auto deviceContext = deviceResources.deviceContext.context)
{
ScopedMultithread scopedMultithread { directX->getD2DMultithread() };
auto hr = swap.resize (size, (float) owner.getPhysicalPixelScaleFactor(), deviceContext);
jassert (SUCCEEDED (hr));
if (FAILED (hr))
teardown();
if (swapChainThread)
swapChainThread->notify();
}
clearWindowRedirectionBitmap();
}
void addDeferredRepaint (Rectangle<int> deferredRepaint)
{
deferredRepaints.add (deferredRepaint);
JUCE_TRACE_EVENT_INT_RECT (etw::repaint, etw::paintKeyword, snappedRectangle);
}
void addInvalidWindowRegionToDeferredRepaints()
{
updateRegion.findRECTAndValidate (hwnd);
// Call addDeferredRepaint for each RECT in the update region to make
// sure they are snapped properly for DPI scaling
auto rectArray = updateRegion.getRECTArray();
for (uint32 i = 0; i < updateRegion.getNumRECT(); ++i)
addDeferredRepaint (D2DUtilities::toRectangle (rectArray[i]));
updateRegion.clear();
}
void clearWindowRedirectionBitmap()
{
if (! opaque && swap.state == SwapChain::State::bufferAllocated)
{
deviceResources.deviceContext.createHwndRenderTarget (hwnd);
// Clear the GDI redirection bitmap using a Direct2D 1.0 render target
auto& hwndRenderTarget = deviceResources.deviceContext.hwndRenderTarget;
if (hwndRenderTarget)
{
const auto colorF = D2DUtilities::toCOLOR_F (getBackgroundTransparencyKeyColour());
RECT clientRect;
GetClientRect (hwnd, &clientRect);
D2D1_SIZE_U size { (uint32) (clientRect.right - clientRect.left), (uint32) (clientRect.bottom - clientRect.top) };
hwndRenderTarget->Resize (size);
hwndRenderTarget->BeginDraw();
hwndRenderTarget->Clear (colorF);
hwndRenderTarget->EndDraw();
}
}
}
SavedState* startFrame() override
{
if (resizing)
{
deferredRepaints = frameSize;
setSize (getClientRect());
}
auto savedState = Pimpl::startFrame();
// If a new frame is starting, clear deferredAreas in case repaint is called
// while the frame is being painted to ensure the new areas are painted on the
// next frame
if (savedState)
{
JUCE_TRACE_LOG_D2D_PAINT_CALL (etw::direct2dHwndPaintStart, owner.getFrameId());
presentation->setPaintAreas (paintAreas);
deferredRepaints.clear();
}
return savedState;
}
HRESULT finishFrame() override
{
const ScopeGuard scope { [this]
{
presentation = nullptr;
lastFinishFrameTicks = Time::getHighResolutionTicks();
} };
if (auto hr = Pimpl::finishFrame(); FAILED (hr))
return hr;
if (resizing)
{
present (presentation, 0);
swapChainThread->retirePresentation (presentation);
}
else
{
swapChainThread->pushPaintedPresentation (presentation);
}
return S_OK;
}
void present (Presentation* paintedPresentation, uint32 flags)
{
if (paintedPresentation == nullptr)
return;
// Fill out the array of dirty rectangles
// Compare paintAreas to the swap chain buffer area. If the rectangles in paintAreas are contained
// by the swap chain buffer area, then mark those rectangles as dirty. DXGI will only keep the dirty rectangles from the
// current buffer and copy the clean area from the previous buffer.
// The buffer needs to be completely filled before using dirty rectangles. The dirty rectangles need to be contained
// within the swap chain buffer.
JUCE_D2DMETRICS_SCOPED_ELAPSED_TIME (owner.metrics, present1Duration);
// Allocate enough memory for the array of dirty rectangles
const auto areas = paintedPresentation->getPaintAreas();
paintedPresentation->setPaintAreas ({});
dirtyRectangles.resize ((size_t) areas.getNumRectangles());
// Fill the array of dirty rectangles, intersecting each paint area with the swap chain buffer
DXGI_PRESENT_PARAMETERS presentParameters{};
if (swap.state == SwapChain::State::bufferFilled)
{
auto* dirtyRectangle = dirtyRectangles.data();
auto const swapChainSize = swap.getSize();
for (const auto& area : areas)
{
// If this paint area contains the entire swap chain, then
// no need for dirty rectangles
if (area.contains (swapChainSize))
{
presentParameters.DirtyRectsCount = 0;
break;
}
// Intersect this paint area with the swap chain buffer
auto intersection = area.getIntersection (swapChainSize);
if (intersection.isEmpty())
{
// Can't clip to an empty rectangle
continue;
}
D2D1_POINT_2U destPoint { (uint32) intersection.getX(), (uint32) intersection.getY() };
D2D1_RECT_U sourceRect { (uint32) intersection.getX(),
(uint32) intersection.getY(),
(uint32) intersection.getRight(),
(uint32) intersection.getBottom() };
swap.buffer->CopyFromBitmap (&destPoint, paintedPresentation->getPresentationBitmap(), &sourceRect);
// Add this intersected paint area to the dirty rectangle array (scaled for DPI)
*dirtyRectangle = D2DUtilities::toRECT (intersection);
dirtyRectangle++;
presentParameters.DirtyRectsCount++;
}
presentParameters.pDirtyRects = dirtyRectangles.data();
}
if (presentParameters.DirtyRectsCount == 0)
{
D2D1_POINT_2U destPoint { 0, 0 };
swap.buffer->CopyFromBitmap (&destPoint, paintedPresentation->getPresentationBitmap(), nullptr);
}
// Present the freshly painted buffer
const auto hr = swap.chain->Present1 (swap.presentSyncInterval, swap.presentFlags | flags, &presentParameters);
jassert (SUCCEEDED (hr));
paintedPresentation->setResult (hr);
// The buffer is now completely filled and ready for dirty rectangles for the next frame
swap.state = SwapChain::State::bufferFilled;
JUCE_TRACE_LOG_D2D_PAINT_CALL (etw::direct2dHwndPaintEnd, owner.getFrameId());
}
Image createSnapshot() const
{
if (frameSize.isEmpty() || deviceResources.deviceContext.context == nullptr || swap.buffer == nullptr)
return {};
// Create the bitmap to receive the snapshot
D2D1_BITMAP_PROPERTIES1 bitmapProperties{};
bitmapProperties.bitmapOptions = D2D1_BITMAP_OPTIONS_TARGET;
bitmapProperties.dpiX = bitmapProperties.dpiY = USER_DEFAULT_SCREEN_DPI * owner.getPhysicalPixelScaleFactor();
bitmapProperties.pixelFormat = swap.buffer->GetPixelFormat();
const D2D_SIZE_U size { (UINT32) frameSize.getWidth(), (UINT32) frameSize.getHeight() };
ComSmartPtr<ID2D1Bitmap1> snapshot;
if (const auto hr = deviceResources.deviceContext.context->CreateBitmap (size, nullptr, 0, bitmapProperties, snapshot.resetAndGetPointerAddress()); FAILED (hr))
return {};
swap.chain->Present (0, DXGI_PRESENT_DO_NOT_WAIT);
// Copy the swap chain buffer to the bitmap snapshot
D2D_POINT_2U p { 0, 0 };
const auto sourceRect = D2DUtilities::toRECT_U (frameSize);
if (const auto hr = snapshot->CopyFromBitmap (&p, swap.buffer, &sourceRect); FAILED (hr))
return {};
auto pixelData = Direct2DPixelData::fromDirect2DBitmap (snapshot);
Image result { pixelData };
swap.chain->Present (0, DXGI_PRESENT_DO_NOT_WAIT);
return result;
}
};
//==============================================================================
Direct2DHwndContext::Direct2DHwndContext (void* windowHandle, bool opaque)
{
#if JUCE_DIRECT2D_METRICS
metrics = new Direct2DMetrics { Direct2DMetricsHub::getInstance()->lock,
"HWND " + String::toHexString ((pointer_sized_int) windowHandle),
windowHandle };
Direct2DMetricsHub::getInstance()->add (metrics);
#endif
pimpl = std::make_unique<HwndPimpl> (*this, reinterpret_cast<HWND> (windowHandle), opaque);
updateSize();
}
Direct2DHwndContext::~Direct2DHwndContext()
{
#if JUCE_DIRECT2D_METRICS
Direct2DMetricsHub::getInstance()->remove (metrics);
#endif
}
void* Direct2DHwndContext::getHwnd() const noexcept
{
return pimpl->getHwnd();
}
Direct2DGraphicsContext::Pimpl* Direct2DHwndContext::getPimpl() const noexcept
{
return pimpl.get();
}
void Direct2DHwndContext::handleShowWindow()
{
pimpl->handleShowWindow();
}
void Direct2DHwndContext::setWindowAlpha (float alpha)
{
pimpl->setTargetAlpha (alpha);
}
void Direct2DHwndContext::startResizing()
{
pimpl->startResizing();
}
void Direct2DHwndContext::finishResizing()
{
pimpl->startResizing();
}
void Direct2DHwndContext::setSize (int width, int height)
{
pimpl->setSize ({ width, height });
}
void Direct2DHwndContext::updateSize()
{
pimpl->setSize (pimpl->getClientRect());
}
void Direct2DHwndContext::addDeferredRepaint (Rectangle<int> deferredRepaint)
{
pimpl->addDeferredRepaint (deferredRepaint);
}
void Direct2DHwndContext::addInvalidWindowRegionToDeferredRepaints()
{
pimpl->addInvalidWindowRegionToDeferredRepaints();
}
Image Direct2DHwndContext::createSnapshot() const
{
return pimpl->createSnapshot();
}
void Direct2DHwndContext::clearTargetBuffer()
{
// For opaque windows, clear the background to black with the window alpha
// For non-opaque windows, clear the background to transparent black
// In either case, add a transparency layer if the window alpha is less than 1.0
pimpl->getDeviceContext()->Clear (pimpl->backgroundColor);
if (pimpl->targetAlpha < 1.0f)
beginTransparencyLayer (pimpl->targetAlpha);
}
} // namespace juce

View file

@ -0,0 +1,73 @@
/*
==============================================================================
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
{
class Direct2DHwndContext : public Direct2DGraphicsContext
{
public:
Direct2DHwndContext (void* windowHandle, bool opaque);
~Direct2DHwndContext() override;
void* getHwnd() const noexcept;
void handleShowWindow();
void setWindowAlpha (float alpha);
void startResizing();
void finishResizing();
void setSize (int width, int height);
void updateSize();
void addDeferredRepaint (Rectangle<int> deferredRepaint);
void addInvalidWindowRegionToDeferredRepaints();
Image createSnapshot() const override;
static Colour getBackgroundTransparencyKeyColour() noexcept
{
return Colour { 0xff000001 };
}
private:
struct HwndPimpl;
std::unique_ptr<HwndPimpl> pimpl;
Pimpl* getPimpl() const noexcept override;
void clearTargetBuffer() override;
JUCE_DECLARE_NON_COPYABLE_WITH_LEAK_DETECTOR (Direct2DHwndContext)
};
} // namespace juce

View file

@ -0,0 +1,124 @@
/*
==============================================================================
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
{
struct Direct2DImageContext::ImagePimpl : public Direct2DGraphicsContext::Pimpl
{
public:
static constexpr auto opaque = false;
ImagePimpl (Direct2DImageContext& ownerIn, Direct2DPixelData::Ptr targetIn)
: Pimpl (ownerIn, opaque),
target (targetIn)
{
if (target != nullptr)
adapter = target->getAdapter();
else
jassertfalse;
}
Rectangle<int> getFrameSize() override
{
const auto targetBitmap = getBitmap();
if (targetBitmap == nullptr)
return {};
auto size = targetBitmap->GetSize();
return Rectangle<float> { size.width, size.height }.getSmallestIntegerContainer();
}
ComSmartPtr<ID2D1Image> getDeviceContextTarget() const override
{
return getBitmap();
}
HRESULT finishFrame() override
{
const auto result = Pimpl::finishFrame();
if (target != nullptr)
target->flushToSoftwareBackup();
return result;
}
private:
ComSmartPtr<ID2D1Bitmap1> getBitmap() const
{
if (target == nullptr)
return {};
return target->getAdapterD2D1Bitmap();
}
void updatePaintAreas() override
{
paintAreas = getFrameSize();
}
Direct2DPixelData::Ptr target;
JUCE_DECLARE_WEAK_REFERENCEABLE (ImagePimpl)
};
//==============================================================================
Direct2DImageContext::Direct2DImageContext (Direct2DPixelData::Ptr targetIn)
: pimpl (new ImagePimpl { *this, targetIn })
{
#if JUCE_DIRECT2D_METRICS
metrics = Direct2DMetricsHub::getInstance()->imageContextMetrics;
#endif
startFrame();
}
Direct2DImageContext::~Direct2DImageContext()
{
endFrame();
}
Direct2DGraphicsContext::Pimpl* Direct2DImageContext::getPimpl() const noexcept
{
return pimpl.get();
}
void Direct2DImageContext::clearTargetBuffer()
{
// The bitmap was already cleared when it was created; do nothing here
}
} // namespace juce

View file

@ -0,0 +1,55 @@
/*
==============================================================================
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
{
class Direct2DImageContext : public Direct2DGraphicsContext
{
public:
explicit Direct2DImageContext (Direct2DPixelData::Ptr);
~Direct2DImageContext() override;
private:
struct ImagePimpl;
std::unique_ptr<ImagePimpl> pimpl;
Pimpl* getPimpl() const noexcept override;
void clearTargetBuffer() override;
JUCE_DECLARE_NON_COPYABLE_WITH_LEAK_DETECTOR (Direct2DImageContext)
};
} // namespace juce

View file

@ -0,0 +1,654 @@
/*
==============================================================================
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
{
class NativeReadOnlyDataReleaser : public Image::BitmapData::BitmapDataReleaser
{
public:
NativeReadOnlyDataReleaser (Image::PixelFormat pixelFormat,
int lineStride,
int w,
int h,
ComSmartPtr<ID2D1DeviceContext1> deviceContextIn,
ComSmartPtr<ID2D1Bitmap1> sourceBitmap,
Point<int> offset)
: bitmap (Direct2DBitmap::createBitmap (deviceContextIn,
pixelFormat,
{ (UINT32) w, (UINT32) h },
lineStride,
D2D1_BITMAP_OPTIONS_CPU_READ | D2D1_BITMAP_OPTIONS_CANNOT_DRAW))
{
const D2D1_POINT_2U destPoint { 0, 0 };
const Rectangle fullRect { w, h };
const auto sourceRect = D2DUtilities::toRECT_U (fullRect.getIntersection (fullRect.withPosition (offset)));
if (auto hr = bitmap->CopyFromBitmap (&destPoint, sourceBitmap, &sourceRect); FAILED (hr))
return;
D2D1_MAPPED_RECT mappedRect{};
bitmap->Map (D2D1_MAP_OPTIONS_READ, &mappedRect);
data = mappedRect.bits;
pitch = mappedRect.pitch;
}
~NativeReadOnlyDataReleaser() override
{
bitmap->Unmap();
}
auto getData() const
{
return data;
}
auto getPitch() const
{
return pitch;
}
private:
ComSmartPtr<ID2D1Bitmap1> bitmap;
BYTE* data = nullptr;
UINT32 pitch = 0;
};
class SoftwareDataReleaser : public Image::BitmapData::BitmapDataReleaser
{
public:
SoftwareDataReleaser (std::unique_ptr<Image::BitmapData::BitmapDataReleaser> r,
Image backupIn,
ComSmartPtr<ID2D1Bitmap1> nativeBitmapIn,
Image::BitmapData::ReadWriteMode modeIn,
D2D1_RECT_U targetRectIn)
: oldReleaser (std::move (r)),
backup (std::move (backupIn)),
nativeBitmap (nativeBitmapIn),
targetRect (targetRectIn),
mode (modeIn)
{
}
static void flushImage (Image softwareImage, ComSmartPtr<ID2D1Bitmap1> native, D2D1_RECT_U target)
{
if (softwareImage.getFormat() == Image::PixelFormat::RGB)
softwareImage = softwareImage.convertedToFormat (Image::PixelFormat::ARGB);
const Image::BitmapData bitmapData { softwareImage,
(int) target.left,
(int) target.top,
(int) (target.right - target.left),
(int) (target.bottom - target.top),
Image::BitmapData::readOnly };
const auto hr = native->CopyFromMemory (&target, bitmapData.data, (UINT32) bitmapData.lineStride);
jassertquiet (SUCCEEDED (hr));
}
~SoftwareDataReleaser() override
{
// Ensure that writes to the backup bitmap have been flushed before reading from it
oldReleaser = nullptr;
if (mode != Image::BitmapData::ReadWriteMode::readOnly)
flushImage (backup, nativeBitmap, targetRect);
}
private:
std::unique_ptr<Image::BitmapData::BitmapDataReleaser> oldReleaser;
Image backup;
ComSmartPtr<ID2D1Bitmap1> nativeBitmap;
D2D1_RECT_U targetRect{};
Image::BitmapData::ReadWriteMode mode{};
};
ComSmartPtr<ID2D1Bitmap1> Direct2DPixelData::createAdapterBitmap() const
{
auto bitmap = Direct2DBitmap::createBitmap (context,
pixelFormat,
{ (UINT32) width, (UINT32) height },
getLineStride(),
D2D1_BITMAP_OPTIONS_TARGET);
// The bitmap may be slightly too large due
// to DPI scaling, so fill it with transparent black
if (bitmap == nullptr || ! clearImage)
return bitmap;
context->SetTarget (bitmap);
context->BeginDraw();
context->Clear();
context->EndDraw();
context->SetTarget (nullptr);
return bitmap;
}
void Direct2DPixelData::createDeviceResources()
{
if (adapter == nullptr)
adapter = directX->adapters.getDefaultAdapter();
if (context == nullptr)
context = Direct2DDeviceContext::createContext (adapter);
if (nativeBitmap == nullptr)
{
nativeBitmap = createAdapterBitmap();
if (backup.isValid())
SoftwareDataReleaser::flushImage (backup, nativeBitmap, { 0, 0, (UINT32) width, (UINT32) height });
}
}
void Direct2DPixelData::initBitmapDataReadOnly (Image::BitmapData& bitmap, int x, int y)
{
const auto pixelStride = getPixelStride();
const auto lineStride = getLineStride();
const auto offset = (size_t) x * (size_t) pixelStride + (size_t) y * (size_t) lineStride;
bitmap.pixelFormat = pixelFormat;
bitmap.pixelStride = pixelStride;
bitmap.lineStride = lineStride;
bitmap.size = (size_t) (height * lineStride) - offset;
JUCE_TRACE_LOG_D2D_IMAGE_MAP_DATA;
auto releaser = std::make_unique<NativeReadOnlyDataReleaser> (pixelFormat,
lineStride,
width,
height,
context,
getAdapterD2D1Bitmap(),
Point { x, y });
bitmap.data = releaser->getData();
bitmap.lineStride = (int) releaser->getPitch();
bitmap.dataReleaser = std::move (releaser);
}
auto Direct2DPixelData::make (Image::PixelFormat formatToUse,
int widthIn,
int heightIn,
bool clearImageIn,
DxgiAdapter::Ptr adapterIn) -> Ptr
{
return new Direct2DPixelData (formatToUse, widthIn, heightIn, clearImageIn, adapterIn);
}
auto Direct2DPixelData::fromDirect2DBitmap (ComSmartPtr<ID2D1Bitmap1> bitmap) -> Ptr
{
const auto size = bitmap->GetPixelSize();
return new Direct2DPixelData { Image::ARGB, (int) size.width, (int) size.height, false, nullptr };
}
Direct2DPixelData::Direct2DPixelData (Image::PixelFormat f, int widthIn, int heightIn, bool clear, DxgiAdapter::Ptr adapterIn)
: ImagePixelData (f, widthIn, heightIn),
clearImage (clear),
adapter (adapterIn != nullptr ? adapterIn : directX->adapters.getDefaultAdapter())
{
directX->adapters.addListener (*this);
}
Direct2DPixelData::~Direct2DPixelData()
{
directX->adapters.removeListener (*this);
}
std::unique_ptr<LowLevelGraphicsContext> Direct2DPixelData::createLowLevelContext()
{
sendDataChangeMessage();
return std::make_unique<Direct2DImageContext> (this);
}
void Direct2DPixelData::initialiseBitmapData (Image::BitmapData& bitmap, int x, int y, Image::BitmapData::ReadWriteMode mode)
{
JUCE_TRACE_LOG_D2D_IMAGE_MAP_DATA;
// The native format matches the JUCE format, and there's no need to write from CPU->GPU, so
// map the GPU memory as read-only and return that.
if (mode == Image::BitmapData::ReadWriteMode::readOnly && pixelFormat != Image::PixelFormat::RGB)
{
initBitmapDataReadOnly (bitmap, x, y);
return;
}
// The native format does not match the JUCE format, or the user wants to read the current state of the image.
// If the user wants to read the image, then we'll need to copy it to CPU memory.
if (mode != Image::BitmapData::ReadWriteMode::writeOnly)
{
// Store the previous width and height, and set up the BitmapData to cover the entire image area
const auto oldW = std::exchange (bitmap.width, width);
const auto oldH = std::exchange (bitmap.height, height);
// Map the image as read-only.
initBitmapDataReadOnly (bitmap, 0, 0);
// Copy the mapped image to CPU memory in the correct format.
backup = BitmapDataDetail::convert (bitmap, SoftwareImageType{});
// Unmap the image (important, the BitmapData is reused later on).
bitmap.dataReleaser = {};
// Reset the initial width and height
bitmap.width = oldW;
bitmap.height = oldH;
}
// If the user doesn't want to read from the image, then we may need to create a blank image that they can write to.
if (! backup.isValid())
backup = Image { SoftwareImageType{}.create (pixelFormat, width, height, false) };
// Redirect the BitmapData to our backup software image.
backup.getPixelData()->initialiseBitmapData (bitmap, x, y, mode);
// When this dataReleaser is destroyed, then if the mode is not read-only, image data will be copied
// from the software image to GPU memory.
bitmap.dataReleaser = std::make_unique<SoftwareDataReleaser> (std::move (bitmap.dataReleaser),
backup,
getAdapterD2D1Bitmap(),
mode,
D2D1_RECT_U { (UINT32) x, (UINT32) y, (UINT32) width, (UINT32) height });
}
void Direct2DPixelData::flushToSoftwareBackup()
{
backup = SoftwareImageType{}.convert (Image { this });
}
ImagePixelData::Ptr Direct2DPixelData::clone()
{
auto cloned = make (pixelFormat, width, height, false, nullptr);
if (cloned == nullptr)
return {};
cloned->backup = backup.createCopy();
const D2D1_POINT_2U destinationPoint { 0, 0 };
const auto sourceRectU = D2DUtilities::toRECT_U (Rectangle { width, height });
const auto sourceD2D1Bitmap = getAdapterD2D1Bitmap();
const auto destinationD2D1Bitmap = cloned->getAdapterD2D1Bitmap();
if (sourceD2D1Bitmap == nullptr || destinationD2D1Bitmap == nullptr)
return {};
if (const auto hr = destinationD2D1Bitmap->CopyFromBitmap (&destinationPoint, sourceD2D1Bitmap, &sourceRectU); FAILED (hr))
{
jassertfalse;
return {};
}
return cloned;
}
void Direct2DPixelData::applyGaussianBlurEffect (float radius, Image& result)
{
// The result must be a separate image!
jassert (result.getPixelData() != this);
if (context == nullptr)
{
result = {};
return;
}
ComSmartPtr<ID2D1Effect> effect;
if (const auto hr = context->CreateEffect (CLSID_D2D1GaussianBlur, effect.resetAndGetPointerAddress());
FAILED (hr) || effect == nullptr)
{
result = {};
return;
}
effect->SetInput (0, getAdapterD2D1Bitmap());
effect->SetValue (D2D1_GAUSSIANBLUR_PROP_STANDARD_DEVIATION, radius / 3.0f);
const auto tie = [] (const auto& x) { return std::tuple (x.pixelFormat, x.width, x.height); };
const auto originalPixelData = dynamic_cast<Direct2DPixelData*> (result.getPixelData());
if (originalPixelData == nullptr || tie (*this) != tie (*originalPixelData))
result = Image { make (pixelFormat, width, height, false, adapter) };
const auto outputPixelData = dynamic_cast<Direct2DPixelData*> (result.getPixelData());
if (outputPixelData == nullptr)
{
result = {};
return;
}
outputPixelData->createDeviceResources();
auto outputDataContext = outputPixelData->context;
if (outputDataContext == nullptr)
{
result = {};
return;
}
outputDataContext->SetTarget (outputPixelData->getAdapterD2D1Bitmap());
outputDataContext->BeginDraw();
outputDataContext->Clear();
outputDataContext->DrawImage (effect);
outputDataContext->EndDraw();
outputDataContext->SetTarget (nullptr);
}
std::unique_ptr<ImageType> Direct2DPixelData::createType() const
{
return std::make_unique<NativeImageType>();
}
void Direct2DPixelData::adapterCreated (DxgiAdapter::Ptr)
{
}
void Direct2DPixelData::adapterRemoved (DxgiAdapter::Ptr)
{
adapter = nullptr;
context = nullptr;
nativeBitmap = nullptr;
}
ComSmartPtr<ID2D1Bitmap1> Direct2DPixelData::getAdapterD2D1Bitmap()
{
createDeviceResources();
return nativeBitmap;
}
//==============================================================================
ImagePixelData::Ptr NativeImageType::create (Image::PixelFormat format, int width, int height, bool clearImage) const
{
SharedResourcePointer<DirectX> directX;
if (directX->adapters.getFactory() == nullptr)
{
// Make sure the DXGI factory exists
//
// The caller may be trying to create an Image from a static variable; if this is a DLL, then this is
// probably called from DllMain. You can't create a DXGI factory from DllMain, so fall back to a
// software image.
return new SoftwarePixelData { format, width, height, clearImage };
}
return Direct2DPixelData::make (format, width, height, clearImage, nullptr);
}
//==============================================================================
//==============================================================================
#if JUCE_UNIT_TESTS
class Direct2DImageUnitTest final : public UnitTest
{
public:
Direct2DImageUnitTest()
: UnitTest ("Direct2DImageUnitTest", UnitTestCategories::graphics)
{
compareFunctions[{ Image::RGB, Image::RGB }] = [] (uint8* rgb1, uint8* rgb2)
{
return rgb1[0] == rgb2[0] && rgb1[1] == rgb2[1] && rgb1[2] == rgb2[2];
};
compareFunctions[{ Image::RGB, Image::ARGB }] = [] (uint8* rgb, uint8* argb)
{
// Compare bytes directly to avoid alpha premultiply issues
return rgb[0] == argb[0] && // blue
rgb[1] == argb[1] && // green
rgb[2] == argb[2]; // red
};
compareFunctions[{ Image::RGB, Image::SingleChannel }] = [] (uint8*, uint8* singleChannel)
{
return *singleChannel == 0xff;
};
compareFunctions[{ Image::ARGB, Image::RGB }] = [] (uint8* argb, uint8* rgb)
{
// Compare bytes directly to avoid alpha premultiply issues
return argb[0] == rgb[0] && argb[1] == rgb[1] && argb[2] == rgb[2];
};
compareFunctions[{ Image::ARGB, Image::ARGB }] = [] (uint8* argb1, uint8* argb2)
{
return *reinterpret_cast<uint32*> (argb1) == *reinterpret_cast<uint32*> (argb2);
};
compareFunctions[{ Image::ARGB, Image::SingleChannel }] = [] (uint8* argb, uint8* singleChannel)
{
return argb[3] = *singleChannel;
};
compareFunctions[{ Image::SingleChannel, Image::RGB }] = [] (uint8* singleChannel, uint8* rgb)
{
auto alpha = *singleChannel;
return rgb[0] == alpha && rgb[1] == alpha && rgb[2] == alpha;
};
compareFunctions[{ Image::SingleChannel, Image::ARGB }] = [] (uint8* singleChannel, uint8* argb)
{
return *singleChannel = argb[3];
};
compareFunctions[{ Image::SingleChannel, Image::SingleChannel }] = [] (uint8* singleChannel1, uint8* singleChannel2)
{
return *singleChannel1 == *singleChannel2;
};
}
void runTest() override
{
beginTest ("Direct2DImageUnitTest");
random = getRandom();
for (auto format : formats)
compareSameFormat (format);
testFormatConversion();
}
Rectangle<int> randomRectangleWithin (Rectangle<int> container) noexcept
{
auto x = random.nextInt (container.getWidth() - 2);
auto y = random.nextInt (container.getHeight() - 2);
auto w = random.nextInt (container.getHeight() - x);
auto h = random.nextInt (container.getWidth() - y);
h = jmax (h, 1);
w = jmax (w, 1);
return Rectangle<int> { x, y, w, h };
}
void compareSameFormat (Image::PixelFormat format)
{
auto softwareImage = Image { SoftwareImageType{}.create (format, 100, 100, true) };
{
Graphics g { softwareImage };
g.fillCheckerBoard (softwareImage.getBounds().toFloat(), 21.0f, 21.0f, makeRandomColor(), makeRandomColor());
}
auto direct2DImage = NativeImageType{}.convert (softwareImage);
compareImages (softwareImage, direct2DImage, compareFunctions[{ softwareImage.getFormat(), direct2DImage.getFormat() }]);
checkReadWriteModes (softwareImage);
checkReadWriteModes (direct2DImage);
}
void compareImages (Image& image1, Image& image2, std::function<bool (uint8*, uint8*)> compareBytes)
{
{
// BitmapData width & height should match
Rectangle<int> area = randomRectangleWithin (image1.getBounds());
Image::BitmapData data1 { image1, area.getX(), area.getY(), area.getWidth(), area.getHeight(), Image::BitmapData::ReadWriteMode::readOnly };
Image::BitmapData data2 { image2, area.getX(), area.getY(), area.getWidth(), area.getHeight(), Image::BitmapData::ReadWriteMode::readOnly };
expect (data1.width == data2.width);
expect (data1.height == data2.height);
}
{
// Bitmap data should match after ImageType::convert
Image::BitmapData data1 { image1, Image::BitmapData::ReadWriteMode::readOnly };
Image::BitmapData data2 { image2, Image::BitmapData::ReadWriteMode::readOnly };
for (int y = 0; y < data1.height; ++y)
{
auto line1 = data1.getLinePointer (y);
auto line2 = data2.getLinePointer (y);
for (int x = 0; x < data1.width; ++x)
{
expect (compareBytes (line1, line2), "Failed comparing format " + String { image1.getFormat() } + " to " + String { image2.getFormat() });
line1 += data1.pixelStride;
line2 += data2.pixelStride;
}
}
}
{
// Subsection data should match
// Should be able to have two different BitmapData objects simultaneously for the same source image
Rectangle<int> area1 = randomRectangleWithin (image1.getBounds());
Rectangle<int> area2 = randomRectangleWithin (image1.getBounds());
Image::BitmapData data1 { image1, Image::BitmapData::ReadWriteMode::readOnly };
Image::BitmapData data2a { image2, area1.getX(), area1.getY(), area1.getWidth(), area1.getHeight(), Image::BitmapData::ReadWriteMode::readOnly };
Image::BitmapData data2b { image2, area2.getX(), area2.getY(), area2.getWidth(), area2.getHeight(), Image::BitmapData::ReadWriteMode::readOnly };
auto compareSubsection = [&] (Image::BitmapData& subsection1, Image::BitmapData& subsection2, Rectangle<int> area)
{
for (int y = 0; y < area.getHeight(); ++y)
{
auto line1 = subsection1.getLinePointer (y + area.getY());
auto line2 = subsection2.getLinePointer (y);
for (int x = 0; x < area.getWidth(); ++x)
{
expect (compareBytes (line1 + (x + area.getX()) * subsection1.pixelStride, line2 + x * subsection2.pixelStride));
}
}
};
compareSubsection (data1, data2a, area1);
compareSubsection (data1, data2b, area2);
}
}
void checkReadWriteModes (Image& image)
{
// Check read and write modes
int x = random.nextInt (image.getWidth());
auto writeColor = makeRandomColor().withAlpha (1.0f);
auto expectedColor = writeColor;
switch (image.getFormat())
{
case Image::SingleChannel:
{
auto alpha = writeColor.getAlpha();
expectedColor = Colour { alpha, alpha, alpha, alpha };
break;
}
case Image::RGB:
case Image::ARGB:
break;
case Image::UnknownFormat:
default:
jassertfalse;
break;
}
{
Image::BitmapData data { image, Image::BitmapData::ReadWriteMode::writeOnly };
for (int y = 0; y < data.height; ++y)
data.setPixelColour (x, y, writeColor);
}
{
Image::BitmapData data { image, Image::BitmapData::ReadWriteMode::readOnly };
for (int y = 0; y < data.height; ++y)
{
auto color = data.getPixelColour (x, y);
expect (color == expectedColor);
}
}
}
void testFormatConversion()
{
for (auto sourceFormat : formats)
{
for (auto destFormat : formats)
{
auto softwareStartImage = Image { SoftwareImageType {}.create (sourceFormat, 100, 100, true) };
{
Graphics g { softwareStartImage };
g.fillCheckerBoard (softwareStartImage.getBounds().toFloat(), 21.0f, 21.0f, makeRandomColor(), makeRandomColor());
}
auto convertedSoftwareImage = softwareStartImage.convertedToFormat (destFormat);
compareImages (softwareStartImage, convertedSoftwareImage, compareFunctions[{ sourceFormat, destFormat }]);
auto direct2DImage = NativeImageType {}.convert (softwareStartImage);
compareImages (softwareStartImage, direct2DImage, compareFunctions[{ sourceFormat, sourceFormat }]);
auto convertedDirect2DImage = direct2DImage.convertedToFormat (destFormat);
compareImages (softwareStartImage, convertedDirect2DImage, compareFunctions[{ sourceFormat, destFormat }]);
}
}
}
Colour makeRandomColor()
{
uint8 red = (uint8) random.nextInt (255);
uint8 green = (uint8) random.nextInt (255);
uint8 blue = (uint8) random.nextInt (255);
uint8 alpha = (uint8) random.nextInt (255);
return Colour { red, green, blue, alpha };
}
Random random;
std::array<Image::PixelFormat, 3> const formats { Image::RGB, Image::ARGB, Image::SingleChannel };
std::map<std::pair<Image::PixelFormat, Image::PixelFormat>, std::function<bool (uint8*, uint8*)>> compareFunctions;
};
static Direct2DImageUnitTest direct2DImageUnitTest;
#endif
} // namespace juce

View file

@ -0,0 +1,93 @@
/*
==============================================================================
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
{
class Direct2DPixelData : public ImagePixelData,
private DxgiAdapterListener
{
public:
using Ptr = ReferenceCountedObjectPtr<Direct2DPixelData>;
static Ptr make (Image::PixelFormat formatToUse,
int w,
int h,
bool clearImageIn,
DxgiAdapter::Ptr adapterIn);
static Ptr fromDirect2DBitmap (ComSmartPtr<ID2D1Bitmap1> bitmap);
~Direct2DPixelData() override;
std::unique_ptr<LowLevelGraphicsContext> createLowLevelContext() override;
void initialiseBitmapData (Image::BitmapData& bitmap, int x, int y, Image::BitmapData::ReadWriteMode mode) override;
ImagePixelData::Ptr clone() override;
void applyGaussianBlurEffect (float radius, Image& result) override;
std::unique_ptr<ImageType> createType() const override;
DxgiAdapter::Ptr getAdapter() const { return adapter; }
ComSmartPtr<ID2D1Bitmap1> getAdapterD2D1Bitmap();
void flushToSoftwareBackup();
private:
Direct2DPixelData (Image::PixelFormat, int, int, bool, DxgiAdapter::Ptr);
int getPixelStride() const { return pixelFormat == Image::SingleChannel ? 1 : 4; }
int getLineStride() const { return (getPixelStride() * jmax (1, width) + 3) & ~3; }
void adapterCreated (DxgiAdapter::Ptr) override;
void adapterRemoved (DxgiAdapter::Ptr) override;
void initBitmapDataReadOnly (Image::BitmapData&, int, int);
ComSmartPtr<ID2D1Bitmap1> createAdapterBitmap() const;
void createDeviceResources();
SharedResourcePointer<DirectX> directX;
const bool clearImage;
Image backup;
DxgiAdapter::Ptr adapter;
ComSmartPtr<ID2D1DeviceContext1> context;
ComSmartPtr<ID2D1Bitmap1> nativeBitmap;
JUCE_LEAK_DETECTOR (Direct2DPixelData)
};
} // namespace juce

View file

@ -0,0 +1,132 @@
/*
==============================================================================
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.
==============================================================================
*/
#if JUCE_DIRECT2D_METRICS
namespace juce
{
String Direct2DMetricsHub::getProcessString() noexcept
{
auto processID = GetCurrentProcessId();
return String::toHexString ((pointer_sized_int) processID);
}
void Direct2DMetricsHub::HubPipeServer::messageReceived (const MemoryBlock& message)
{
int requestType = *(int*) message.getData();
switch (requestType)
{
case getValuesRequest:
{
ScopedLock locker { owner.lock };
auto foregroundWindow = GetForegroundWindow();
Direct2DMetrics::Ptr metrics = nullptr;
for (int i = 0; i < owner.metricsArray.size(); ++i)
{
auto arrayEntry = owner.metricsArray[i];
if (arrayEntry->windowHandle && arrayEntry->windowHandle == foregroundWindow)
{
metrics = arrayEntry;
break;
}
}
if (! metrics)
{
if (owner.lastMetrics && owner.metricsArray.contains (owner.lastMetrics))
metrics = owner.lastMetrics;
}
if (metrics)
{
MemoryBlock block { sizeof (GetValuesResponse), true };
auto* response = (GetValuesResponse*) block.getData();
response->responseType = getValuesRequest;
response->windowHandle = metrics->windowHandle;
for (size_t i = 0; i <= Direct2DMetrics::drawGlyphRunTime; ++i)
{
auto& accumulator = metrics->getAccumulator (i);
response->values[i].count = accumulator.getCount();
response->values[i].total = metrics->getSum (i);
response->values[i].average = accumulator.getAverage();
response->values[i].minimum = accumulator.getMinValue();
response->values[i].maximum = accumulator.getMaxValue();
response->values[i].stdDev = accumulator.getStandardDeviation();
}
// Track bitmap operations common to all device contexts
for (size_t i = Direct2DMetrics::createBitmapTime; i <= Direct2DMetrics::unmapBitmapTime; ++i)
{
auto& accumulator = owner.imageContextMetrics->getAccumulator (i);
response->values[i].count = accumulator.getCount();
response->values[i].total = metrics->getSum (i);
response->values[i].average = accumulator.getAverage();
response->values[i].minimum = accumulator.getMinValue();
response->values[i].maximum = accumulator.getMaxValue();
response->values[i].stdDev = accumulator.getStandardDeviation();
}
sendMessage (block);
owner.lastMetrics = metrics.get();
}
break;
}
case resetValuesRequest:
{
owner.resetAll();
break;
}
}
}
void Direct2DMetricsHub::resetAll()
{
ScopedLock locker { lock };
imageContextMetrics->reset();
for (auto metrics : metricsArray)
{
metrics->reset();
}
}
} // namespace juce
#endif

View file

@ -0,0 +1,320 @@
/*
==============================================================================
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.
==============================================================================
*/
#pragma once
#if JUCE_DIRECT2D_METRICS
namespace juce
{
struct Direct2DMetrics : public ReferenceCountedObject
{
using Ptr = ReferenceCountedObjectPtr<Direct2DMetrics>;
#define DIRECT2D_PAINT_STAT_LIST \
DIRECT2D_PAINT_STAT (messageThreadPaintDuration) \
DIRECT2D_PAINT_STAT (swapChainThreadTime) \
DIRECT2D_PAINT_STAT (frameInterval) \
DIRECT2D_PAINT_STAT (endDrawDuration) \
DIRECT2D_PAINT_STAT (present1Duration) \
DIRECT2D_PAINT_STAT (createGeometryTime) \
DIRECT2D_PAINT_STAT (drawGeometryTime) \
DIRECT2D_PAINT_STAT (fillGeometryTime) \
DIRECT2D_PAINT_STAT (createFilledGRTime) \
DIRECT2D_PAINT_STAT (createStrokedGRTime) \
DIRECT2D_PAINT_STAT (drawGRTime) \
DIRECT2D_PAINT_STAT (createGradientTime) \
DIRECT2D_PAINT_STAT (pushAliasedAxisAlignedLayerTime) \
DIRECT2D_PAINT_STAT (pushGeometryLayerTime) \
DIRECT2D_PAINT_STAT (fillTranslatedRectTime) \
DIRECT2D_PAINT_STAT (fillAxisAlignedRectTime) \
DIRECT2D_PAINT_STAT (fillTransformedRectTime) \
DIRECT2D_PAINT_STAT (fillRectListTime) \
DIRECT2D_PAINT_STAT (drawImageTime) \
DIRECT2D_PAINT_STAT (spriteBatchTime) \
DIRECT2D_PAINT_STAT (spriteBatchSetupTime) \
DIRECT2D_PAINT_STAT (createSpriteSourceTime) \
DIRECT2D_PAINT_STAT (setSpritesTime) \
DIRECT2D_PAINT_STAT (addSpritesTime) \
DIRECT2D_PAINT_STAT (clearSpritesTime) \
DIRECT2D_PAINT_STAT (drawSpritesTime) \
DIRECT2D_PAINT_STAT (drawGlyphRunTime) \
DIRECT2D_PAINT_STAT (createBitmapTime) \
DIRECT2D_PAINT_STAT (mapBitmapTime) \
DIRECT2D_LAST_PAINT_STAT (unmapBitmapTime)
#define DIRECT2D_PAINT_STAT(name) name,
#define DIRECT2D_LAST_PAINT_STAT(name) name
enum
{
DIRECT2D_PAINT_STAT_LIST,
numStats
};
#undef DIRECT2D_PAINT_STAT
#undef DIRECT2D_LAST_PAINT_STAT
#define DIRECT2D_PAINT_STAT(name) #name,
#define DIRECT2D_LAST_PAINT_STAT(name) #name
StringArray const accumulatorNames { DIRECT2D_PAINT_STAT_LIST };
#undef DIRECT2D_PAINT_STAT
#undef DIRECT2D_LAST_PAINT_STAT
CriticalSection& lock;
String const name;
void* const windowHandle;
int64 const creationTime = Time::getMillisecondCounter();
double const millisecondsPerTick = 1000.0 / (double) Time::getHighResolutionTicksPerSecond();
int paintCount = 0;
int presentCount = 0;
int present1Count = 0;
int64 lastPaintStartTicks = 0;
uint64 lockAcquireMaxTicks = 0;
Direct2DMetrics (CriticalSection& lockIn, String nameIn, void* windowHandleIn)
: lock (lockIn),
name (nameIn),
windowHandle (windowHandleIn)
{
}
~Direct2DMetrics() = default;
void startFrame()
{
ScopedLock locker { lock };
zerostruct (sums);
}
void finishFrame()
{
}
void reset()
{
ScopedLock locker { lock };
for (auto& accumulator : runningAccumulators)
accumulator.reset();
lastPaintStartTicks = 0;
paintCount = 0;
present1Count = 0;
lockAcquireMaxTicks = 0;
}
auto& getAccumulator (size_t index) noexcept
{
return runningAccumulators[index];
}
auto getSum (size_t index) const noexcept
{
return sums[index];
}
void addValueTicks (size_t index, int64 ticks)
{
addValueMsec (index, Time::highResolutionTicksToSeconds (ticks) * 1000.0);
}
void addValueMsec (size_t index, double value)
{
ScopedLock locker { lock };
auto& accumulator = runningAccumulators[index];
switch (index)
{
case frameInterval:
if (accumulator.getCount() > 100)
{
accumulator.reset();
}
break;
}
accumulator.addValue (value);
sums[index] += value;
}
private:
std::array<StatisticsAccumulator<double>, numStats> runningAccumulators;
std::array<double, numStats> sums;
};
struct Direct2DScopedElapsedTime
{
Direct2DScopedElapsedTime (Direct2DMetrics::Ptr& metricsIn, size_t accumulatorIndexIn)
: metrics (metricsIn.get()),
accumulatorIndex (accumulatorIndexIn)
{
}
Direct2DScopedElapsedTime (Direct2DMetrics* metricsIn, size_t accumulatorIndexIn)
: metrics (metricsIn),
accumulatorIndex (accumulatorIndexIn)
{
}
~Direct2DScopedElapsedTime()
{
auto finishTicks = Time::getHighResolutionTicks();
metrics->addValueTicks (accumulatorIndex, finishTicks - startTicks);
}
int64 startTicks = Time::getHighResolutionTicks();
Direct2DMetrics* metrics;
size_t accumulatorIndex;
};
class Direct2DMetricsHub : public DeletedAtShutdown
{
public:
Direct2DMetricsHub()
{
imageContextMetrics = new Direct2DMetrics { lock, "Image " + getProcessString(), nullptr };
add (imageContextMetrics);
}
~Direct2DMetricsHub() override
{
clearSingletonInstance();
}
void add (Direct2DMetrics::Ptr metrics)
{
metricsArray.insert (0, metrics);
}
void remove (Direct2DMetrics::Ptr metrics)
{
metricsArray.removeObject (metrics);
}
Direct2DMetrics::Ptr getMetricsForWindowHandle (void* windowHandle) noexcept
{
for (auto& metrics : metricsArray)
if (metrics->windowHandle == windowHandle)
return metrics;
return nullptr;
}
enum
{
getValuesRequest,
resetValuesRequest
};
struct MetricValues
{
size_t count;
double total;
double average;
double minimum;
double maximum;
double stdDev;
};
struct GetValuesResponse
{
int responseType;
void* windowHandle;
MetricValues values[Direct2DMetrics::numStats];
};
CriticalSection lock;
Direct2DMetrics::Ptr imageContextMetrics;
static constexpr int magicNumber = 0xd2d1;
JUCE_DECLARE_SINGLETON (Direct2DMetricsHub, false)
private:
static String getProcessString() noexcept;
void resetAll();
struct HubPipeServer : public InterprocessConnection
{
explicit HubPipeServer (Direct2DMetricsHub& ownerIn)
: InterprocessConnection (false, magicNumber),
owner (ownerIn)
{
createPipe ("JUCEDirect2DMetricsHub:" + owner.getProcessString(), -1, true);
}
~HubPipeServer() override
{
disconnect();
}
void connectionMade() override
{
}
void connectionLost() override
{
}
void messageReceived (const MemoryBlock& message) override;
Direct2DMetricsHub& owner;
};
HubPipeServer hubPipeServer { *this };
ReferenceCountedArray<Direct2DMetrics> metricsArray;
Direct2DMetrics* lastMetrics = nullptr;
};
} // namespace juce
#define JUCE_D2DMETRICS_SCOPED_ELAPSED_TIME(metrics, name) juce::Direct2DScopedElapsedTime scopedElapsedTime_##name { metrics, juce::Direct2DMetrics::name };
#else
namespace juce
{
struct Direct2DMetrics : public ReferenceCountedObject
{
using Ptr = ReferenceCountedObjectPtr<Direct2DMetrics>;
};
} // namespace juce
#define JUCE_D2DMETRICS_SCOPED_ELAPSED_TIME(metrics, name)
#endif

View file

@ -0,0 +1,670 @@
/*
==============================================================================
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
{
struct Direct2DDeviceContext
{
HRESULT createHwndRenderTarget (HWND hwnd)
{
if (hwndRenderTarget != nullptr)
return S_OK;
SharedResourcePointer<DirectX> directX;
D2D1_SIZE_U size { 1, 1 };
D2D1_RENDER_TARGET_PROPERTIES renderTargetProps{};
renderTargetProps.pixelFormat.alphaMode = D2D1_ALPHA_MODE_PREMULTIPLIED;
renderTargetProps.pixelFormat.format = DXGI_FORMAT_B8G8R8A8_UNORM;
D2D1_HWND_RENDER_TARGET_PROPERTIES hwndRenderTargetProps{};
hwndRenderTargetProps.hwnd = hwnd;
hwndRenderTargetProps.pixelSize = size;
hwndRenderTargetProps.presentOptions = D2D1_PRESENT_OPTIONS_IMMEDIATELY | D2D1_PRESENT_OPTIONS_RETAIN_CONTENTS;
return directX->getD2DFactory()->CreateHwndRenderTarget (&renderTargetProps,
&hwndRenderTargetProps,
hwndRenderTarget.resetAndGetPointerAddress());
}
void resetTransform()
{
context->SetTransform (D2D1::IdentityMatrix());
}
void setTransform (AffineTransform newTransform)
{
context->SetTransform (D2DUtilities::transformToMatrix (newTransform));
}
void release()
{
hwndRenderTarget = nullptr;
context = nullptr;
}
static ComSmartPtr<ID2D1DeviceContext1> createContext (DxgiAdapter::Ptr adapter)
{
ComSmartPtr<ID2D1DeviceContext1> result;
if (const auto hr = adapter->direct2DDevice->CreateDeviceContext (D2D1_DEVICE_CONTEXT_OPTIONS_ENABLE_MULTITHREADED_OPTIMIZATIONS,
result.resetAndGetPointerAddress());
FAILED (hr))
{
jassertfalse;
return {};
}
result->SetTextAntialiasMode (D2D1_TEXT_ANTIALIAS_MODE_GRAYSCALE);
result->SetAntialiasMode (D2D1_ANTIALIAS_MODE_PER_PRIMITIVE);
result->SetUnitMode (D2D1_UNIT_MODE_PIXELS);
return result;
}
ComSmartPtr<ID2D1DeviceContext1> context;
ComSmartPtr<ID2D1HwndRenderTarget> hwndRenderTarget;
};
class Direct2DBitmap final
{
public:
static ComSmartPtr<ID2D1Bitmap1> fromImage (const Image& image,
ComSmartPtr<ID2D1DeviceContext1> deviceContext,
Image::PixelFormat outputFormat)
{
JUCE_D2DMETRICS_SCOPED_ELAPSED_TIME (Direct2DMetricsHub::getInstance()->imageContextMetrics, createBitmapTime);
jassert (outputFormat == Image::ARGB || outputFormat == Image::SingleChannel);
JUCE_TRACE_LOG_D2D_PAINT_CALL (etw::createDirect2DBitmapFromImage, etw::graphicsKeyword);
// Calling Image::convertedToFormat could cause unchecked recursion since convertedToFormat
// calls Graphics::drawImageAt which calls Direct2DGraphicsContext::drawImage which calls this function...
//
// Use a software image for the conversion instead so the Graphics::drawImageAt call doesn't go
// through the Direct2D renderer
//
// Be sure to explicitly set the DPI to 96.0 for the image; otherwise it will default to the screen DPI
// and may be scaled incorrectly
const auto convertedImage = SoftwareImageType{}.convert (image).convertedToFormat (outputFormat);
if (! convertedImage.isValid())
return {};
Image::BitmapData bitmapData { convertedImage, Image::BitmapData::readWrite };
D2D1_BITMAP_PROPERTIES1 bitmapProperties{};
bitmapProperties.pixelFormat.format = outputFormat == Image::SingleChannel
? DXGI_FORMAT_A8_UNORM
: DXGI_FORMAT_B8G8R8A8_UNORM;
bitmapProperties.pixelFormat.alphaMode = outputFormat == Image::RGB
? D2D1_ALPHA_MODE_IGNORE
: D2D1_ALPHA_MODE_PREMULTIPLIED;
bitmapProperties.dpiX = USER_DEFAULT_SCREEN_DPI;
bitmapProperties.dpiY = USER_DEFAULT_SCREEN_DPI;
const D2D1_SIZE_U size { (UINT32) image.getWidth(), (UINT32) image.getHeight() };
ComSmartPtr<ID2D1Bitmap1> bitmap;
deviceContext->CreateBitmap (size,
bitmapData.data,
(UINT32) bitmapData.lineStride,
bitmapProperties,
bitmap.resetAndGetPointerAddress());
return bitmap;
}
static ComSmartPtr<ID2D1Bitmap1> createBitmap (ComSmartPtr<ID2D1DeviceContext1> deviceContext,
Image::PixelFormat format,
D2D_SIZE_U size,
int lineStride,
D2D1_BITMAP_OPTIONS options)
{
JUCE_TRACE_LOG_D2D_PAINT_CALL (etw::createDirect2DBitmap, etw::graphicsKeyword);
JUCE_D2DMETRICS_SCOPED_ELAPSED_TIME (Direct2DMetricsHub::getInstance()->imageContextMetrics, createBitmapTime);
#if JUCE_DEBUG
// Verify that the GPU can handle a bitmap of this size
//
// If you need a bitmap larger than this, you'll need to either split it up into multiple bitmaps
// or use a software image (see SoftwareImageType).
auto maxBitmapSize = deviceContext->GetMaximumBitmapSize();
jassert (size.width <= maxBitmapSize && size.height <= maxBitmapSize);
#endif
D2D1_BITMAP_PROPERTIES1 bitmapProperties{};
bitmapProperties.dpiX = bitmapProperties.dpiY = USER_DEFAULT_SCREEN_DPI;
bitmapProperties.pixelFormat.format = format == Image::SingleChannel
? DXGI_FORMAT_A8_UNORM
: DXGI_FORMAT_B8G8R8A8_UNORM;
bitmapProperties.pixelFormat.alphaMode = format == Image::RGB
? D2D1_ALPHA_MODE_IGNORE
: D2D1_ALPHA_MODE_PREMULTIPLIED;
bitmapProperties.bitmapOptions = options;
ComSmartPtr<ID2D1Bitmap1> bitmap;
deviceContext->CreateBitmap (size,
nullptr,
(UINT32) lineStride,
bitmapProperties,
bitmap.resetAndGetPointerAddress());
return bitmap;
}
Direct2DBitmap() = delete;
};
static ComSmartPtr<ID2D1GradientStopCollection> makeGradientStopCollection (const ColourGradient& gradient,
ComSmartPtr<ID2D1DeviceContext1> deviceContext,
[[maybe_unused]] Direct2DMetrics* metrics) noexcept
{
JUCE_D2DMETRICS_SCOPED_ELAPSED_TIME (metrics, createGradientTime);
const int numColors = gradient.getNumColours();
std::vector<D2D1_GRADIENT_STOP> stops ((size_t) numColors);
for (auto [index, stop] : enumerate (stops, int{}))
{
stop.color = D2DUtilities::toCOLOR_F (gradient.getColour (index));
stop.position = (FLOAT) gradient.getColourPosition (index);
}
ComSmartPtr<ID2D1GradientStopCollection> result;
deviceContext->CreateGradientStopCollection (stops.data(), (UINT32) stops.size(), result.resetAndGetPointerAddress());
return result;
}
class LinearGradientCache
{
public:
ComSmartPtr<ID2D1LinearGradientBrush> get (const ColourGradient& gradient,
ComSmartPtr<ID2D1DeviceContext1> deviceContext,
Direct2DMetrics* metrics)
{
jassert (! gradient.isRadial);
return cache.get (gradient, [&deviceContext, &metrics] (const auto& key)
{
const auto gradientStops = makeGradientStopCollection (key, deviceContext, metrics);
const auto p1 = key.point1;
const auto p2 = key.point2;
const auto linearGradientBrushProperties = D2D1::LinearGradientBrushProperties ({ p1.x, p1.y }, { p2.x, p2.y });
const D2D1_BRUSH_PROPERTIES brushProps { 1.0f, D2D1::IdentityMatrix() };
ComSmartPtr<ID2D1LinearGradientBrush> result;
deviceContext->CreateLinearGradientBrush (linearGradientBrushProperties,
brushProps,
gradientStops,
result.resetAndGetPointerAddress());
return result;
});
}
private:
LruCache<ColourGradient, ComSmartPtr<ID2D1LinearGradientBrush>> cache;
};
class RadialGradientCache
{
public:
ComSmartPtr<ID2D1RadialGradientBrush> get (const ColourGradient& gradient,
ComSmartPtr<ID2D1DeviceContext1> deviceContext,
Direct2DMetrics* metrics)
{
jassert (gradient.isRadial);
return cache.get (gradient, [&deviceContext, &metrics] (const auto& key)
{
const auto gradientStops = makeGradientStopCollection (key, deviceContext, metrics);
const auto p1 = key.point1;
const auto p2 = key.point2;
const auto r = p1.getDistanceFrom (p2);
const auto radialGradientBrushProperties = D2D1::RadialGradientBrushProperties ({ p1.x, p1.y }, {}, r, r);
const D2D1_BRUSH_PROPERTIES brushProps { 1.0F, D2D1::IdentityMatrix() };
ComSmartPtr<ID2D1RadialGradientBrush> result;
deviceContext->CreateRadialGradientBrush (radialGradientBrushProperties,
brushProps,
gradientStops,
result.resetAndGetPointerAddress());
return result;
});
}
private:
LruCache<ColourGradient, ComSmartPtr<ID2D1RadialGradientBrush>> cache;
};
class RectangleListSpriteBatch
{
public:
RectangleListSpriteBatch() = default;
~RectangleListSpriteBatch()
{
release();
}
void release()
{
whiteRectangle = nullptr;
spriteBatches = {};
destinations.free();
destinationsCapacity = 0;
}
template <typename TransformRectangle>
void fillRectangles (ComSmartPtr<ID2D1DeviceContext1> deviceContext,
const RectangleList<float>& rectangles,
const Colour colour,
TransformRectangle&& transformRectangle,
[[maybe_unused]] Direct2DMetrics* metrics)
{
if (rectangles.isEmpty())
return;
JUCE_D2DMETRICS_SCOPED_ELAPSED_TIME (metrics, spriteBatchTime)
auto numRectanglesPainted = 0;
while (numRectanglesPainted < rectangles.getNumRectangles())
{
auto numRectanglesRemaining = rectangles.getNumRectangles() - numRectanglesPainted;
auto spriteBatchSize = isPowerOfTwo (numRectanglesRemaining) ? numRectanglesRemaining : (nextPowerOfTwo (numRectanglesRemaining) >> 1);
{
JUCE_D2DMETRICS_SCOPED_ELAPSED_TIME (metrics, spriteBatchSetupTime);
if (destinationsCapacity < (size_t) spriteBatchSize)
{
destinations.calloc (spriteBatchSize);
destinationsCapacity = (size_t) spriteBatchSize;
}
auto destination = destinations.getData();
for (int i = numRectanglesPainted; i < numRectanglesPainted + spriteBatchSize; ++i)
{
auto r = rectangles.getRectangle (i);
r = transformRectangle (r);
*destination = D2DUtilities::toRECT_F (r);
++destination;
}
}
if (! whiteRectangle)
{
JUCE_D2DMETRICS_SCOPED_ELAPSED_TIME (metrics, createSpriteSourceTime);
auto hr = deviceContext->CreateCompatibleRenderTarget (D2D1_SIZE_F { (float) rectangleSize, (float) rectangleSize },
D2D1_SIZE_U { rectangleSize, rectangleSize },
D2D1_PIXEL_FORMAT { DXGI_FORMAT_B8G8R8A8_UNORM, D2D1_ALPHA_MODE_PREMULTIPLIED },
whiteRectangle.resetAndGetPointerAddress());
if (FAILED (hr))
return;
whiteRectangle->BeginDraw();
whiteRectangle->Clear (D2D1_COLOR_F { 1.0f, 1.0f, 1.0f, 1.0f });
whiteRectangle->EndDraw();
}
ComSmartPtr<ID2D1Bitmap> bitmap;
if (auto hr = whiteRectangle->GetBitmap (bitmap.resetAndGetPointerAddress()); SUCCEEDED (hr))
{
ComSmartPtr<ID2D1DeviceContext3> deviceContext3;
if (hr = deviceContext->QueryInterface<ID2D1DeviceContext3> (deviceContext3.resetAndGetPointerAddress()); SUCCEEDED (hr))
{
auto d2dColour = D2DUtilities::toCOLOR_F (colour);
auto spriteBatch = getSpriteBatch (*deviceContext3, (uint32) spriteBatchSize);
if (spriteBatch == nullptr)
return;
auto setCount = jmin ((uint32) spriteBatchSize, spriteBatch->GetSpriteCount());
auto addCount = (uint32) spriteBatchSize > setCount ? (uint32) spriteBatchSize - setCount : 0;
if (setCount != 0)
{
JUCE_D2DMETRICS_SCOPED_ELAPSED_TIME (metrics, setSpritesTime);
spriteBatch->SetSprites (0, setCount, destinations.getData(), nullptr, &d2dColour, nullptr, sizeof (D2D1_RECT_F), 0, 0, 0);
}
if (addCount != 0)
{
JUCE_D2DMETRICS_SCOPED_ELAPSED_TIME (metrics, addSpritesTime);
spriteBatch->AddSprites (addCount, destinations.getData() + setCount, nullptr, &d2dColour, nullptr, sizeof (D2D1_RECT_F), 0, 0, 0);
}
JUCE_D2DMETRICS_SCOPED_ELAPSED_TIME (metrics, drawSpritesTime);
deviceContext3->SetAntialiasMode (D2D1_ANTIALIAS_MODE_ALIASED);
deviceContext3->DrawSpriteBatch (spriteBatch, bitmap);
deviceContext3->SetAntialiasMode (D2D1_ANTIALIAS_MODE_PER_PRIMITIVE);
}
}
numRectanglesPainted += spriteBatchSize;
}
}
private:
ComSmartPtr<ID2D1SpriteBatch> getSpriteBatch (ID2D1DeviceContext3& dc, uint32 key)
{
return spriteBatches.get ((uint32) key, [&dc] (auto) -> ComSmartPtr<ID2D1SpriteBatch>
{
ComSmartPtr<ID2D1SpriteBatch> result;
if (const auto hr = dc.CreateSpriteBatch (result.resetAndGetPointerAddress()); SUCCEEDED (hr))
return result;
return nullptr;
});
}
static constexpr uint32 rectangleSize = 32;
ComSmartPtr<ID2D1BitmapRenderTarget> whiteRectangle;
HeapBlock<D2D1_RECT_F> destinations;
size_t destinationsCapacity = 0;
LruCache<uint32, ComSmartPtr<ID2D1SpriteBatch>, 8> spriteBatches;
};
class Direct2DDeviceResources
{
public:
Direct2DDeviceResources() = default;
// Create a Direct2D device context for a DXGI adapter
HRESULT create (DxgiAdapter::Ptr adapter)
{
jassert (adapter);
if (deviceContext.context == nullptr)
deviceContext.context = Direct2DDeviceContext::createContext (adapter);
if (colourBrush == nullptr)
{
if (const auto hr = deviceContext.context->CreateSolidColorBrush (D2D1::ColorF (0.0f, 0.0f, 0.0f, 1.0f),
colourBrush.resetAndGetPointerAddress());
FAILED (hr))
{
jassertfalse;
return hr;
}
}
if (rectangleListSpriteBatch == nullptr)
rectangleListSpriteBatch = std::make_unique<RectangleListSpriteBatch>();
return S_OK;
}
void release()
{
rectangleListSpriteBatch = nullptr;
linearGradientCache = {};
radialGradientCache = {};
colourBrush = nullptr;
deviceContext.release();
}
bool canPaint (DxgiAdapter::Ptr adapter) const
{
return adapter->direct2DDevice != nullptr && deviceContext.context != nullptr && colourBrush != nullptr;
}
Direct2DDeviceContext deviceContext;
ComSmartPtr<ID2D1SolidColorBrush> colourBrush;
LinearGradientCache linearGradientCache;
RadialGradientCache radialGradientCache;
std::unique_ptr<RectangleListSpriteBatch> rectangleListSpriteBatch;
};
class SwapChain
{
public:
SwapChain() = default;
HRESULT create (HWND hwnd, Rectangle<int> size, DxgiAdapter::Ptr adapter)
{
if (chain != nullptr || hwnd == nullptr)
return S_OK;
SharedResourcePointer<DirectX> directX;
auto dxgiFactory = directX->adapters.getFactory();
if (dxgiFactory == nullptr || adapter->direct3DDevice == nullptr)
return E_FAIL;
buffer = nullptr;
chain = nullptr;
// Make the waitable swap chain
// Create the swap chain with premultiplied alpha support for transparent windows
DXGI_SWAP_CHAIN_DESC1 swapChainDescription = {};
swapChainDescription.Format = DXGI_FORMAT_B8G8R8A8_UNORM;
swapChainDescription.Width = (UINT) size.getWidth();
swapChainDescription.Height = (UINT) size.getHeight();
swapChainDescription.SampleDesc.Count = 1;
swapChainDescription.BufferUsage = DXGI_USAGE_RENDER_TARGET_OUTPUT;
swapChainDescription.BufferCount = bufferCount;
swapChainDescription.SwapEffect = swapEffect;
swapChainDescription.Flags = swapChainFlags;
swapChainDescription.Scaling = DXGI_SCALING_STRETCH;
swapChainDescription.AlphaMode = DXGI_ALPHA_MODE_PREMULTIPLIED;
if (const auto hr = dxgiFactory->CreateSwapChainForComposition (adapter->direct3DDevice,
&swapChainDescription,
nullptr,
chain.resetAndGetPointerAddress());
FAILED (hr))
{
return hr;
}
// Get the waitable swap chain presentation event and set the maximum frame latency
ComSmartPtr<IDXGISwapChain2> chain2;
if (const auto hr = chain.QueryInterface (chain2); FAILED (hr))
return hr;
if (chain2 == nullptr)
return E_FAIL;
swapChainEvent.emplace (chain2->GetFrameLatencyWaitableObject());
if (swapChainEvent->getHandle() == INVALID_HANDLE_VALUE)
return E_NOINTERFACE;
if (const auto hr = chain2->SetMaximumFrameLatency (1); SUCCEEDED (hr))
state = State::chainAllocated;
return S_OK;
}
HRESULT createBuffer (ComSmartPtr<ID2D1DeviceContext> deviceContext)
{
if (deviceContext == nullptr || chain == nullptr || buffer != nullptr)
return S_OK;
ComSmartPtr<IDXGISurface> surface;
JUCE_BEGIN_IGNORE_WARNINGS_GCC_LIKE ("-Wlanguage-extension-token")
if (const auto hr = chain->GetBuffer (0, __uuidof (surface), reinterpret_cast<void**> (surface.resetAndGetPointerAddress())); FAILED (hr))
return hr;
JUCE_END_IGNORE_WARNINGS_GCC_LIKE
D2D1_BITMAP_PROPERTIES1 bitmapProperties{};
bitmapProperties.bitmapOptions = D2D1_BITMAP_OPTIONS_TARGET | D2D1_BITMAP_OPTIONS_CANNOT_DRAW;
bitmapProperties.pixelFormat.format = DXGI_FORMAT_B8G8R8A8_UNORM;
bitmapProperties.pixelFormat.alphaMode = D2D1_ALPHA_MODE_PREMULTIPLIED;
if (const auto hr = deviceContext->CreateBitmapFromDxgiSurface (surface, bitmapProperties, buffer.resetAndGetPointerAddress()); FAILED (hr))
return hr;
state = State::bufferAllocated;
return S_OK;
}
void release()
{
buffer = nullptr;
chain = nullptr;
state = State::idle;
}
bool canPaint() const
{
return chain != nullptr && buffer != nullptr && state >= State::bufferAllocated;
}
HRESULT resize (Rectangle<int> newSize, float dpiScalingFactor, ComSmartPtr<ID2D1DeviceContext> deviceContext)
{
if (chain == nullptr)
return E_FAIL;
auto scaledSize = newSize * dpiScalingFactor;
scaledSize = scaledSize.getUnion ({ Direct2DGraphicsContext::minFrameSize, Direct2DGraphicsContext::minFrameSize })
.getIntersection ({ Direct2DGraphicsContext::maxFrameSize, Direct2DGraphicsContext::maxFrameSize });
buffer = nullptr;
state = State::chainAllocated;
auto dpi = USER_DEFAULT_SCREEN_DPI * dpiScalingFactor;
deviceContext->SetDpi (dpi, dpi);
if (const auto hr = chain->ResizeBuffers (0, (UINT) scaledSize.getWidth(), (UINT) scaledSize.getHeight(), DXGI_FORMAT_B8G8R8A8_UNORM, swapChainFlags); FAILED (hr))
return hr;
if (const auto hr = createBuffer (deviceContext); FAILED (hr))
{
release();
return hr;
}
return S_OK;
}
Rectangle<int> getSize() const
{
if (buffer == nullptr)
return {};
auto size = buffer->GetPixelSize();
return { (int) size.width, (int) size.height };
}
DXGI_SWAP_EFFECT const swapEffect = DXGI_SWAP_EFFECT_FLIP_SEQUENTIAL;
UINT const bufferCount = 2;
uint32 const swapChainFlags = DXGI_SWAP_CHAIN_FLAG_FRAME_LATENCY_WAITABLE_OBJECT;
uint32 const presentSyncInterval = 1;
uint32 const presentFlags = 0;
ComSmartPtr<IDXGISwapChain1> chain;
ComSmartPtr<ID2D1Bitmap1> buffer;
std::optional<WindowsScopedEvent> swapChainEvent;
enum class State
{
idle,
chainAllocated,
bufferAllocated,
bufferFilled
};
State state = State::idle;
};
//==============================================================================
/* DirectComposition
Using DirectComposition enables transparent windows and smoother window
resizing
This class builds a simple DirectComposition tree that ultimately contains
the swap chain
*/
class CompositionTree
{
public:
HRESULT create (IDXGIDevice* const dxgiDevice, HWND hwnd, IDXGISwapChain1* const swapChain)
{
if (compositionDevice != nullptr)
return S_OK;
if (dxgiDevice == nullptr)
return E_FAIL;
JUCE_BEGIN_IGNORE_WARNINGS_GCC_LIKE ("-Wlanguage-extension-token")
if (const auto hr = DCompositionCreateDevice (dxgiDevice,
__uuidof (IDCompositionDevice),
reinterpret_cast<void**> (compositionDevice.resetAndGetPointerAddress()));
FAILED (hr))
{
return hr;
}
JUCE_END_IGNORE_WARNINGS_GCC_LIKE
if (const auto hr = compositionDevice->CreateTargetForHwnd (hwnd, FALSE, compositionTarget.resetAndGetPointerAddress()); FAILED (hr))
return hr;
if (const auto hr = compositionDevice->CreateVisual (compositionVisual.resetAndGetPointerAddress()); FAILED (hr))
return hr;
if (const auto hr = compositionTarget->SetRoot (compositionVisual); FAILED (hr))
return hr;
if (const auto hr = compositionVisual->SetContent (swapChain); FAILED (hr))
return hr;
if (const auto hr = compositionDevice->Commit(); FAILED (hr))
return hr;
return S_OK;
}
void release()
{
compositionVisual = nullptr;
compositionTarget = nullptr;
compositionDevice = nullptr;
}
bool canPaint() const
{
return compositionVisual != nullptr;
}
private:
ComSmartPtr<IDCompositionDevice> compositionDevice;
ComSmartPtr<IDCompositionTarget> compositionTarget;
ComSmartPtr<IDCompositionVisual> compositionVisual;
};
} // namespace juce

View file

@ -360,96 +360,93 @@ private:
IDWriteFontFileLoader& loader;
};
//==============================================================================
class Direct2DFactories
{
public:
Direct2DFactories()
{
JUCE_BEGIN_IGNORE_WARNINGS_GCC_LIKE ("-Wlanguage-extension-token")
ComSmartPtr<IDWriteFontCollection> collection;
if (direct2dDll.open ("d2d1.dll"))
{
JUCE_LOAD_WINAPI_FUNCTION (direct2dDll, D2D1CreateFactory, d2d1CreateFactory,
HRESULT, (D2D1_FACTORY_TYPE, REFIID, D2D1_FACTORY_OPTIONS*, void**))
if (d2d1CreateFactory != nullptr)
{
D2D1_FACTORY_OPTIONS options;
options.debugLevel = D2D1_DEBUG_LEVEL_NONE;
d2d1CreateFactory (D2D1_FACTORY_TYPE_SINGLE_THREADED, __uuidof (ID2D1Factory), &options,
(void**) d2dFactory.resetAndGetPointerAddress());
}
}
if (directWriteDll.open ("DWrite.dll"))
{
JUCE_LOAD_WINAPI_FUNCTION (directWriteDll, DWriteCreateFactory, dWriteCreateFactory,
HRESULT, (DWRITE_FACTORY_TYPE, REFIID, IUnknown**))
if (dWriteCreateFactory == nullptr)
return;
for (const auto uuid : { __uuidof (IDWriteFactory3), __uuidof (IDWriteFactory2), __uuidof (IDWriteFactory) })
{
dWriteCreateFactory (DWRITE_FACTORY_TYPE_SHARED, uuid,
(IUnknown**) directWriteFactory.resetAndGetPointerAddress());
if (directWriteFactory != nullptr)
break;
}
if (directWriteFactory != nullptr)
{
directWriteFactory->RegisterFontFileLoader (fileLoader);
directWriteFactory->RegisterFontCollectionLoader (collectionLoader);
ComSmartPtr<IDWriteFontCollection> collection;
if (SUCCEEDED (directWriteFactory->GetSystemFontCollection (collection.resetAndGetPointerAddress(), FALSE)) && collection != nullptr)
fonts.emplace (collection);
else
jassertfalse;
}
if (d2dFactory != nullptr)
{
auto d2dRTProp = D2D1::RenderTargetProperties (D2D1_RENDER_TARGET_TYPE_SOFTWARE,
D2D1::PixelFormat (DXGI_FORMAT_B8G8R8A8_UNORM,
D2D1_ALPHA_MODE_IGNORE),
0, 0,
D2D1_RENDER_TARGET_USAGE_GDI_COMPATIBLE,
D2D1_FEATURE_LEVEL_DEFAULT);
d2dFactory->CreateDCRenderTarget (&d2dRTProp, directWriteRenderTarget.resetAndGetPointerAddress());
}
}
JUCE_END_IGNORE_WARNINGS_GCC_LIKE
if (SUCCEEDED (directWriteFactory->GetSystemFontCollection (collection.resetAndGetPointerAddress(), FALSE)) && collection != nullptr)
fonts.emplace (collection);
else
jassertfalse;
}
~Direct2DFactories()
{
if (directWriteFactory != nullptr)
{
directWriteFactory->UnregisterFontCollectionLoader (collectionLoader);
directWriteFactory->UnregisterFontFileLoader (fileLoader);
}
if (directWriteFactory == nullptr)
return;
directWriteFactory->UnregisterFontCollectionLoader (collectionLoader);
directWriteFactory->UnregisterFontFileLoader (fileLoader);
}
[[nodiscard]] ComSmartPtr<IDWriteFactory> getDWriteFactory() const { return directWriteFactory; }
[[nodiscard]] ComSmartPtr<IDWriteFactory4> getDWriteFactory4() const { return directWriteFactory4; }
[[nodiscard]] AggregateFontCollection& getFonts() { jassert (fonts.has_value()); return *fonts; }
[[nodiscard]] ComSmartPtr<IDWriteFontCollectionLoader> getCollectionLoader() const { return collectionLoader; }
private:
DynamicLibrary direct2dDll, directWriteDll;
ComSmartPtr<ID2D1Factory> d2dFactory;
ComSmartPtr<IDWriteFactory> directWriteFactory;
ComSmartPtr<ID2D1DCRenderTarget> directWriteRenderTarget;
std::optional<AggregateFontCollection> fonts;
DynamicLibrary direct2dDll { "d2d1.dll" }, directWriteDll { "DWrite.dll" };
ComSmartPtr<IDWriteFontFileLoader> fileLoader = becomeComSmartPtrOwner (new MemoryFontFileLoader);
ComSmartPtr<IDWriteFontCollectionLoader> collectionLoader = becomeComSmartPtrOwner (new DirectWriteCustomFontCollectionLoader (*fileLoader));
const ComSmartPtr<ID2D1Factory> d2dFactory = [&]() -> ComSmartPtr<ID2D1Factory>
{
JUCE_LOAD_WINAPI_FUNCTION (direct2dDll,
D2D1CreateFactory,
d2d1CreateFactory,
HRESULT,
(D2D1_FACTORY_TYPE, REFIID, D2D1_FACTORY_OPTIONS*, void**))
if (d2d1CreateFactory == nullptr)
return {};
D2D1_FACTORY_OPTIONS options;
options.debugLevel = D2D1_DEBUG_LEVEL_NONE;
ComSmartPtr<ID2D1Factory> result;
JUCE_BEGIN_IGNORE_WARNINGS_GCC_LIKE ("-Wlanguage-extension-token")
d2d1CreateFactory (D2D1_FACTORY_TYPE_SINGLE_THREADED,
__uuidof (ID2D1Factory),
&options,
(void**) result.resetAndGetPointerAddress());
JUCE_END_IGNORE_WARNINGS_GCC_LIKE
return result;
}();
const ComSmartPtr<IDWriteFontFileLoader> fileLoader = becomeComSmartPtrOwner (new MemoryFontFileLoader);
const ComSmartPtr<IDWriteFontCollectionLoader> collectionLoader = becomeComSmartPtrOwner (new DirectWriteCustomFontCollectionLoader (*fileLoader));
const ComSmartPtr<IDWriteFactory> directWriteFactory = [&]() -> ComSmartPtr<IDWriteFactory>
{
JUCE_LOAD_WINAPI_FUNCTION (directWriteDll,
DWriteCreateFactory,
dWriteCreateFactory,
HRESULT,
(DWRITE_FACTORY_TYPE, REFIID, IUnknown**))
if (dWriteCreateFactory == nullptr)
return {};
ComSmartPtr<IDWriteFactory> result;
JUCE_BEGIN_IGNORE_WARNINGS_GCC_LIKE ("-Wlanguage-extension-token")
dWriteCreateFactory (DWRITE_FACTORY_TYPE_SHARED,
__uuidof (IDWriteFactory),
(IUnknown**) result.resetAndGetPointerAddress());
JUCE_END_IGNORE_WARNINGS_GCC_LIKE
result->RegisterFontFileLoader (fileLoader);
result->RegisterFontCollectionLoader (collectionLoader);
return result;
}();
const ComSmartPtr<IDWriteFactory4> directWriteFactory4 = directWriteFactory.getInterface<IDWriteFactory4>();
std::optional<AggregateFontCollection> fonts;
JUCE_DECLARE_NON_COPYABLE_WITH_LEAK_DETECTOR (Direct2DFactories)
};
@ -567,7 +564,7 @@ public:
return new WindowsDirectWriteTypeface (mappedName, mappedStyle, mapped.font, mappedFace, HbFont { hb_font_create (hbFace.get()) }, {});
}
IDWriteFontFace* getIDWriteFontFace() const { return dwFontFace; }
ComSmartPtr<IDWriteFontFace> getIDWriteFontFace() const { return dwFontFace; }
private:
float getKerning (int glyph1, int glyph2) const

View file

@ -0,0 +1,327 @@
/*
==============================================================================
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
{
struct DxgiAdapter : public ReferenceCountedObject
{
using Ptr = ReferenceCountedObjectPtr<DxgiAdapter>;
DxgiAdapter (ComSmartPtr<ID2D1Factory2> d2dFactory, ComSmartPtr<IDXGIAdapter1> dxgiAdapterIn)
: dxgiAdapter (dxgiAdapterIn)
{
for (UINT i = 0;; ++i)
{
ComSmartPtr<IDXGIOutput> output;
const auto hr = dxgiAdapter->EnumOutputs (i, output.resetAndGetPointerAddress());
if (hr == DXGI_ERROR_NOT_FOUND || hr == DXGI_ERROR_NOT_CURRENTLY_AVAILABLE)
break;
dxgiOutputs.push_back (output);
}
// This flag adds support for surfaces with a different color channel ordering
// than the API default. It is required for compatibility with Direct2D.
const auto creationFlags = D3D11_CREATE_DEVICE_BGRA_SUPPORT;
jassert (dxgiAdapter);
if (const auto hr = D3D11CreateDevice (dxgiAdapter,
D3D_DRIVER_TYPE_UNKNOWN,
nullptr,
creationFlags,
nullptr,
0,
D3D11_SDK_VERSION,
direct3DDevice.resetAndGetPointerAddress(),
nullptr,
nullptr); FAILED (hr))
{
return;
}
if (const auto hr = direct3DDevice->QueryInterface (dxgiDevice.resetAndGetPointerAddress()); FAILED (hr))
return;
if (const auto hr = d2dFactory->CreateDevice (dxgiDevice, direct2DDevice.resetAndGetPointerAddress()); FAILED (hr))
return;
}
void release()
{
direct2DDevice = nullptr;
dxgiDevice = nullptr;
dxgiOutputs.clear();
dxgiAdapter = nullptr;
direct3DDevice = nullptr; // release the Direct3D device after the adapter to avoid an exception with AMD
}
bool uniqueIDMatches (ReferenceCountedObjectPtr<DxgiAdapter> other) const
{
auto luid = getAdapterUniqueID();
auto otherLuid = other->getAdapterUniqueID();
return (luid.HighPart == otherLuid.HighPart) && (luid.LowPart == otherLuid.LowPart);
}
LUID getAdapterUniqueID() const
{
DXGI_ADAPTER_DESC1 desc;
if (auto hr = dxgiAdapter->GetDesc1 (&desc); SUCCEEDED (hr))
return desc.AdapterLuid;
return LUID { 0, 0 };
}
ComSmartPtr<ID3D11Device> direct3DDevice;
ComSmartPtr<IDXGIDevice> dxgiDevice;
ComSmartPtr<ID2D1Device1> direct2DDevice;
ComSmartPtr<IDXGIAdapter1> dxgiAdapter;
std::vector<ComSmartPtr<IDXGIOutput>> dxgiOutputs;
};
struct DxgiAdapterListener
{
virtual ~DxgiAdapterListener() = default;
virtual void adapterCreated (DxgiAdapter::Ptr adapter) = 0;
virtual void adapterRemoved (DxgiAdapter::Ptr adapter) = 0;
};
class DxgiAdapters
{
public:
explicit DxgiAdapters (ComSmartPtr<ID2D1Factory2> d2dFactoryIn)
: d2dFactory (d2dFactoryIn)
{
updateAdapters();
}
~DxgiAdapters()
{
releaseAdapters();
}
void updateAdapters()
{
if (factory != nullptr && factory->IsCurrent() && ! adapterArray.isEmpty())
return;
releaseAdapters();
if (factory == nullptr || ! factory->IsCurrent())
factory = makeDxgiFactory();
if (factory == nullptr)
{
// If you hit this, we were unable to create a DXGI Factory, so we won't be able to
// render anything using Direct2D.
// Maybe this version of Windows doesn't have Direct2D support.
jassertfalse;
return;
}
for (UINT i = 0;; ++i)
{
ComSmartPtr<IDXGIAdapter1> dxgiAdapter;
if (factory->EnumAdapters1 (i, dxgiAdapter.resetAndGetPointerAddress()) == DXGI_ERROR_NOT_FOUND)
break;
const auto adapter = adapterArray.add (new DxgiAdapter { d2dFactory, dxgiAdapter });
listeners.call ([adapter] (DxgiAdapterListener& l) { l.adapterCreated (adapter); });
}
}
void releaseAdapters()
{
for (const auto& adapter : adapterArray)
listeners.call ([adapter] (DxgiAdapterListener& l) { l.adapterRemoved (adapter); });
adapterArray.clear();
}
const auto& getAdapterArray() const
{
return adapterArray;
}
auto getFactory() const
{
return factory;
}
DxgiAdapter::Ptr getAdapterForHwnd (HWND hwnd) const
{
const auto monitor = MonitorFromWindow (hwnd, MONITOR_DEFAULTTONULL);
if (monitor == nullptr)
return getDefaultAdapter();
for (auto& adapter : adapterArray)
{
for (const auto& dxgiOutput : adapter->dxgiOutputs)
{
DXGI_OUTPUT_DESC desc{};
if (FAILED (dxgiOutput->GetDesc (&desc)))
continue;
if (desc.Monitor == monitor)
return adapter;
}
}
return getDefaultAdapter();
}
DxgiAdapter::Ptr getDefaultAdapter() const
{
return adapterArray.getFirst();
}
void addListener (DxgiAdapterListener& l)
{
listeners.add (&l);
}
void removeListener (DxgiAdapterListener& l)
{
listeners.remove (&l);
}
private:
static ComSmartPtr<IDXGIFactory2> makeDxgiFactory()
{
JUCE_BEGIN_IGNORE_WARNINGS_GCC_LIKE ("-Wlanguage-extension-token")
ComSmartPtr<IDXGIFactory2> result;
if (const auto hr = CreateDXGIFactory2 (0, __uuidof (IDXGIFactory2), (void**) result.resetAndGetPointerAddress()); SUCCEEDED (hr))
return result;
JUCE_END_IGNORE_WARNINGS_GCC_LIKE
// If CreateDXGIFactory fails, check to see if this is being called in the context of DllMain.
// CreateDXGIFactory will always fail if called from the context of DllMain. In this case, the renderer
// will create a software image instead as a fallback, but that won't perform as well.
//
// You may be creating an Image as a static object, which will likely be created in the context of DllMain.
// Consider deferring your Image creation until later.
jassertfalse;
return {};
}
ComSmartPtr<ID2D1Factory2> d2dFactory;
ListenerList<DxgiAdapterListener> listeners;
ComSmartPtr<IDXGIFactory2> factory = makeDxgiFactory();
ReferenceCountedArray<DxgiAdapter> adapterArray;
};
class DirectX
{
public:
DirectX() = default;
auto getD2DFactory() const { return d2dSharedFactory; }
auto getD2DMultithread() const { return multithread; }
private:
ComSmartPtr<ID2D1Factory2> d2dSharedFactory = [&]
{
D2D1_FACTORY_OPTIONS options;
options.debugLevel = D2D1_DEBUG_LEVEL_NONE;
JUCE_BEGIN_IGNORE_WARNINGS_GCC_LIKE ("-Wlanguage-extension-token")
ComSmartPtr<ID2D1Factory2> result;
auto hr = D2D1CreateFactory (D2D1_FACTORY_TYPE_MULTI_THREADED,
__uuidof (ID2D1Factory2),
&options,
(void**) result.resetAndGetPointerAddress());
jassertquiet (SUCCEEDED (hr));
JUCE_END_IGNORE_WARNINGS_GCC_LIKE
return result;
}();
ComSmartPtr<ID2D1Multithread> multithread = [&]
{
ComSmartPtr<ID2D1Multithread> result;
d2dSharedFactory->QueryInterface<ID2D1Multithread> (result.resetAndGetPointerAddress());
return result;
}();
public:
DxgiAdapters adapters { d2dSharedFactory };
private:
JUCE_DECLARE_NON_COPYABLE_WITH_LEAK_DETECTOR (DirectX)
};
struct D2DUtilities
{
template <typename Type>
static D2D1_RECT_F toRECT_F (const Rectangle<Type>& r)
{
return { (float) r.getX(), (float) r.getY(), (float) r.getRight(), (float) r.getBottom() };
}
template <typename Type>
static D2D1_RECT_U toRECT_U (const Rectangle<Type>& r)
{
return { (UINT32) r.getX(), (UINT32) r.getY(), (UINT32) r.getRight(), (UINT32) r.getBottom() };
}
template <typename Type>
static RECT toRECT (const Rectangle<Type>& r)
{
return { r.getX(), r.getY(), r.getRight(), r.getBottom() };
}
static Rectangle<int> toRectangle (const RECT& r)
{
return Rectangle<int>::leftTopRightBottom (r.left, r.top, r.right, r.bottom);
}
static Point<int> toPoint (POINT p) noexcept { return { p.x, p.y }; }
static POINT toPOINT (Point<int> p) noexcept { return { p.x, p.y }; }
static D2D1_COLOR_F toCOLOR_F (Colour c)
{
return { c.getFloatRed(), c.getFloatGreen(), c.getFloatBlue(), c.getFloatAlpha() };
}
static D2D1::Matrix3x2F transformToMatrix (const AffineTransform& transform)
{
return { transform.mat00, transform.mat10, transform.mat01, transform.mat11, transform.mat02, transform.mat12 };
}
};
} // namespace juce

View file

@ -0,0 +1,310 @@
/*
==============================================================================
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.
==============================================================================
*/
#pragma once
namespace juce::etw
{
//==============================================================================
/*
The following XML can be passed to Windows Performance Recorder (WPR) to enable tracing from
JUCE projects.
- Save the XML into a file with the name JUCE.wprp
- Run the following command from an admin command prompt to start capture. If you use a Developer
Command Prompt, wpr.exe should be found on the PATH already.
- <path to wpr>\wpr.exe -start JUCE.wprp
- Start your JUCE project
- Run the following command from an admin command prompt to stop capture
- <path to wpr>\wpr.exe -stop TraceCaptureFile.etl description
<?xml version="1.0" encoding="utf-8"?>
<WindowsPerformanceRecorder Version="1.0" Author="Microsoft Corporation" Copyright="Microsoft Corporation" Company="Microsoft Corporation">
<Profiles>
<EventCollector Id="EventCollector_JUCETraceLogProvider" Name="JUCETraceLogProvider">
<BufferSize Value="64" />
<Buffers Value="4" />
</EventCollector>
<EventProvider Id="EventProvider_JUCETraceLogProvider" Name="6A612E78-284D-4DDB-877A-5F521EB33132" />
<Profile Id="JUCETraceLogProvider.Verbose.File" Name="JUCETraceLogProvider" Description="JUCETraceLogProvider" LoggingMode="File" DetailLevel="Verbose">
<Collectors>
<EventCollectorId Value="EventCollector_JUCETraceLogProvider">
<EventProviders>
<EventProviderId Value="EventProvider_JUCETraceLogProvider" />
</EventProviders>
</EventCollectorId>
</Collectors>
</Profile>
<Profile Id="JUCETraceLogProvider.Light.File" Name="JUCETraceLogProvider" Description="JUCETraceLogProvider" Base="JUCETraceLogProvider.Verbose.File" LoggingMode="File" DetailLevel="Light" />
<Profile Id="JUCETraceLogProvider.Verbose.Memory" Name="JUCETraceLogProvider" Description="JUCETraceLogProvider" Base="JUCETraceLogProvider.Verbose.File" LoggingMode="Memory" DetailLevel="Verbose" />
<Profile Id="JUCETraceLogProvider.Light.Memory" Name="JUCETraceLogProvider" Description="JUCETraceLogProvider" Base="JUCETraceLogProvider.Verbose.File" LoggingMode="Memory" DetailLevel="Light" />
</Profiles>
</WindowsPerformanceRecorder>
*/
//==============================================================================
enum
{
paintKeyword = 1 << 0,
sizeKeyword = 1 << 1,
graphicsKeyword = 1 << 2,
crucialKeyword = 1 << 3,
threadPaintKeyword = 1 << 4,
messageKeyword = 1 << 5,
direct2dKeyword = 1 << 6,
softwareRendererKeyword = 1 << 7,
resourcesKeyword = 1 << 8,
componentKeyword = 1 << 9,
spriteKeyword = 1 << 10
};
enum : uint64_t
{
direct2dHwndPaintStart,
direct2dHwndPaintEnd,
endDraw,
present1SwapChainStart,
present1SwapChainEnd,
swapChainThreadEvent,
waitForVBlankDone,
callVBlankListeners,
resize,
createResource,
presentIdleFrame,
direct2dImagePaintStart,
direct2dImagePaintEnd,
startD2DFrame,
flush,
startGDIFrame,
startGDIImage,
endGDIFrame,
createLowLevelGraphicsContext,
createDeviceResources,
createSwapChain,
createSwapChainBuffer,
createPeer,
mapBitmap,
unmapBitmap,
createDirect2DBitmapFromImage,
createDirect2DBitmap,
setOrigin,
addTransform,
clipToRectangle,
clipToRectangleList,
excludeClipRectangle,
clipToPath,
clipToImageAlpha,
saveState,
restoreState,
beginTransparencyLayer,
endTransparencyLayer,
setFill,
setOpacity,
setInterpolationQuality,
fillRect,
fillRectReplace,
fillRectList,
drawRectTranslated,
drawRectTransformed,
drawRect,
fillPath,
strokePath,
drawPath,
drawImage,
drawLine,
setFont,
drawGlyph,
drawGlyphRun,
drawTextLayout,
drawRoundedRectangle,
fillRoundedRectangle,
drawEllipse,
fillEllipse,
filledGeometryRealizationCacheHit,
filledGeometryRealizationCreated,
strokedGeometryRealizationCacheHit,
strokedGeometryRealizationCreated,
releaseGeometryRealization,
gradientCacheHit,
gradientCreated,
releaseGradient,
nativeDropShadow,
nativeGlowEffect,
resetToDefaultState,
reduceClipRegionRectangle,
reduceClipRegionRectangleList,
reduceClipRegionImage,
reduceClipRegionPath,
excludeClipRegion,
fillAll,
repaint,
paintComponentAndChildren,
paintWithinParentContext,
createSpriteBatch,
setSprites,
addSprites,
drawSprites,
};
#if JUCE_WINDOWS && JUCE_ETW_TRACELOGGING
JUCE_BEGIN_IGNORE_WARNINGS_GCC_LIKE ("-Wc++98-compat-extra-semi", "-Wmissing-prototypes", "-Wgnu-zero-variadic-macro-arguments")
TRACELOGGING_DECLARE_PROVIDER (JUCETraceLogProvider);
JUCE_END_IGNORE_WARNINGS_GCC_LIKE
#define JUCE_WRITE_TRACE_LOG_VA(code, keyword, ...) \
TraceLoggingWrite (::juce::etw::JUCETraceLogProvider, \
#code, \
TraceLoggingLevel (TRACE_LEVEL_INFORMATION), \
TraceLoggingKeyword ((UINT64) keyword), \
__VA_ARGS__, \
TraceLoggingValue ((unsigned short) code, "code"))
#define JUCE_WRITE_TRACE_LOG(code, keyword) \
TraceLoggingWrite (::juce::etw::JUCETraceLogProvider, \
#code, \
TraceLoggingLevel (TRACE_LEVEL_INFORMATION), \
TraceLoggingKeyword ((UINT64) keyword), \
TraceLoggingValue ((unsigned short) code, "code"))
#else
#define JUCE_WRITE_TRACE_LOG_VA(code, keyword, ...)
#define JUCE_WRITE_TRACE_LOG(code, keyword)
#endif
template <typename Number>
auto toVector (const Rectangle<Number>& r)
{
return std::vector { r.getX(), r.getY(), r.getWidth(), r.getHeight() };
}
template <typename Number>
auto toVector (const RectangleList<Number>& list)
{
std::vector<Number> result;
for (const auto& r : list)
result.insert (result.end(), { r.getX(), r.getY(), r.getWidth(), r.getHeight() });
return result;
}
//==============================================================================
#if JUCE_WINDOWS && JUCE_ETW_TRACELOGGING
#define JUCE_SCOPED_TRACE_EVENT_FRAME(code, keyword, frameNumber) \
const ScopeGuard scopedEvent_ ## __LINE__ { [start = ::juce::Time::getHighResolutionTicks(), frame = (frameNumber)] \
{ \
const auto ticks = ::juce::Time::getHighResolutionTicks() - start; \
JUCE_WRITE_TRACE_LOG_VA (code, keyword, TraceLoggingValue (ticks), TraceLoggingValue (frame)); \
} };
#define JUCE_SCOPED_TRACE_EVENT_FRAME_RECT_F32(code, keyword, frameNumber, rectIn) \
const ScopeGuard scopedEvent_ ## __LINE__ { [start = ::juce::Time::getHighResolutionTicks(), frame = (frameNumber), rect = (rectIn)] \
{ \
const auto ticks = ::juce::Time::getHighResolutionTicks() - start; \
const std::vector<float> vec = ::juce::etw::toVector (rect); \
JUCE_WRITE_TRACE_LOG_VA (code, \
keyword, \
TraceLoggingValue (ticks), \
TraceLoggingValue (frame), \
TraceLoggingFloat32Array (vec.data(), (UINT16) vec.size(), "rect")); \
} };
#define JUCE_SCOPED_TRACE_EVENT_FRAME_RECT_I32(code, keyword, frameNumber, rectIn) \
const ScopeGuard scopedEvent_ ## __LINE__ { [start = ::juce::Time::getHighResolutionTicks(), frame = (frameNumber), rect = (rectIn)] \
{ \
const auto ticks = ::juce::Time::getHighResolutionTicks() - start; \
const std::vector<INT32> vec = ::juce::etw::toVector (rect); \
JUCE_WRITE_TRACE_LOG_VA (code, \
keyword, \
TraceLoggingValue (ticks), \
TraceLoggingValue (frame), \
TraceLoggingInt32Array (vec.data(), (UINT16) vec.size(), "rect")); \
} };
#else
#define JUCE_SCOPED_TRACE_EVENT_FRAME(code, keyword, frameNumber)
#define JUCE_SCOPED_TRACE_EVENT_FRAME_RECT_F32(code, keyword, frameNumber, rectIn)
#define JUCE_SCOPED_TRACE_EVENT_FRAME_RECT_I32(code, keyword, frameNumber, rectIn)
#endif
//==============================================================================
#define JUCE_TRACE_LOG_D2D_PAINT_CALL(code, frameNumber) \
JUCE_WRITE_TRACE_LOG_VA (code, etw::paintKeyword | etw::direct2dKeyword, TraceLoggingValue ((UINT64) frameNumber, "frame"))
#define JUCE_TRACE_LOG_JUCE_VBLANK_THREAD_EVENT \
JUCE_WRITE_TRACE_LOG (etw::waitForVBlankDone, etw::softwareRendererKeyword)
#define JUCE_TRACE_LOG_JUCE_VBLANK_CALL_LISTENERS \
JUCE_WRITE_TRACE_LOG (etw::callVBlankListeners, etw::softwareRendererKeyword)
#define JUCE_TRACE_LOG_D2D_RESIZE(message) \
JUCE_WRITE_TRACE_LOG_VA (etw::resize, etw::paintKeyword | etw::direct2dKeyword, TraceLoggingValue (message, "message"))
#define JUCE_TRACE_LOG_D2D_IMAGE_MAP_DATA \
JUCE_WRITE_TRACE_LOG (etw::mapBitmap, etw::direct2dKeyword)
#define JUCE_TRACE_LOG_D2D_IMAGE_UNMAP_DATA \
JUCE_WRITE_TRACE_LOG (etw::unmapBitmap, etw::direct2dKeyword)
#define JUCE_TRACE_LOG_PAINT_COMPONENT_AND_CHILDREN(depth) \
JUCE_WRITE_TRACE_LOG_VA (etw::paintComponentAndChildren, etw::paintKeyword, TraceLoggingValue (depth, "depth"))
#define JUCE_TRACE_LOG_PAINT_CALL(code, frameNumber) \
JUCE_WRITE_TRACE_LOG_VA (code, etw::softwareRendererKeyword, TraceLoggingValue ((UINT64) frameNumber, "frame"))
#if JUCE_ETW_TRACELOGGING
#define JUCE_TRACE_EVENT_INT_RECT_LIST(code, keyword, frameNumber, rect) \
{ \
const std::vector<INT32> vec = ::juce::etw::toVector (rect); \
JUCE_WRITE_TRACE_LOG (code, \
etw::softwareRendererKeyword, \
TraceLoggingValue ((UINT64) frameNumber, "frame"), \
TraceLoggingInt32Array (vec.data(), (UINT16) vec.size(), "rect")); \
}
#define JUCE_TRACE_EVENT_INT_RECT(code, keyword, rect) \
{ \
const std::vector<INT32> vec = ::juce::etw::toVector (rect); \
JUCE_WRITE_TRACE_LOG (code, \
etw::softwareRendererKeyword, \
TraceLoggingInt32Array (vec.data(), (UINT16) vec.size(), "rect")); \
}
#else
#define JUCE_TRACE_EVENT_INT_RECT_LIST(code, keyword, frameNumber, rect)
#define JUCE_TRACE_EVENT_INT_RECT(code, keyword, rect)
#endif
} // namespace juce::etw

View file

@ -131,18 +131,35 @@ public:
return r + offset.toFloat();
}
template <typename RectangleOrPoint>
RectangleOrPoint transformed (RectangleOrPoint r) const noexcept
auto boundsAfterTransform (Rectangle<float> r) const noexcept
{
jassert (! isOnlyTranslated);
return r.transformedBy (complexTransform);
}
template <typename Type>
Rectangle<Type> deviceSpaceToUserSpace (Rectangle<Type> r) const noexcept
auto transformed (Point<float> r) const noexcept
{
return isOnlyTranslated ? r - offset
: r.transformedBy (complexTransform.inverted());
jassert (! isOnlyTranslated);
return r.transformedBy (complexTransform);
}
auto boundsAfterTransform (const RectangleList<float>& r) const noexcept
{
jassert (! isOnlyTranslated);
return boundsAfterTransform (r.getBounds());
}
auto boundsAfterTransform (Line<float> r) const noexcept
{
jassert (! isOnlyTranslated);
return Line { transformed (r.getStart()), transformed (r.getEnd()) };
}
template <typename Type>
Rectangle<float> deviceSpaceToUserSpace (Rectangle<Type> r) const noexcept
{
return isOnlyTranslated ? r.toFloat() - offset.toFloat()
: r.toFloat().transformedBy (complexTransform.inverted());
}
AffineTransform complexTransform;
@ -2007,11 +2024,6 @@ public:
cloneClipIfMultiplyReferenced();
clip = clip->clipToRectangle (transform.translated (r));
}
else if (! transform.isRotated)
{
cloneClipIfMultiplyReferenced();
clip = clip->clipToRectangle (transform.transformed (r));
}
else
{
Path p;
@ -2042,16 +2054,6 @@ public:
clip = clip->clipToRectangleList (offsetList);
}
}
else if (! transform.isRotated)
{
cloneClipIfMultiplyReferenced();
RectangleList<int> scaledList;
for (auto& i : r)
scaledList.add (transform.transformed (i));
clip = clip->clipToRectangleList (scaledList);
}
else
{
clipToPath (r.toPath(), {});
@ -2083,7 +2085,7 @@ public:
}
else if (! transform.isRotated)
{
clip = clip->excludeClipRectangle (getLargestIntegerWithin (transform.transformed (r.toFloat())));
clip = clip->excludeClipRectangle (getLargestIntegerWithin (transform.boundsAfterTransform (r.toFloat())));
}
else
{
@ -2141,7 +2143,7 @@ public:
Rectangle<int> getClipBounds() const
{
return clip != nullptr ? transform.deviceSpaceToUserSpace (clip->getClipBounds())
return clip != nullptr ? transform.deviceSpaceToUserSpace (clip->getClipBounds()).getSmallestIntegerContainer()
: Rectangle<int>();
}
@ -2198,11 +2200,12 @@ public:
}
else if (! transform.isRotated)
{
fillTargetRect (transform.transformed (r), replaceContents);
jassert (! replaceContents); // not implemented
fillTargetRect (transform.boundsAfterTransform (r.toFloat()));
}
else
{
jassert (! replaceContents); // not implemented..
jassert (! replaceContents); // not implemented
fillRectAsPath (r);
}
}
@ -2215,7 +2218,7 @@ public:
if (transform.isOnlyTranslated)
fillTargetRect (transform.translated (r));
else if (! transform.isRotated)
fillTargetRect (transform.transformed (r));
fillTargetRect (transform.boundsAfterTransform (r));
else
fillRectAsPath (r);
}
@ -2575,13 +2578,18 @@ template <class SavedStateType>
class StackBasedLowLevelGraphicsContext : public LowLevelGraphicsContext
{
public:
explicit StackBasedLowLevelGraphicsContext (uint64_t frameIn)
: frame (frameIn)
{
}
bool isVectorDevice() const override { return false; }
Rectangle<int> getClipBounds() const override { return stack->getClipBounds(); }
bool isClipEmpty() const override { return stack->clip == nullptr; }
void setOrigin (Point<int> o) override { stack->transform.setOrigin (o); }
void addTransform (const AffineTransform& t) override { stack->transform.addTransform (t); }
float getPhysicalPixelScaleFactor() override { return stack->transform.getPhysicalPixelScaleFactor(); }
float getPhysicalPixelScaleFactor() const override { return stack->transform.getPhysicalPixelScaleFactor(); }
bool clipRegionIntersects (const Rectangle<int>& r) override { return stack->clipRegionIntersects (r); }
bool clipToRectangle (const Rectangle<int>& r) override { return stack->clipToRectangle (r); }
bool clipToRectangleList (const RectangleList<int>& r) override { return stack->clipToRectangleList (r); }
@ -2603,6 +2611,7 @@ public:
void drawLine (const Line<float>& line) override { stack->drawLine (line); }
void setFont (const Font& newFont) override { stack->font = newFont; }
const Font& getFont() override { return stack->font; }
uint64_t getFrameId() const override { return frame; }
void drawGlyphs (Span<const uint16_t> glyphs,
Span<const Point<float>> positions,
@ -2627,7 +2636,7 @@ protected:
auto& cache = RenderingHelpers::GlyphCache::getInstance();
const Point pos (t.getTranslationX(), t.getTranslationY());
if (stack->transform.isOnlyTranslated)
if (this->stack->transform.isOnlyTranslated)
{
const auto drawPos = pos + stack->transform.offset.toFloat();
return std::tuple (cache.get (stack->font, i), drawPos);
@ -2653,7 +2662,7 @@ protected:
}();
const auto initialFill = stack->fillType;
const ScopeGuard scope { [&] { stack->setFillType (initialFill); } };
const ScopeGuard scope { [&] { this->stack->setFillType (initialFill); } };
for (const auto& layer : layers)
{
@ -2683,6 +2692,7 @@ protected:
StackBasedLowLevelGraphicsContext() = default;
RenderingHelpers::SavedStateStack<SavedStateType> stack;
uint64_t frame = 0;
};
JUCE_END_IGNORE_WARNINGS_MSVC

View file

@ -505,67 +505,6 @@ bool Component::isOpaque() const noexcept
}
//==============================================================================
struct StandardCachedComponentImage final : public CachedComponentImage
{
StandardCachedComponentImage (Component& c) noexcept : owner (c) {}
void paint (Graphics& g) override
{
scale = g.getInternalContext().getPhysicalPixelScaleFactor();
auto compBounds = owner.getLocalBounds();
auto imageBounds = compBounds * scale;
if (image.isNull() || image.getBounds() != imageBounds)
{
image = Image (owner.isOpaque() ? Image::RGB
: Image::ARGB,
jmax (1, imageBounds.getWidth()),
jmax (1, imageBounds.getHeight()),
! owner.isOpaque());
validArea.clear();
}
if (! validArea.containsRectangle (compBounds))
{
Graphics imG (image);
auto& lg = imG.getInternalContext();
lg.addTransform (AffineTransform::scale (scale));
for (auto& i : validArea)
lg.excludeClipRectangle (i);
if (! owner.isOpaque())
{
lg.setFill (Colours::transparentBlack);
lg.fillRect (compBounds, true);
lg.setFill (Colours::black);
}
owner.paintEntireComponent (imG, true);
}
validArea = compBounds;
g.setColour (Colours::black.withAlpha (owner.getAlpha()));
g.drawImageTransformed (image, AffineTransform::scale ((float) compBounds.getWidth() / (float) imageBounds.getWidth(),
(float) compBounds.getHeight() / (float) imageBounds.getHeight()), false);
}
bool invalidateAll() override { validArea.clear(); return true; }
bool invalidate (const Rectangle<int>& area) override { validArea.subtract (area); return true; }
void releaseResources() override { image = Image(); }
private:
Image image;
RectangleList<int> validArea;
Component& owner;
float scale = 1.0f;
JUCE_DECLARE_NON_COPYABLE_WITH_LEAK_DETECTOR (StandardCachedComponentImage)
};
void Component::setCachedComponentImage (CachedComponentImage* newCachedImage)
{
if (cachedImage.get() != newCachedImage)
@ -581,12 +520,12 @@ void Component::setBufferedToImage (bool shouldBeBuffered)
// so by calling setBufferedToImage, you'll be deleting the custom one - this is almost certainly
// not what you wanted to happen... If you really do know what you're doing here, and want to
// avoid this assertion, just call setCachedComponentImage (nullptr) before setBufferedToImage().
jassert (cachedImage == nullptr || dynamic_cast<StandardCachedComponentImage*> (cachedImage.get()) != nullptr);
jassert (cachedImage == nullptr || dynamic_cast<detail::StandardCachedComponentImage*> (cachedImage.get()) != nullptr);
if (shouldBeBuffered)
{
if (cachedImage == nullptr)
cachedImage.reset (new StandardCachedComponentImage (*this));
cachedImage = std::make_unique<detail::StandardCachedComponentImage> (*this);
}
else
{
@ -1673,6 +1612,20 @@ void Component::paintWithinParentContext (Graphics& g)
void Component::paintComponentAndChildren (Graphics& g)
{
#if JUCE_ETW_TRACELOGGING
{
int depth = 0;
auto parent = getParentComponent();
while (parent)
{
parent = parent->getParentComponent();
depth++;
}
JUCE_TRACE_LOG_PAINT_COMPONENT_AND_CHILDREN (depth);
}
#endif
auto clipBounds = g.getClipBounds();
if (flags.dontClipGraphicsFlag && getNumChildComponents() == 0)
@ -1756,12 +1709,25 @@ void Component::paintEntireComponent (Graphics& g, bool ignoreAlphaLevel)
auto scaledBounds = getLocalBounds() * scale;
Image effectImage (flags.opaqueFlag ? Image::RGB : Image::ARGB,
scaledBounds.getWidth(), scaledBounds.getHeight(), ! flags.opaqueFlag);
// Store the effect image in the image cache to avoid recreating it every time
auto imageFormat = flags.opaqueFlag ? Image::RGB : Image::ARGB;
int64 imageHashCode = scaledBounds.getWidth() | ((int64) scaledBounds.getHeight() << 24) | ((int64) imageFormat << 56);
auto effectImage = ImageCache::getFromHashCode (imageHashCode);
if (effectImage.isNull())
{
effectImage = Image { imageFormat, scaledBounds.getWidth(), scaledBounds.getHeight(), ! flags.opaqueFlag };
ImageCache::addImageToCache (effectImage, imageHashCode);
}
effectImage.clear (effectImage.getBounds(), (imageFormat == Image::ARGB) ? Colours::transparentBlack : Colours::black);
{
Graphics g2 (effectImage);
g2.addTransform (AffineTransform::scale ((float) scaledBounds.getWidth() / (float) getWidth(),
(float) scaledBounds.getHeight() / (float) getHeight()));
paintComponentAndChildren (g2);
}

View file

@ -0,0 +1,129 @@
/*
==============================================================================
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::detail
{
struct StandardCachedComponentImage : public CachedComponentImage
{
explicit StandardCachedComponentImage (Component& c) noexcept
: owner (c)
{
}
void paint (Graphics& g) override
{
scale = g.getInternalContext().getPhysicalPixelScaleFactor();
auto compBounds = owner.getLocalBounds();
auto imageBounds = compBounds * scale;
if (image.isNull() || image.getBounds() != imageBounds)
{
#if JUCE_WINDOWS
auto imageType = SoftwareImageType {};
#else
auto imageType = NativeImageType {};
#endif
image = Image (owner.isOpaque() ? Image::RGB
: Image::ARGB,
jmax (1, imageBounds.getWidth()),
jmax (1, imageBounds.getHeight()),
! owner.isOpaque(),
imageType);
validArea.clear();
}
paintImage (compBounds, AffineTransform::scale (scale));
validArea = compBounds;
g.setColour (Colours::black.withAlpha (owner.getAlpha()));
g.drawImageTransformed (image,
AffineTransform::scale ((float) compBounds.getWidth() / (float) imageBounds.getWidth(),
(float) compBounds.getHeight() / (float) imageBounds.getHeight()),
false);
}
void paintImage (Rectangle<int> compBounds, AffineTransform transform)
{
if (! validArea.containsRectangle (compBounds))
{
Graphics imG (image);
auto& lg = imG.getInternalContext();
lg.addTransform (transform);
for (auto& i : validArea)
lg.excludeClipRectangle (i);
if (! owner.isOpaque())
{
lg.setFill (Colours::transparentBlack);
lg.fillRect (compBounds, true);
lg.setFill (Colours::black);
}
owner.paintEntireComponent (imG, true);
}
}
bool invalidateAll() override
{
validArea.clear();
return true;
}
bool invalidate (const Rectangle<int>& area) override
{
validArea.subtract (area);
return true;
}
void releaseResources() override
{
image = Image();
}
protected:
Image image;
RectangleList<int> validArea;
Component& owner;
float scale = 1.0f;
JUCE_DECLARE_NON_COPYABLE_WITH_LEAK_DETECTOR (StandardCachedComponentImage)
};
} // namespace juce::detail

View file

@ -80,12 +80,19 @@
//==============================================================================
#elif JUCE_WINDOWS
#include <windowsx.h>
#include <vfw.h>
#include <commdlg.h>
#include <commctrl.h>
#include <commdlg.h>
#include <d2d1_3.h>
#include <d3d11_2.h>
#include <dxgi1_3.h>
#include <sapi.h>
#include <dxgi.h>
#include <vfw.h>
#include <windowsx.h>
#if JUCE_ETW_TRACELOGGING
#include <TraceLoggingProvider.h>
#include <evntrace.h>
#endif
#if JUCE_MINGW
// Some MinGW headers use 'new' as a parameter name
@ -109,21 +116,18 @@
#pragma comment(lib, "vfw32.lib")
#pragma comment(lib, "imm32.lib")
#pragma comment(lib, "comctl32.lib")
#pragma comment(lib, "dxgi.lib")
#if JUCE_OPENGL
#pragma comment(lib, "OpenGL32.Lib")
#pragma comment(lib, "GlU32.Lib")
#endif
#if JUCE_DIRECT2D
#pragma comment (lib, "Dwrite.lib")
#pragma comment (lib, "D2d1.lib")
#endif
#endif
#endif
//==============================================================================
#include <juce_graphics/native/juce_EventTracing.h>
#include "detail/juce_AccessibilityHelpers.h"
#include "detail/juce_ButtonAccessibilityHandler.h"
#include "detail/juce_ScalingHelpers.h"
@ -144,6 +148,7 @@
#include "detail/juce_WindowingHelpers.h"
#include "detail/juce_AlertWindowHelpers.h"
#include "detail/juce_TopLevelWindowManager.h"
#include "detail/juce_StandardCachedComponentImage.h"
//==============================================================================
#if JUCE_IOS || JUCE_WINDOWS
@ -185,9 +190,8 @@
#include "native/juce_MouseCursor_mac.mm"
#elif JUCE_WINDOWS
#if JUCE_MODULE_AVAILABLE_juce_audio_plugin_client
#include <juce_audio_plugin_client/AAX/juce_AAX_Modifier_Injector.h>
#endif
#include <juce_graphics/native/juce_DirectX_windows.h>
#include "native/accessibility/juce_ComInterfaces_windows.h"
#include "native/accessibility/juce_WindowsUIAWrapper_windows.h"
#include "native/accessibility/juce_AccessibilityElement_windows.h"

View file

@ -454,24 +454,28 @@ void DragAndDropContainer::startDragging (const var& sourceDescription,
const auto clipped = (image.getBounds().toDouble() / scaleFactor).getConstrainedPoint (relPos);
Image fade (Image::SingleChannel, image.getWidth(), image.getHeight(), true);
Graphics fadeContext (fade);
{
Graphics fadeContext (fade);
ColourGradient gradient;
gradient.isRadial = true;
gradient.point1 = clipped.toFloat() * scaleFactor;
gradient.point2 = gradient.point1 + Point<float> (0.0f, scaleFactor * 400.0f);
gradient.addColour (0.0, Colours::white);
gradient.addColour (0.375, Colours::white);
gradient.addColour (1.0, Colours::transparentWhite);
ColourGradient gradient;
gradient.isRadial = true;
gradient.point1 = clipped.toFloat() * scaleFactor;
gradient.point2 = gradient.point1 + Point<float> (0.0f, scaleFactor * 400.0f);
gradient.addColour (0.0, Colours::white);
gradient.addColour (0.375, Colours::white);
gradient.addColour (1.0, Colours::transparentWhite);
fadeContext.setGradientFill (gradient);
fadeContext.fillAll();
fadeContext.setGradientFill (gradient);
fadeContext.fillAll();
}
Image composite (Image::ARGB, image.getWidth(), image.getHeight(), true);
Graphics compositeContext (composite);
{
Graphics compositeContext (composite);
compositeContext.reduceClipRegion (fade, {});
compositeContext.drawImageAt (image, 0, 0);
compositeContext.reduceClipRegion (fade, {});
compositeContext.drawImageAt (image, 0, 0);
}
return { ScaledImage (composite, scaleFactor), clipped };
}();

View file

@ -105,7 +105,6 @@ public:
[&listener] (const auto& l) { return &(l.get()) == &listener; });
}
//==============================================================================
static HMONITOR getMonitorFromOutput (ComSmartPtr<IDXGIOutput> output)
{
DXGI_OUTPUT_DESC desc = {};
@ -219,12 +218,13 @@ public:
if (threadWithListener != threads.end())
removeListener (threadWithListener, listener);
for (auto adapter : adapters)
SharedResourcePointer<DirectX> directX;
for (const auto& adapter : directX->adapters.getAdapterArray())
{
UINT i = 0;
ComSmartPtr<IDXGIOutput> output;
while (adapter->EnumOutputs (i, output.resetAndGetPointerAddress()) != DXGI_ERROR_NOT_FOUND)
while (adapter->dxgiAdapter->EnumOutputs (i, output.resetAndGetPointerAddress()) != DXGI_ERROR_NOT_FOUND)
{
if (VBlankThread::getMonitorFromOutput (output) == monitor)
{
@ -246,21 +246,8 @@ public:
void reconfigureDisplays()
{
adapters.clear();
ComSmartPtr<IDXGIFactory> factory;
JUCE_BEGIN_IGNORE_WARNINGS_GCC_LIKE ("-Wlanguage-extension-token")
CreateDXGIFactory (__uuidof (IDXGIFactory), (void**)factory.resetAndGetPointerAddress());
JUCE_END_IGNORE_WARNINGS_GCC_LIKE
UINT i = 0;
ComSmartPtr<IDXGIAdapter> adapter;
while (factory->EnumAdapters (i, adapter.resetAndGetPointerAddress()) != DXGI_ERROR_NOT_FOUND)
{
adapters.push_back (adapter);
++i;
}
SharedResourcePointer<DirectX> directX;
directX->adapters.updateAdapters();
for (auto& thread : threads)
thread->updateMonitor();
@ -304,7 +291,6 @@ private:
}
//==============================================================================
std::vector<ComSmartPtr<IDXGIAdapter>> adapters;
Threads threads;
JUCE_DECLARE_NON_COPYABLE_WITH_LEAK_DETECTOR (VBlankDispatcher)

File diff suppressed because it is too large Load diff

View file

@ -168,6 +168,8 @@ void ComponentPeer::handlePaint (LowLevelGraphicsContext& contextToPaintTo)
mess up a lot of the calculations that the library needs to do.
*/
jassert (roundToInt (10.1f) == 10);
++peerFrameNumber;
}
Component* ComponentPeer::getTargetForKeyPress()

View file

@ -322,7 +322,10 @@ public:
virtual void handleScreenSizeChange();
//==============================================================================
/** This is called to repaint the component into the given context. */
/** This is called to repaint the component into the given context.
Increments the result of getNumFramesPainted().
*/
void handlePaint (LowLevelGraphicsContext& contextToPaintTo);
//==============================================================================
@ -561,6 +564,13 @@ public:
/** Returns the style requested for this app. */
Style getAppStyle() const { return style; }
/** Returns the number of times that this peer has been painted.
This is mainly useful when debugging component painting. For example, you might use this to
match logging calls to specific frames.
*/
uint64_t getNumFramesPainted() const { return peerFrameNumber; }
protected:
//==============================================================================
static void forceDisplayUpdate();
@ -603,6 +613,7 @@ private:
Component* lastDragAndDropCompUnderMouse = nullptr;
TextInputTarget* textInputTarget = nullptr;
const uint32 uniqueID;
uint64_t peerFrameNumber = 0;
bool isWindowMinimised = false;
//==============================================================================

View file

@ -67,6 +67,8 @@ public:
ScopedThreadDPIAwarenessSetter threadDpiAwarenessSetter { hwnd };
SetWindowPos (hwnd, nullptr, area.getX(), area.getY(), area.getWidth(), area.getHeight(), flagsToSend);
invalidateHWNDAndChildren();
}
}
@ -89,7 +91,7 @@ public:
ShowWindow (hwnd, isShowing ? SW_SHOWNA : SW_HIDE);
if (isShowing)
InvalidateRect (hwnd, nullptr, 0);
InvalidateRect (hwnd, nullptr, TRUE);
}
void componentVisibilityChanged() override
@ -120,6 +122,17 @@ public:
return {};
}
void invalidateHWNDAndChildren()
{
EnumChildWindows (hwnd, invalidateHwndCallback, 0);
}
static BOOL WINAPI invalidateHwndCallback (HWND hwnd, LPARAM)
{
InvalidateRect (hwnd, nullptr, TRUE);
return TRUE;
}
HWND hwnd;
private:
@ -127,14 +140,14 @@ private:
{
if (currentPeer != nullptr)
{
auto windowFlags = GetWindowLongPtr (hwnd, -16);
auto windowFlags = GetWindowLongPtr (hwnd, GWL_STYLE);
using FlagType = decltype (windowFlags);
windowFlags &= ~(FlagType) WS_POPUP;
windowFlags |= (FlagType) WS_CHILD;
SetWindowLongPtr (hwnd, -16, windowFlags);
SetWindowLongPtr (hwnd, GWL_STYLE, windowFlags);
SetParent (hwnd, (HWND) currentPeer->getNativeHandle());
componentMovedOrResized (true, true);

View file

@ -35,7 +35,7 @@
namespace juce
{
extern ComponentPeer* createNonRepaintingEmbeddedWindowsPeer (Component&, void* parent);
extern ComponentPeer* createNonRepaintingEmbeddedWindowsPeer (Component&, Component* parent);
//==============================================================================
class OpenGLContext::NativeContext : private ComponentPeer::ScaleFactorListener
@ -295,7 +295,7 @@ private:
auto* parentHWND = topComp->getWindowHandle();
ScopedThreadDPIAwarenessSetter setter { parentHWND };
nativeWindow.reset (createNonRepaintingEmbeddedWindowsPeer (*dummyComponent, parentHWND));
nativeWindow.reset (createNonRepaintingEmbeddedWindowsPeer (*dummyComponent, topComp));
}
if (auto* peer = topComp->getPeer())