diff --git a/build/macosx/Juce.xcodeproj/project.pbxproj b/build/macosx/Juce.xcodeproj/project.pbxproj index 0d69db8fda..baf02d49b8 100644 --- a/build/macosx/Juce.xcodeproj/project.pbxproj +++ b/build/macosx/Juce.xcodeproj/project.pbxproj @@ -70,7 +70,6 @@ 84816E8D10809DCB008FEC33 /* juce_BlowFish.h in Headers */ = {isa = PBXBuildFile; fileRef = 84F1E942104036B3006A1807 /* juce_BlowFish.h */; }; 84816E8E10809DCB008FEC33 /* juce_BooleanPropertyComponent.h in Headers */ = {isa = PBXBuildFile; fileRef = 84F1EAE010403709006A1807 /* juce_BooleanPropertyComponent.h */; }; 84816E8F10809DCB008FEC33 /* juce_BorderSize.h in Headers */ = {isa = PBXBuildFile; fileRef = 84F1EB5A10403709006A1807 /* juce_BorderSize.h */; }; - 84816E9010809DCB008FEC33 /* juce_Brush.h in Headers */ = {isa = PBXBuildFile; fileRef = 84F1EB1C10403709006A1807 /* juce_Brush.h */; }; 84816E9110809DCB008FEC33 /* juce_BubbleComponent.h in Headers */ = {isa = PBXBuildFile; fileRef = 84F1EAF210403709006A1807 /* juce_BubbleComponent.h */; }; 84816E9210809DCB008FEC33 /* juce_BubbleMessageComponent.h in Headers */ = {isa = PBXBuildFile; fileRef = 84F1EAF410403709006A1807 /* juce_BubbleMessageComponent.h */; }; 84816E9310809DCB008FEC33 /* juce_BufferedInputStream.h in Headers */ = {isa = PBXBuildFile; fileRef = 84F1E99F104036D6006A1807 /* juce_BufferedInputStream.h */; }; @@ -143,7 +142,6 @@ 84816ED610809DCB008FEC33 /* juce_GIFLoader.h in Headers */ = {isa = PBXBuildFile; fileRef = 84F1EB7710403709006A1807 /* juce_GIFLoader.h */; }; 84816ED710809DCB008FEC33 /* juce_GlowEffect.h in Headers */ = {isa = PBXBuildFile; fileRef = 84F1EB4910403709006A1807 /* juce_GlowEffect.h */; }; 84816ED810809DCB008FEC33 /* juce_GlyphArrangement.h in Headers */ = {isa = PBXBuildFile; fileRef = 84F1EB5110403709006A1807 /* juce_GlyphArrangement.h */; }; - 84816ED910809DCB008FEC33 /* juce_GradientBrush.h in Headers */ = {isa = PBXBuildFile; fileRef = 84F1EB1E10403709006A1807 /* juce_GradientBrush.h */; }; 84816EDA10809DCB008FEC33 /* juce_Graphics.h in Headers */ = {isa = PBXBuildFile; fileRef = 84F1EB2F10403709006A1807 /* juce_Graphics.h */; }; 84816EDB10809DCB008FEC33 /* juce_GroupComponent.h in Headers */ = {isa = PBXBuildFile; fileRef = 84F1EAAB10403709006A1807 /* juce_GroupComponent.h */; }; 84816EDC10809DCB008FEC33 /* juce_GZIPCompressorOutputStream.h in Headers */ = {isa = PBXBuildFile; fileRef = 84F1E9A3104036D6006A1807 /* juce_GZIPCompressorOutputStream.h */; }; @@ -152,7 +150,6 @@ 84816EDF10809DCB008FEC33 /* juce_IIRFilter.h in Headers */ = {isa = PBXBuildFile; fileRef = 84F1E7B710403614006A1807 /* juce_IIRFilter.h */; }; 84816EE010809DCB008FEC33 /* juce_IIRFilterAudioSource.h in Headers */ = {isa = PBXBuildFile; fileRef = 84F1E79F10403614006A1807 /* juce_IIRFilterAudioSource.h */; }; 84816EE110809DCB008FEC33 /* juce_Image.h in Headers */ = {isa = PBXBuildFile; fileRef = 84F1EB6E10403709006A1807 /* juce_Image.h */; }; - 84816EE210809DCB008FEC33 /* juce_ImageBrush.h in Headers */ = {isa = PBXBuildFile; fileRef = 84F1EB2010403709006A1807 /* juce_ImageBrush.h */; }; 84816EE310809DCB008FEC33 /* juce_ImageButton.h in Headers */ = {isa = PBXBuildFile; fileRef = 84F1EA5710403709006A1807 /* juce_ImageButton.h */; }; 84816EE410809DCB008FEC33 /* juce_ImageCache.h in Headers */ = {isa = PBXBuildFile; fileRef = 84F1EB7010403709006A1807 /* juce_ImageCache.h */; }; 84816EE510809DCB008FEC33 /* juce_ImageConvolutionKernel.h in Headers */ = {isa = PBXBuildFile; fileRef = 84F1EB7210403709006A1807 /* juce_ImageConvolutionKernel.h */; }; @@ -275,7 +272,6 @@ 84816F5B10809DCB008FEC33 /* juce_SliderListener.h in Headers */ = {isa = PBXBuildFile; fileRef = 84F1EA6B10403709006A1807 /* juce_SliderListener.h */; }; 84816F5C10809DCB008FEC33 /* juce_SliderPropertyComponent.h in Headers */ = {isa = PBXBuildFile; fileRef = 84F1EAEA10403709006A1807 /* juce_SliderPropertyComponent.h */; }; 84816F5D10809DCB008FEC33 /* juce_Socket.h in Headers */ = {isa = PBXBuildFile; fileRef = 84F1E99A104036D6006A1807 /* juce_Socket.h */; }; - 84816F5E10809DCB008FEC33 /* juce_SolidColourBrush.h in Headers */ = {isa = PBXBuildFile; fileRef = 84F1EB2210403709006A1807 /* juce_SolidColourBrush.h */; }; 84816F5F10809DCB008FEC33 /* juce_SortedSet.h in Headers */ = {isa = PBXBuildFile; fileRef = 84F1E8DC10403671006A1807 /* juce_SortedSet.h */; }; 84816F6010809DCB008FEC33 /* juce_SparseSet.h in Headers */ = {isa = PBXBuildFile; fileRef = 84F1E8DD10403671006A1807 /* juce_SparseSet.h */; }; 84816F6110809DCB008FEC33 /* juce_SplashScreen.h in Headers */ = {isa = PBXBuildFile; fileRef = 84F1EB1210403709006A1807 /* juce_SplashScreen.h */; }; @@ -372,7 +368,6 @@ 84816FBC10809E00008FEC33 /* juce_BlowFish.cpp in Sources */ = {isa = PBXBuildFile; fileRef = 84F1E941104036B3006A1807 /* juce_BlowFish.cpp */; }; 84816FBD10809E00008FEC33 /* juce_BooleanPropertyComponent.cpp in Sources */ = {isa = PBXBuildFile; fileRef = 84F1EADF10403709006A1807 /* juce_BooleanPropertyComponent.cpp */; }; 84816FBE10809E00008FEC33 /* juce_BorderSize.cpp in Sources */ = {isa = PBXBuildFile; fileRef = 84F1EB5910403709006A1807 /* juce_BorderSize.cpp */; }; - 84816FBF10809E00008FEC33 /* juce_Brush.cpp in Sources */ = {isa = PBXBuildFile; fileRef = 84F1EB1B10403709006A1807 /* juce_Brush.cpp */; }; 84816FC010809E00008FEC33 /* juce_BubbleComponent.cpp in Sources */ = {isa = PBXBuildFile; fileRef = 84F1EAF110403709006A1807 /* juce_BubbleComponent.cpp */; }; 84816FC110809E00008FEC33 /* juce_BubbleMessageComponent.cpp in Sources */ = {isa = PBXBuildFile; fileRef = 84F1EAF310403709006A1807 /* juce_BubbleMessageComponent.cpp */; }; 84816FC210809E00008FEC33 /* juce_BufferedInputStream.cpp in Sources */ = {isa = PBXBuildFile; fileRef = 84F1E99E104036D6006A1807 /* juce_BufferedInputStream.cpp */; }; @@ -434,7 +429,6 @@ 84816FFA10809E00008FEC33 /* juce_GIFLoader.cpp in Sources */ = {isa = PBXBuildFile; fileRef = 84F1EB7610403709006A1807 /* juce_GIFLoader.cpp */; }; 84816FFB10809E00008FEC33 /* juce_GlowEffect.cpp in Sources */ = {isa = PBXBuildFile; fileRef = 84F1EB4810403709006A1807 /* juce_GlowEffect.cpp */; }; 84816FFC10809E00008FEC33 /* juce_GlyphArrangement.cpp in Sources */ = {isa = PBXBuildFile; fileRef = 84F1EB5010403709006A1807 /* juce_GlyphArrangement.cpp */; }; - 84816FFD10809E00008FEC33 /* juce_GradientBrush.cpp in Sources */ = {isa = PBXBuildFile; fileRef = 84F1EB1D10403709006A1807 /* juce_GradientBrush.cpp */; }; 84816FFE10809E00008FEC33 /* juce_Graphics.cpp in Sources */ = {isa = PBXBuildFile; fileRef = 84F1EB2E10403709006A1807 /* juce_Graphics.cpp */; }; 84816FFF10809E00008FEC33 /* juce_GroupComponent.cpp in Sources */ = {isa = PBXBuildFile; fileRef = 84F1EAAA10403709006A1807 /* juce_GroupComponent.cpp */; }; 8481700010809E00008FEC33 /* juce_GZIPCompressorOutputStream.cpp in Sources */ = {isa = PBXBuildFile; fileRef = 84F1E9A2104036D6006A1807 /* juce_GZIPCompressorOutputStream.cpp */; }; @@ -443,7 +437,6 @@ 8481700310809E00008FEC33 /* juce_IIRFilter.cpp in Sources */ = {isa = PBXBuildFile; fileRef = 84F1E7B610403614006A1807 /* juce_IIRFilter.cpp */; }; 8481700410809E00008FEC33 /* juce_IIRFilterAudioSource.cpp in Sources */ = {isa = PBXBuildFile; fileRef = 84F1E79E10403614006A1807 /* juce_IIRFilterAudioSource.cpp */; }; 8481700510809E00008FEC33 /* juce_Image.cpp in Sources */ = {isa = PBXBuildFile; fileRef = 84F1EB6D10403709006A1807 /* juce_Image.cpp */; }; - 8481700610809E00008FEC33 /* juce_ImageBrush.cpp in Sources */ = {isa = PBXBuildFile; fileRef = 84F1EB1F10403709006A1807 /* juce_ImageBrush.cpp */; }; 8481700710809E00008FEC33 /* juce_ImageButton.cpp in Sources */ = {isa = PBXBuildFile; fileRef = 84F1EA5610403709006A1807 /* juce_ImageButton.cpp */; }; 8481700810809E00008FEC33 /* juce_ImageCache.cpp in Sources */ = {isa = PBXBuildFile; fileRef = 84F1EB6F10403709006A1807 /* juce_ImageCache.cpp */; }; 8481700910809E00008FEC33 /* juce_ImageConvolutionKernel.cpp in Sources */ = {isa = PBXBuildFile; fileRef = 84F1EB7110403709006A1807 /* juce_ImageConvolutionKernel.cpp */; }; @@ -566,7 +559,6 @@ 8481707F10809E00008FEC33 /* juce_Slider.cpp in Sources */ = {isa = PBXBuildFile; fileRef = 84F1EA6910403709006A1807 /* juce_Slider.cpp */; }; 8481708010809E00008FEC33 /* juce_SliderPropertyComponent.cpp in Sources */ = {isa = PBXBuildFile; fileRef = 84F1EAE910403709006A1807 /* juce_SliderPropertyComponent.cpp */; }; 8481708110809E00008FEC33 /* juce_Socket.cpp in Sources */ = {isa = PBXBuildFile; fileRef = 84F1E999104036D6006A1807 /* juce_Socket.cpp */; }; - 8481708210809E00008FEC33 /* juce_SolidColourBrush.cpp in Sources */ = {isa = PBXBuildFile; fileRef = 84F1EB2110403709006A1807 /* juce_SolidColourBrush.cpp */; }; 8481708310809E00008FEC33 /* juce_SplashScreen.cpp in Sources */ = {isa = PBXBuildFile; fileRef = 84F1EB1110403709006A1807 /* juce_SplashScreen.cpp */; }; 8481708410809E00008FEC33 /* juce_StretchableLayoutManager.cpp in Sources */ = {isa = PBXBuildFile; fileRef = 84F1EAB410403709006A1807 /* juce_StretchableLayoutManager.cpp */; }; 8481708510809E00008FEC33 /* juce_StretchableLayoutResizerBar.cpp in Sources */ = {isa = PBXBuildFile; fileRef = 84F1EAB610403709006A1807 /* juce_StretchableLayoutResizerBar.cpp */; }; @@ -1128,14 +1120,6 @@ 84F1EC911040370A006A1807 /* juce_TooltipWindow.h in Headers */ = {isa = PBXBuildFile; fileRef = 84F1EB1610403709006A1807 /* juce_TooltipWindow.h */; }; 84F1EC921040370A006A1807 /* juce_TopLevelWindow.cpp in Sources */ = {isa = PBXBuildFile; fileRef = 84F1EB1710403709006A1807 /* juce_TopLevelWindow.cpp */; }; 84F1EC931040370A006A1807 /* juce_TopLevelWindow.h in Headers */ = {isa = PBXBuildFile; fileRef = 84F1EB1810403709006A1807 /* juce_TopLevelWindow.h */; }; - 84F1EC941040370A006A1807 /* juce_Brush.cpp in Sources */ = {isa = PBXBuildFile; fileRef = 84F1EB1B10403709006A1807 /* juce_Brush.cpp */; }; - 84F1EC951040370A006A1807 /* juce_Brush.h in Headers */ = {isa = PBXBuildFile; fileRef = 84F1EB1C10403709006A1807 /* juce_Brush.h */; }; - 84F1EC961040370A006A1807 /* juce_GradientBrush.cpp in Sources */ = {isa = PBXBuildFile; fileRef = 84F1EB1D10403709006A1807 /* juce_GradientBrush.cpp */; }; - 84F1EC971040370A006A1807 /* juce_GradientBrush.h in Headers */ = {isa = PBXBuildFile; fileRef = 84F1EB1E10403709006A1807 /* juce_GradientBrush.h */; }; - 84F1EC981040370A006A1807 /* juce_ImageBrush.cpp in Sources */ = {isa = PBXBuildFile; fileRef = 84F1EB1F10403709006A1807 /* juce_ImageBrush.cpp */; }; - 84F1EC991040370A006A1807 /* juce_ImageBrush.h in Headers */ = {isa = PBXBuildFile; fileRef = 84F1EB2010403709006A1807 /* juce_ImageBrush.h */; }; - 84F1EC9A1040370A006A1807 /* juce_SolidColourBrush.cpp in Sources */ = {isa = PBXBuildFile; fileRef = 84F1EB2110403709006A1807 /* juce_SolidColourBrush.cpp */; }; - 84F1EC9B1040370A006A1807 /* juce_SolidColourBrush.h in Headers */ = {isa = PBXBuildFile; fileRef = 84F1EB2210403709006A1807 /* juce_SolidColourBrush.h */; }; 84F1EC9C1040370A006A1807 /* juce_Colour.cpp in Sources */ = {isa = PBXBuildFile; fileRef = 84F1EB2410403709006A1807 /* juce_Colour.cpp */; }; 84F1EC9D1040370A006A1807 /* juce_ColourGradient.cpp in Sources */ = {isa = PBXBuildFile; fileRef = 84F1EB2510403709006A1807 /* juce_ColourGradient.cpp */; }; 84F1EC9E1040370A006A1807 /* juce_ColourGradient.h in Headers */ = {isa = PBXBuildFile; fileRef = 84F1EB2610403709006A1807 /* juce_ColourGradient.h */; }; @@ -1215,6 +1199,8 @@ 84F1ECE81040370A006A1807 /* juce_GIFLoader.h in Headers */ = {isa = PBXBuildFile; fileRef = 84F1EB7710403709006A1807 /* juce_GIFLoader.h */; }; 84F1ECE91040370A006A1807 /* juce_JPEGLoader.cpp in Sources */ = {isa = PBXBuildFile; fileRef = 84F1EB7810403709006A1807 /* juce_JPEGLoader.cpp */; }; 84F1ECEA1040370A006A1807 /* juce_PNGLoader.cpp in Sources */ = {isa = PBXBuildFile; fileRef = 84F1EB7910403709006A1807 /* juce_PNGLoader.cpp */; }; + 84F29A9F10C2EFA5005014DF /* juce_FillType.cpp in Sources */ = {isa = PBXBuildFile; fileRef = 84F29A9D10C2EFA5005014DF /* juce_FillType.cpp */; }; + 84F29AA010C2EFA5005014DF /* juce_FillType.h in Headers */ = {isa = PBXBuildFile; fileRef = 84F29A9E10C2EFA5005014DF /* juce_FillType.h */; }; /* End PBXBuildFile section */ /* Begin PBXFileReference section */ @@ -1739,14 +1725,6 @@ 84F1EB1610403709006A1807 /* juce_TooltipWindow.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; name = juce_TooltipWindow.h; path = ../../src/gui/components/windows/juce_TooltipWindow.h; sourceTree = SOURCE_ROOT; }; 84F1EB1710403709006A1807 /* juce_TopLevelWindow.cpp */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.cpp.cpp; name = juce_TopLevelWindow.cpp; path = ../../src/gui/components/windows/juce_TopLevelWindow.cpp; sourceTree = SOURCE_ROOT; }; 84F1EB1810403709006A1807 /* juce_TopLevelWindow.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; name = juce_TopLevelWindow.h; path = ../../src/gui/components/windows/juce_TopLevelWindow.h; sourceTree = SOURCE_ROOT; }; - 84F1EB1B10403709006A1807 /* juce_Brush.cpp */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.cpp.cpp; name = juce_Brush.cpp; path = ../../src/gui/graphics/brushes/juce_Brush.cpp; sourceTree = SOURCE_ROOT; }; - 84F1EB1C10403709006A1807 /* juce_Brush.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; name = juce_Brush.h; path = ../../src/gui/graphics/brushes/juce_Brush.h; sourceTree = SOURCE_ROOT; }; - 84F1EB1D10403709006A1807 /* juce_GradientBrush.cpp */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.cpp.cpp; name = juce_GradientBrush.cpp; path = ../../src/gui/graphics/brushes/juce_GradientBrush.cpp; sourceTree = SOURCE_ROOT; }; - 84F1EB1E10403709006A1807 /* juce_GradientBrush.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; name = juce_GradientBrush.h; path = ../../src/gui/graphics/brushes/juce_GradientBrush.h; sourceTree = SOURCE_ROOT; }; - 84F1EB1F10403709006A1807 /* juce_ImageBrush.cpp */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.cpp.cpp; name = juce_ImageBrush.cpp; path = ../../src/gui/graphics/brushes/juce_ImageBrush.cpp; sourceTree = SOURCE_ROOT; }; - 84F1EB2010403709006A1807 /* juce_ImageBrush.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; name = juce_ImageBrush.h; path = ../../src/gui/graphics/brushes/juce_ImageBrush.h; sourceTree = SOURCE_ROOT; }; - 84F1EB2110403709006A1807 /* juce_SolidColourBrush.cpp */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.cpp.cpp; name = juce_SolidColourBrush.cpp; path = ../../src/gui/graphics/brushes/juce_SolidColourBrush.cpp; sourceTree = SOURCE_ROOT; }; - 84F1EB2210403709006A1807 /* juce_SolidColourBrush.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; name = juce_SolidColourBrush.h; path = ../../src/gui/graphics/brushes/juce_SolidColourBrush.h; sourceTree = SOURCE_ROOT; }; 84F1EB2410403709006A1807 /* juce_Colour.cpp */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.cpp.cpp; name = juce_Colour.cpp; path = ../../src/gui/graphics/colour/juce_Colour.cpp; sourceTree = SOURCE_ROOT; }; 84F1EB2510403709006A1807 /* juce_ColourGradient.cpp */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.cpp.cpp; name = juce_ColourGradient.cpp; path = ../../src/gui/graphics/colour/juce_ColourGradient.cpp; sourceTree = SOURCE_ROOT; }; 84F1EB2610403709006A1807 /* juce_ColourGradient.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; name = juce_ColourGradient.h; path = ../../src/gui/graphics/colour/juce_ColourGradient.h; sourceTree = SOURCE_ROOT; }; @@ -1826,6 +1804,8 @@ 84F1EB7710403709006A1807 /* juce_GIFLoader.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; name = juce_GIFLoader.h; path = ../../src/gui/graphics/imaging/image_file_formats/juce_GIFLoader.h; sourceTree = SOURCE_ROOT; }; 84F1EB7810403709006A1807 /* juce_JPEGLoader.cpp */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.cpp.cpp; name = juce_JPEGLoader.cpp; path = ../../src/gui/graphics/imaging/image_file_formats/juce_JPEGLoader.cpp; sourceTree = SOURCE_ROOT; }; 84F1EB7910403709006A1807 /* juce_PNGLoader.cpp */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.cpp.cpp; name = juce_PNGLoader.cpp; path = ../../src/gui/graphics/imaging/image_file_formats/juce_PNGLoader.cpp; sourceTree = SOURCE_ROOT; }; + 84F29A9D10C2EFA5005014DF /* juce_FillType.cpp */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.cpp.cpp; path = juce_FillType.cpp; sourceTree = ""; }; + 84F29A9E10C2EFA5005014DF /* juce_FillType.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = juce_FillType.h; sourceTree = ""; }; D2AAC046055464E500DB518D /* libjucedebug.a */ = {isa = PBXFileReference; explicitFileType = archive.ar; includeInIndex = 0; path = libjucedebug.a; sourceTree = BUILT_PRODUCTS_DIR; }; /* End PBXFileReference section */ @@ -2730,7 +2710,6 @@ 84F1EB1910403709006A1807 /* graphics */ = { isa = PBXGroup; children = ( - 84F1EB1A10403709006A1807 /* brushes */, 84F1EB2310403709006A1807 /* colour */, 84F1EB2B10403709006A1807 /* contexts */, 84F1EB3910403709006A1807 /* drawables */, @@ -2743,22 +2722,6 @@ path = ../../src/gui/graphics; sourceTree = SOURCE_ROOT; }; - 84F1EB1A10403709006A1807 /* brushes */ = { - isa = PBXGroup; - children = ( - 84F1EB1B10403709006A1807 /* juce_Brush.cpp */, - 84F1EB1C10403709006A1807 /* juce_Brush.h */, - 84F1EB1D10403709006A1807 /* juce_GradientBrush.cpp */, - 84F1EB1E10403709006A1807 /* juce_GradientBrush.h */, - 84F1EB1F10403709006A1807 /* juce_ImageBrush.cpp */, - 84F1EB2010403709006A1807 /* juce_ImageBrush.h */, - 84F1EB2110403709006A1807 /* juce_SolidColourBrush.cpp */, - 84F1EB2210403709006A1807 /* juce_SolidColourBrush.h */, - ); - name = brushes; - path = ../../src/gui/graphics/brushes; - sourceTree = SOURCE_ROOT; - }; 84F1EB2310403709006A1807 /* colour */ = { isa = PBXGroup; children = ( @@ -2779,6 +2742,8 @@ children = ( 84F1EB2C10403709006A1807 /* juce_EdgeTable.cpp */, 84F1EB2D10403709006A1807 /* juce_EdgeTable.h */, + 84F29A9D10C2EFA5005014DF /* juce_FillType.cpp */, + 84F29A9E10C2EFA5005014DF /* juce_FillType.h */, 84F1EB2E10403709006A1807 /* juce_Graphics.cpp */, 84F1EB2F10403709006A1807 /* juce_Graphics.h */, 84F1EB3010403709006A1807 /* juce_Justification.cpp */, @@ -2961,7 +2926,6 @@ 84816E8D10809DCB008FEC33 /* juce_BlowFish.h in Headers */, 84816E8E10809DCB008FEC33 /* juce_BooleanPropertyComponent.h in Headers */, 84816E8F10809DCB008FEC33 /* juce_BorderSize.h in Headers */, - 84816E9010809DCB008FEC33 /* juce_Brush.h in Headers */, 84816E9110809DCB008FEC33 /* juce_BubbleComponent.h in Headers */, 84816E9210809DCB008FEC33 /* juce_BubbleMessageComponent.h in Headers */, 84816E9310809DCB008FEC33 /* juce_BufferedInputStream.h in Headers */, @@ -3034,7 +2998,6 @@ 84816ED610809DCB008FEC33 /* juce_GIFLoader.h in Headers */, 84816ED710809DCB008FEC33 /* juce_GlowEffect.h in Headers */, 84816ED810809DCB008FEC33 /* juce_GlyphArrangement.h in Headers */, - 84816ED910809DCB008FEC33 /* juce_GradientBrush.h in Headers */, 84816EDA10809DCB008FEC33 /* juce_Graphics.h in Headers */, 84816EDB10809DCB008FEC33 /* juce_GroupComponent.h in Headers */, 84816EDC10809DCB008FEC33 /* juce_GZIPCompressorOutputStream.h in Headers */, @@ -3043,7 +3006,6 @@ 84816EDF10809DCB008FEC33 /* juce_IIRFilter.h in Headers */, 84816EE010809DCB008FEC33 /* juce_IIRFilterAudioSource.h in Headers */, 84816EE110809DCB008FEC33 /* juce_Image.h in Headers */, - 84816EE210809DCB008FEC33 /* juce_ImageBrush.h in Headers */, 84816EE310809DCB008FEC33 /* juce_ImageButton.h in Headers */, 84816EE410809DCB008FEC33 /* juce_ImageCache.h in Headers */, 84816EE510809DCB008FEC33 /* juce_ImageConvolutionKernel.h in Headers */, @@ -3166,7 +3128,6 @@ 84816F5B10809DCB008FEC33 /* juce_SliderListener.h in Headers */, 84816F5C10809DCB008FEC33 /* juce_SliderPropertyComponent.h in Headers */, 84816F5D10809DCB008FEC33 /* juce_Socket.h in Headers */, - 84816F5E10809DCB008FEC33 /* juce_SolidColourBrush.h in Headers */, 84816F5F10809DCB008FEC33 /* juce_SortedSet.h in Headers */, 84816F6010809DCB008FEC33 /* juce_SparseSet.h in Headers */, 84816F6110809DCB008FEC33 /* juce_SplashScreen.h in Headers */, @@ -3504,10 +3465,6 @@ 84F1EC8F1040370A006A1807 /* juce_ThreadWithProgressWindow.h in Headers */, 84F1EC911040370A006A1807 /* juce_TooltipWindow.h in Headers */, 84F1EC931040370A006A1807 /* juce_TopLevelWindow.h in Headers */, - 84F1EC951040370A006A1807 /* juce_Brush.h in Headers */, - 84F1EC971040370A006A1807 /* juce_GradientBrush.h in Headers */, - 84F1EC991040370A006A1807 /* juce_ImageBrush.h in Headers */, - 84F1EC9B1040370A006A1807 /* juce_SolidColourBrush.h in Headers */, 84F1EC9E1040370A006A1807 /* juce_ColourGradient.h in Headers */, 84F1ECA01040370A006A1807 /* juce_Colours.h in Headers */, 84F1ECA11040370A006A1807 /* juce_PixelFormats.h in Headers */, @@ -3554,6 +3511,7 @@ 84AB91FE10A078190048FC39 /* juce_CodeEditorComponent.h in Headers */, 84AB920010A078190048FC39 /* juce_CPlusPlusCodeTokeniser.h in Headers */, 84AB927210A082E30048FC39 /* juce_CodeTokeniser.h in Headers */, + 84F29AA010C2EFA5005014DF /* juce_FillType.h in Headers */, ); runOnlyForDeploymentPostprocessing = 0; }; @@ -3656,7 +3614,6 @@ 84816FBC10809E00008FEC33 /* juce_BlowFish.cpp in Sources */, 84816FBD10809E00008FEC33 /* juce_BooleanPropertyComponent.cpp in Sources */, 84816FBE10809E00008FEC33 /* juce_BorderSize.cpp in Sources */, - 84816FBF10809E00008FEC33 /* juce_Brush.cpp in Sources */, 84816FC010809E00008FEC33 /* juce_BubbleComponent.cpp in Sources */, 84816FC110809E00008FEC33 /* juce_BubbleMessageComponent.cpp in Sources */, 84816FC210809E00008FEC33 /* juce_BufferedInputStream.cpp in Sources */, @@ -3718,7 +3675,6 @@ 84816FFA10809E00008FEC33 /* juce_GIFLoader.cpp in Sources */, 84816FFB10809E00008FEC33 /* juce_GlowEffect.cpp in Sources */, 84816FFC10809E00008FEC33 /* juce_GlyphArrangement.cpp in Sources */, - 84816FFD10809E00008FEC33 /* juce_GradientBrush.cpp in Sources */, 84816FFE10809E00008FEC33 /* juce_Graphics.cpp in Sources */, 84816FFF10809E00008FEC33 /* juce_GroupComponent.cpp in Sources */, 8481700010809E00008FEC33 /* juce_GZIPCompressorOutputStream.cpp in Sources */, @@ -3727,7 +3683,6 @@ 8481700310809E00008FEC33 /* juce_IIRFilter.cpp in Sources */, 8481700410809E00008FEC33 /* juce_IIRFilterAudioSource.cpp in Sources */, 8481700510809E00008FEC33 /* juce_Image.cpp in Sources */, - 8481700610809E00008FEC33 /* juce_ImageBrush.cpp in Sources */, 8481700710809E00008FEC33 /* juce_ImageButton.cpp in Sources */, 8481700810809E00008FEC33 /* juce_ImageCache.cpp in Sources */, 8481700910809E00008FEC33 /* juce_ImageConvolutionKernel.cpp in Sources */, @@ -3850,7 +3805,6 @@ 8481707F10809E00008FEC33 /* juce_Slider.cpp in Sources */, 8481708010809E00008FEC33 /* juce_SliderPropertyComponent.cpp in Sources */, 8481708110809E00008FEC33 /* juce_Socket.cpp in Sources */, - 8481708210809E00008FEC33 /* juce_SolidColourBrush.cpp in Sources */, 8481708310809E00008FEC33 /* juce_SplashScreen.cpp in Sources */, 8481708410809E00008FEC33 /* juce_StretchableLayoutManager.cpp in Sources */, 8481708510809E00008FEC33 /* juce_StretchableLayoutResizerBar.cpp in Sources */, @@ -4144,10 +4098,6 @@ 84F1EC8E1040370A006A1807 /* juce_ThreadWithProgressWindow.cpp in Sources */, 84F1EC901040370A006A1807 /* juce_TooltipWindow.cpp in Sources */, 84F1EC921040370A006A1807 /* juce_TopLevelWindow.cpp in Sources */, - 84F1EC941040370A006A1807 /* juce_Brush.cpp in Sources */, - 84F1EC961040370A006A1807 /* juce_GradientBrush.cpp in Sources */, - 84F1EC981040370A006A1807 /* juce_ImageBrush.cpp in Sources */, - 84F1EC9A1040370A006A1807 /* juce_SolidColourBrush.cpp in Sources */, 84F1EC9C1040370A006A1807 /* juce_Colour.cpp in Sources */, 84F1EC9D1040370A006A1807 /* juce_ColourGradient.cpp in Sources */, 84F1EC9F1040370A006A1807 /* juce_Colours.cpp in Sources */, @@ -4195,6 +4145,7 @@ 84AB91FB10A078190048FC39 /* juce_CodeDocument.cpp in Sources */, 84AB91FD10A078190048FC39 /* juce_CodeEditorComponent.cpp in Sources */, 84AB91FF10A078190048FC39 /* juce_CPlusPlusCodeTokeniser.cpp in Sources */, + 84F29A9F10C2EFA5005014DF /* juce_FillType.cpp in Sources */, ); runOnlyForDeploymentPostprocessing = 0; }; diff --git a/build/win32/vc8/JUCE.vcproj b/build/win32/vc8/JUCE.vcproj index 127c440c33..598a6fd521 100644 --- a/build/win32/vc8/JUCE.vcproj +++ b/build/win32/vc8/JUCE.vcproj @@ -2211,6 +2211,14 @@ RelativePath="..\..\..\src\gui\graphics\contexts\juce_EdgeTable.h" > + + + + diff --git a/extras/juce demo/src/demos/PathsAndTransformsDemo.cpp b/extras/juce demo/src/demos/PathsAndTransformsDemo.cpp index af68d37e27..4ec20f9a11 100644 --- a/extras/juce demo/src/demos/PathsAndTransformsDemo.cpp +++ b/extras/juce demo/src/demos/PathsAndTransformsDemo.cpp @@ -301,10 +301,10 @@ private: dp.setPath (shape); dp.setStrokeThickness (4.0f); - dp.setStrokeColour (Colours::blue); + dp.setStrokeFill (Colours::blue); - dp.setFillGradient (ColourGradient (Colours::red.withAlpha (0.4f), -100.0f, -100.0f, - Colours::green.withAlpha (0.6f), 100.0f, 100.0f, false)); + dp.setFill (ColourGradient (Colours::red.withAlpha (0.4f), -100.0f, -100.0f, + Colours::green.withAlpha (0.6f), 100.0f, 100.0f, false)); dc->insertDrawable (dp); diff --git a/extras/juce demo/src/demos/WidgetsDemo.cpp b/extras/juce demo/src/demos/WidgetsDemo.cpp index a3fe1c835c..c6fc60b717 100644 --- a/extras/juce demo/src/demos/WidgetsDemo.cpp +++ b/extras/juce demo/src/demos/WidgetsDemo.cpp @@ -422,13 +422,13 @@ static Component* createRadioButtonPage() Path p; p.addStar (0.0f, 0.0f, i + 5, 20.0f, 50.0f, -0.2f); normal.setPath (p); - normal.setFillColour (Colours::lightblue); - normal.setStrokeColour (Colours::black); + normal.setFill (Colours::lightblue); + normal.setStrokeFill (Colours::black); normal.setStrokeThickness (4.0f); over.setPath (p); - over.setFillColour (Colours::blue); - over.setStrokeColour (Colours::black); + over.setFill (Colours::blue); + over.setStrokeFill (Colours::black); over.setStrokeThickness (4.0f); DrawableButton* db = new DrawableButton (String (i + 5) + T(" points"), DrawableButton::ImageAboveTextLabel); @@ -480,13 +480,13 @@ public: Path p; p.addStar (0.0f, 0.0f, 5, 20.0f, 50.0f, 0.2f); normal.setPath (p); - normal.setFillColour (Colours::red); + normal.setFill (Colours::red); p.clear(); p.addStar (0.0f, 0.0f, 7, 30.0f, 50.0f, 0.0f); over.setPath (p); - over.setFillColour (Colours::pink); - over.setStrokeColour (Colours::black); + over.setFill (Colours::pink); + over.setStrokeFill (Colours::black); over.setStrokeThickness (5.0f); DrawableImage down; diff --git a/extras/the jucer/src/model/paintelements/jucer_ColouredElement.cpp b/extras/the jucer/src/model/paintelements/jucer_ColouredElement.cpp index 5a5894c5cb..97b89e8488 100644 --- a/extras/the jucer/src/model/paintelements/jucer_ColouredElement.cpp +++ b/extras/the jucer/src/model/paintelements/jucer_ColouredElement.cpp @@ -58,22 +58,22 @@ public: void setIndex (const int newIndex) { - FillType fill (isForStroke ? owner->getStrokeType().fill - : owner->getFillType()); + JucerFillType fill (isForStroke ? owner->getStrokeType().fill + : owner->getFillType()); switch (newIndex) { case 0: - fill.mode = FillType::solidColour; + fill.mode = JucerFillType::solidColour; break; case 1: - fill.mode = FillType::linearGradient; + fill.mode = JucerFillType::linearGradient; break; case 2: - fill.mode = FillType::radialGradient; + fill.mode = JucerFillType::radialGradient; break; case 3: - fill.mode = FillType::imageBrush; + fill.mode = JucerFillType::imageBrush; break; default: @@ -92,13 +92,13 @@ public: switch (isForStroke ? owner->getStrokeType().fill.mode : owner->getFillType().mode) { - case FillType::solidColour: + case JucerFillType::solidColour: return 0; - case FillType::linearGradient: + case JucerFillType::linearGradient: return 1; - case FillType::radialGradient: + case JucerFillType::radialGradient: return 2; - case FillType::imageBrush: + case JucerFillType::imageBrush: return 3; default: jassertfalse @@ -151,8 +151,8 @@ public: { owner->getDocument()->getUndoManager().undoCurrentTransactionOnly(); - FillType fill (isForStroke ? owner->getStrokeType().fill - : owner->getFillType()); + JucerFillType fill (isForStroke ? owner->getStrokeType().fill + : owner->getFillType()); switch (type) { @@ -181,8 +181,8 @@ public: const Colour getColour() const { - const FillType fill (isForStroke ? owner->getStrokeType().fill - : owner->getFillType()); + const JucerFillType fill (isForStroke ? owner->getStrokeType().fill + : owner->getFillType()); switch (type) { @@ -248,8 +248,8 @@ public: //============================================================================== void setPosition (const RelativePositionedRectangle& newPos) { - FillType fill (isForStroke ? owner->getStrokeType().fill - : owner->getFillType()); + JucerFillType fill (isForStroke ? owner->getStrokeType().fill + : owner->getFillType()); if (isStart) fill.gradPos1 = newPos; @@ -264,8 +264,8 @@ public: const RelativePositionedRectangle getPosition() const { - const FillType fill (isForStroke ? owner->getStrokeType().fill - : owner->getFillType()); + const JucerFillType fill (isForStroke ? owner->getStrokeType().fill + : owner->getFillType()); return isStart ? fill.gradPos1 : fill.gradPos2; @@ -472,14 +472,14 @@ public: { if (isForStroke) { - FillType type (element->getStrokeType().fill); + JucerFillType type (element->getStrokeType().fill); type.imageResourceName = newName; element->setStrokeFill (type, true); } else { - FillType type (element->getFillType()); + JucerFillType type (element->getFillType()); type.imageResourceName = newName; element->setFillType (type, true); @@ -523,13 +523,13 @@ public: { if (isForStroke) { - FillType type (owner->getStrokeType().fill); + JucerFillType type (owner->getStrokeType().fill); type.imageAnchor = newPos; owner->setStrokeFill (type, true); } else { - FillType type (owner->getFillType()); + JucerFillType type (owner->getFillType()); type.imageAnchor = newPos; owner->setFillType (type, true); } @@ -572,14 +572,14 @@ public: if (isForStroke) { - FillType type (element->getStrokeType().fill); + JucerFillType type (element->getStrokeType().fill); type.imageOpacity = newValue; element->setStrokeFill (type, true); } else { - FillType type (element->getFillType()); + JucerFillType type (element->getFillType()); type.imageOpacity = newValue; element->setFillType (type, true); @@ -634,12 +634,12 @@ void ColouredElement::getColourSpecificProperties (Array & p switch (getFillType().mode) { - case FillType::solidColour: + case JucerFillType::solidColour: properties.add (new ElementFillColourProperty (T("colour"), this, ElementFillColourProperty::solidColour, false)); break; - case FillType::linearGradient: - case FillType::radialGradient: + case JucerFillType::linearGradient: + case JucerFillType::radialGradient: properties.add (new ElementFillColourProperty (T("colour 1"), this, ElementFillColourProperty::gradientColour1, false)); properties.add (new ElementFillPositionProperty (this, T("x1"), PositionPropertyBase::componentX, true, false)); properties.add (new ElementFillPositionProperty (this, T("y1"), PositionPropertyBase::componentY, true, false)); @@ -648,7 +648,7 @@ void ColouredElement::getColourSpecificProperties (Array & p properties.add (new ElementFillPositionProperty (this, T("y2"), PositionPropertyBase::componentY, false, false)); break; - case FillType::imageBrush: + case JucerFillType::imageBrush: properties.add (new ImageBrushResourceProperty (this, false)); properties.add (new ImageBrushPositionProperty (this, T("anchor x"), PositionPropertyBase::componentX, false)); properties.add (new ImageBrushPositionProperty (this, T("anchor y"), PositionPropertyBase::componentY, false)); @@ -678,12 +678,12 @@ void ColouredElement::getColourSpecificProperties (Array & p switch (getStrokeType().fill.mode) { - case FillType::solidColour: + case JucerFillType::solidColour: properties.add (new ElementFillColourProperty (T("colour"), this, ElementFillColourProperty::solidColour, true)); break; - case FillType::linearGradient: - case FillType::radialGradient: + case JucerFillType::linearGradient: + case JucerFillType::radialGradient: properties.add (new ElementFillColourProperty (T("colour 1"), this, ElementFillColourProperty::gradientColour1, true)); properties.add (new ElementFillPositionProperty (this, T("x1"), PositionPropertyBase::componentX, true, true)); properties.add (new ElementFillPositionProperty (this, T("y1"), PositionPropertyBase::componentY, true, true)); @@ -692,7 +692,7 @@ void ColouredElement::getColourSpecificProperties (Array & p properties.add (new ElementFillPositionProperty (this, T("y2"), PositionPropertyBase::componentY, false, true)); break; - case FillType::imageBrush: + case JucerFillType::imageBrush: properties.add (new ImageBrushResourceProperty (this, true)); properties.add (new ImageBrushPositionProperty (this, T("stroke anchor x"), PositionPropertyBase::componentX, true)); properties.add (new ImageBrushPositionProperty (this, T("stroke anchor y"), PositionPropertyBase::componentY, true)); @@ -708,7 +708,7 @@ void ColouredElement::getColourSpecificProperties (Array & p } //============================================================================== -const FillType& ColouredElement::getFillType() throw() +const JucerFillType& ColouredElement::getFillType() throw() { return fillType; } @@ -716,7 +716,7 @@ const FillType& ColouredElement::getFillType() throw() class FillTypeChangeAction : public PaintElementUndoableAction { public: - FillTypeChangeAction (ColouredElement* const element, const FillType& newState_) + FillTypeChangeAction (ColouredElement* const element, const JucerFillType& newState_) : PaintElementUndoableAction (element), newState (newState_) { @@ -738,10 +738,10 @@ public: } private: - FillType newState, oldState; + JucerFillType newState, oldState; }; -void ColouredElement::setFillType (const FillType& newType, const bool undoable) +void ColouredElement::setFillType (const JucerFillType& newType, const bool undoable) { if (fillType != newType) { @@ -878,7 +878,7 @@ void ColouredElement::setStrokeType (const PathStrokeType& newType, const bool u class StrokeFillTypeChangeAction : public PaintElementUndoableAction { public: - StrokeFillTypeChangeAction (ColouredElement* const element, const FillType& newState_) + StrokeFillTypeChangeAction (ColouredElement* const element, const JucerFillType& newState_) : PaintElementUndoableAction (element), newState (newState_) { @@ -900,10 +900,10 @@ public: } private: - FillType newState, oldState; + JucerFillType newState, oldState; }; -void ColouredElement::setStrokeFill (const FillType& newType, const bool undoable) +void ColouredElement::setStrokeFill (const JucerFillType& newType, const bool undoable) { if (strokeType.fill != newType) { diff --git a/extras/the jucer/src/model/paintelements/jucer_ColouredElement.h b/extras/the jucer/src/model/paintelements/jucer_ColouredElement.h index 8f05be88a5..806d307d66 100644 --- a/extras/the jucer/src/model/paintelements/jucer_ColouredElement.h +++ b/extras/the jucer/src/model/paintelements/jucer_ColouredElement.h @@ -52,15 +52,15 @@ public: void getColourSpecificProperties (Array & properties); //============================================================================== - const FillType& getFillType() throw(); - void setFillType (const FillType& newType, const bool undoable); + const JucerFillType& getFillType() throw(); + void setFillType (const JucerFillType& newType, const bool undoable); bool isStrokeEnabled() const throw(); void enableStroke (bool enable, const bool undoable); const StrokeType& getStrokeType() throw(); void setStrokeType (const PathStrokeType& newType, const bool undoable); - void setStrokeFill (const FillType& newType, const bool undoable); + void setStrokeFill (const JucerFillType& newType, const bool undoable); //============================================================================== const Rectangle getCurrentBounds (const Rectangle& parentArea) const; @@ -76,7 +76,7 @@ public: juce_UseDebuggingNewOperator protected: - FillType fillType; + JucerFillType fillType; bool isStrokePresent; const bool showOutline, showJointAndEnd; diff --git a/extras/the jucer/src/model/paintelements/jucer_FillType.cpp b/extras/the jucer/src/model/paintelements/jucer_FillType.cpp index 5d22fa4a51..423eca190a 100644 --- a/extras/the jucer/src/model/paintelements/jucer_FillType.cpp +++ b/extras/the jucer/src/model/paintelements/jucer_FillType.cpp @@ -28,13 +28,13 @@ //============================================================================== -FillType::FillType() +JucerFillType::JucerFillType() : image (0) { reset(); } -FillType::FillType (const FillType& other) +JucerFillType::JucerFillType (const JucerFillType& other) { image = 0; mode = other.mode; @@ -48,7 +48,7 @@ FillType::FillType (const FillType& other) imageAnchor = other.imageAnchor; } -const FillType& FillType::operator= (const FillType& other) +const JucerFillType& JucerFillType::operator= (const JucerFillType& other) { ImageCache::release (image); image = 0; @@ -66,12 +66,12 @@ const FillType& FillType::operator= (const FillType& other) return *this; } -FillType::~FillType() +JucerFillType::~JucerFillType() { ImageCache::release (image); } -bool FillType::operator== (const FillType& other) const throw() +bool JucerFillType::operator== (const JucerFillType& other) const throw() { return mode == other.mode && colour == other.colour @@ -84,12 +84,12 @@ bool FillType::operator== (const FillType& other) const throw() && imageAnchor == other.imageAnchor; } -bool FillType::operator!= (const FillType& other) const throw() +bool JucerFillType::operator!= (const JucerFillType& other) const throw() { return ! operator== (other); } -void FillType::reset() +void JucerFillType::reset() { ImageCache::release (image); image = 0; @@ -110,7 +110,7 @@ void FillType::reset() } //============================================================================== -void FillType::setFillType (Graphics& g, JucerDocument* const document, const Rectangle& parentArea) +void JucerFillType::setFillType (Graphics& g, JucerDocument* const document, const Rectangle& parentArea) { if (mode == solidColour) { @@ -141,7 +141,7 @@ void FillType::setFillType (Graphics& g, JucerDocument* const document, const Re } } -void FillType::fillInGeneratedCode (GeneratedCode& code, String& paintMethodCode) const +void JucerFillType::fillInGeneratedCode (GeneratedCode& code, String& paintMethodCode) const { String s; @@ -203,7 +203,7 @@ void FillType::fillInGeneratedCode (GeneratedCode& code, String& paintMethodCode paintMethodCode += s; } -const String FillType::toString() const +const String JucerFillType::toString() const { switch (mode) { @@ -235,7 +235,7 @@ const String FillType::toString() const return String::empty; } -void FillType::restoreFromString (const String& s) +void JucerFillType::restoreFromString (const String& s) { reset(); @@ -278,7 +278,7 @@ void FillType::restoreFromString (const String& s) } } -bool FillType::isOpaque() const +bool JucerFillType::isOpaque() const { switch (mode) { @@ -302,7 +302,7 @@ bool FillType::isOpaque() const return false; } -bool FillType::isInvisible() const +bool JucerFillType::isInvisible() const { switch (mode) { @@ -324,7 +324,7 @@ bool FillType::isInvisible() const return false; } -void FillType::loadImage (JucerDocument* const document) +void JucerFillType::loadImage (JucerDocument* const document) { if (image == 0) { diff --git a/extras/the jucer/src/model/paintelements/jucer_FillType.h b/extras/the jucer/src/model/paintelements/jucer_FillType.h index ed63d79462..b19f37d524 100644 --- a/extras/the jucer/src/model/paintelements/jucer_FillType.h +++ b/extras/the jucer/src/model/paintelements/jucer_FillType.h @@ -33,17 +33,17 @@ /** Defines a brush to be used to fill a shape. */ -class FillType +class JucerFillType { public: //============================================================================== - FillType(); - FillType (const FillType& other); - const FillType& operator= (const FillType& other); - ~FillType(); + JucerFillType(); + JucerFillType (const JucerFillType& other); + const JucerFillType& operator= (const JucerFillType& other); + ~JucerFillType(); - bool operator== (const FillType& other) const throw(); - bool operator!= (const FillType& other) const throw(); + bool operator== (const JucerFillType& other) const throw(); + bool operator!= (const JucerFillType& other) const throw(); //============================================================================== void setFillType (Graphics& g, JucerDocument* const document, const Rectangle& parentArea); diff --git a/extras/the jucer/src/model/paintelements/jucer_GradientPointComponent.h b/extras/the jucer/src/model/paintelements/jucer_GradientPointComponent.h index 5c76dfaf72..2c31d5cac7 100644 --- a/extras/the jucer/src/model/paintelements/jucer_GradientPointComponent.h +++ b/extras/the jucer/src/model/paintelements/jucer_GradientPointComponent.h @@ -72,7 +72,7 @@ public: if (isStroke) { - FillType f (e->getStrokeType().fill); + JucerFillType f (e->getStrokeType().fill); if (isStart) f.gradPos1 = newPos; @@ -83,7 +83,7 @@ public: } else { - FillType f (e->getFillType()); + JucerFillType f (e->getFillType()); if (isStart) f.gradPos1 = newPos; @@ -100,11 +100,11 @@ public: ColouredElement* e = dynamic_cast (owner); - FillType f (isStroke ? e->getStrokeType().fill - : e->getFillType()); + JucerFillType f (isStroke ? e->getStrokeType().fill + : e->getFillType()); - setVisible (f.mode == FillType::linearGradient - || f.mode == FillType::radialGradient); + setVisible (f.mode == JucerFillType::linearGradient + || f.mode == JucerFillType::radialGradient); } private: diff --git a/extras/the jucer/src/model/paintelements/jucer_StrokeType.cpp b/extras/the jucer/src/model/paintelements/jucer_StrokeType.cpp index e50554bc01..20afc61ed3 100644 --- a/extras/the jucer/src/model/paintelements/jucer_StrokeType.cpp +++ b/extras/the jucer/src/model/paintelements/jucer_StrokeType.cpp @@ -41,7 +41,7 @@ StrokeType::~StrokeType() void StrokeType::reset() { stroke = PathStrokeType (5.0f); - fill = FillType(); + fill = JucerFillType(); fill.colour = Colours::black; } diff --git a/extras/the jucer/src/model/paintelements/jucer_StrokeType.h b/extras/the jucer/src/model/paintelements/jucer_StrokeType.h index f12b82ece9..304d594516 100644 --- a/extras/the jucer/src/model/paintelements/jucer_StrokeType.h +++ b/extras/the jucer/src/model/paintelements/jucer_StrokeType.h @@ -51,7 +51,7 @@ public: //============================================================================== PathStrokeType stroke; - FillType fill; + JucerFillType fill; //============================================================================== bool operator== (const StrokeType& other) const throw(); diff --git a/juce_amalgamated.cpp b/juce_amalgamated.cpp index fd958c5bed..6791f3c1f9 100644 --- a/juce_amalgamated.cpp +++ b/juce_amalgamated.cpp @@ -730,7 +730,7 @@ public: the rest of the codebase. */ -#define USE_COREGRAPHICS_RENDERING 1 +#define USE_COREGRAPHICS_RENDERING 0 #if JUCE_IPHONE #import @@ -30774,7 +30774,10 @@ const String AudioUnitPluginFormat::getNameOfPluginFromIdentifier (const String& bool AudioUnitPluginFormat::doesPluginStillExist (const PluginDescription& desc) { - return File (desc.fileOrIdentifier).exists(); + if (desc.fileOrIdentifier.startsWithIgnoreCase (auIdentifierPrefix)) + return fileMightContainThisPluginType (desc.fileOrIdentifier); + else + return File (desc.fileOrIdentifier).exists(); } const FileSearchPath AudioUnitPluginFormat::getDefaultLocationsToSearch() @@ -57649,7 +57652,7 @@ FileSearchPathListComponent::FileSearchPathListComponent() Path arrowPath; arrowPath.addArrow (50.0f, 100.0f, 50.0f, 0.0, 40.0f, 100.0f, 50.0f); DrawablePath arrowImage; - arrowImage.setFillColour (Colours::black.withAlpha (0.4f)); + arrowImage.setFill (Colours::black.withAlpha (0.4f)); arrowImage.setPath (arrowPath); ((DrawableButton*) upButton)->setImages (&arrowImage); @@ -57662,7 +57665,7 @@ FileSearchPathListComponent::FileSearchPathListComponent() Path arrowPath; arrowPath.addArrow (50.0f, 0.0f, 50.0f, 100.0f, 40.0f, 100.0f, 50.0f); DrawablePath arrowImage; - arrowImage.setFillColour (Colours::black.withAlpha (0.4f)); + arrowImage.setFill (Colours::black.withAlpha (0.4f)); arrowImage.setPath (arrowPath); ((DrawableButton*) downButton)->setImages (&arrowImage); @@ -58413,44 +58416,8 @@ public: void paintButton (Graphics& g, bool isOver, bool isDown) { - if (keyNum >= 0) - { - if (isEnabled()) - { - const float alpha = isDown ? 0.3f : (isOver ? 0.15f : 0.08f); - g.fillAll (owner->textColour.withAlpha (alpha)); - - g.setOpacity (0.3f); - g.drawBevel (0, 0, getWidth(), getHeight(), 2); - } - - g.setColour (owner->textColour); - g.setFont (getHeight() * 0.6f); - g.drawFittedText (getName(), - 3, 0, getWidth() - 6, getHeight(), - Justification::centred, 1); - } - else - { - const float thickness = 7.0f; - const float indent = 22.0f; - - Path p; - p.addEllipse (0.0f, 0.0f, 100.0f, 100.0f); - p.addRectangle (indent, 50.0f - thickness, 100.0f - indent * 2.0f, thickness * 2.0f); - p.addRectangle (50.0f - thickness, indent, thickness * 2.0f, 50.0f - indent - thickness); - p.addRectangle (50.0f - thickness, 50.0f + thickness, thickness * 2.0f, 50.0f - indent - thickness); - p.setUsingNonZeroWinding (false); - - g.setColour (owner->textColour.withAlpha (isDown ? 0.7f : (isOver ? 0.5f : 0.3f))); - g.fillPath (p, p.getTransformToScaleToFit (2.0f, 2.0f, getWidth() - 4.0f, getHeight() - 4.0f, true)); - } - - if (hasKeyboardFocus (false)) - { - g.setColour (owner->textColour.withAlpha (0.4f)); - g.drawRect (0, 0, getWidth(), getHeight()); - } + getLookAndFeel().drawKeymapChangeButton (g, getWidth(), getHeight(), *this, + keyNum >= 0 ? getName() : String::empty); } void clicked() @@ -58544,7 +58511,7 @@ public: void paint (Graphics& g) { g.setFont (getHeight() * 0.7f); - g.setColour (owner->textColour); + g.setColour (findColour (KeyMappingEditorComponent::textColourId)); g.drawFittedText (owner->getMappings()->getCommandManager()->getNameOfCommand (commandID), 4, 0, jmax (40, getChildComponent (0)->getX() - 5), getHeight(), @@ -58629,7 +58596,7 @@ public: void paintItem (Graphics& g, int width, int height) { g.setFont (height * 0.6f, Font::bold); - g.setColour (owner->textColour); + g.setColour (owner->findColour (KeyMappingEditorComponent::textColourId)); g.drawText (categoryName, 2, 0, width - 2, height, @@ -58669,8 +58636,7 @@ private: KeyMappingEditorComponent::KeyMappingEditorComponent (KeyPressMappingSet* const mappingManager, const bool showResetToDefaultButton) - : mappings (mappingManager), - textColour (Colours::black) + : mappings (mappingManager) { jassert (mappingManager != 0); // can't be null! @@ -58687,7 +58653,7 @@ KeyMappingEditorComponent::KeyMappingEditorComponent (KeyPressMappingSet* const } addAndMakeVisible (tree = new TreeView()); - tree->setColour (TreeView::backgroundColourId, backgroundColour); + tree->setColour (TreeView::backgroundColourId, findColour (backgroundColourId)); tree->setRootItemVisible (false); tree->setDefaultOpenness (true); tree->setRootItem (this); @@ -58710,11 +58676,11 @@ const String KeyMappingEditorComponent::getUniqueName() const } void KeyMappingEditorComponent::setColours (const Colour& mainBackground, - const Colour& textColour_) + const Colour& textColour) { - backgroundColour = mainBackground; - textColour = textColour_; - tree->setColour (TreeView::backgroundColourId, backgroundColour); + setColour (backgroundColourId, mainBackground); + setColour (textColourId, textColour); + tree->setColour (TreeView::backgroundColourId, mainBackground); } void KeyMappingEditorComponent::parentHierarchyChanged() @@ -58918,6 +58884,9 @@ KeyPress::KeyPress (const int keyCode_, mods (mods_), textCharacter (textCharacter_) { + // If you specify an upper-case letter but no shift key, how is the user supposed to press it!? + // Stick to lower-case letters when defining a keypress, to avoid ambiguity. + jassert (! (CharacterFunctions::isUpperCase (textCharacter_) && ! mods.isShiftDown())); } KeyPress::KeyPress (const int keyCode_) throw() @@ -63271,6 +63240,9 @@ LookAndFeel::LookAndFeel() ColourSelector::backgroundColourId, 0xffe5e5e5, ColourSelector::labelTextColourId, 0xff000000, + KeyMappingEditorComponent::backgroundColourId, 0x00000000, + KeyMappingEditorComponent::textColourId, 0xff000000, + FileSearchPathListComponent::backgroundColourId, 0xffffffff, }; @@ -65362,7 +65334,7 @@ Button* LookAndFeel::createTabBarExtrasButton() DrawablePath ellipse; ellipse.setPath (p); - ellipse.setFillColour (Colour (0x99ffffff)); + ellipse.setFill (Colour (0x99ffffff)); p.clear(); p.addEllipse (0.0f, 0.0f, 100.0f, 100.0f); @@ -65373,13 +65345,13 @@ Button* LookAndFeel::createTabBarExtrasButton() DrawablePath dp; dp.setPath (p); - dp.setFillColour (Colour (0x59000000)); + dp.setFill (Colour (0x59000000)); DrawableComposite normalImage; normalImage.insertDrawable (ellipse); normalImage.insertDrawable (dp); - dp.setFillColour (Colour (0xcc000000)); + dp.setFill (Colour (0xcc000000)); DrawableComposite overImage; overImage.insertDrawable (ellipse); @@ -65620,7 +65592,7 @@ Button* LookAndFeel::createFileBrowserGoUpButton() arrowPath.addArrow (50.0f, 100.0f, 50.0f, 0.0, 40.0f, 100.0f, 50.0f); DrawablePath arrowImage; - arrowImage.setFillColour (Colours::black.withAlpha (0.4f)); + arrowImage.setFill (Colours::black.withAlpha (0.4f)); arrowImage.setPath (arrowPath); goUpButton->setImages (&arrowImage); @@ -65770,6 +65742,50 @@ void LookAndFeel::drawLevelMeter (Graphics& g, int width, int height, float leve } } +void LookAndFeel::drawKeymapChangeButton (Graphics& g, int width, int height, Button& button, const String& keyDescription) +{ + const Colour textColour (button.findColour (KeyMappingEditorComponent::textColourId, true)); + + if (keyDescription.isNotEmpty()) + { + if (button.isEnabled()) + { + const float alpha = button.isDown() ? 0.3f : (button.isOver() ? 0.15f : 0.08f); + g.fillAll (textColour.withAlpha (alpha)); + + g.setOpacity (0.3f); + g.drawBevel (0, 0, width, height, 2); + } + + g.setColour (textColour); + g.setFont (height * 0.6f); + g.drawFittedText (keyDescription, + 3, 0, width - 6, height, + Justification::centred, 1); + } + else + { + const float thickness = 7.0f; + const float indent = 22.0f; + + Path p; + p.addEllipse (0.0f, 0.0f, 100.0f, 100.0f); + p.addRectangle (indent, 50.0f - thickness, 100.0f - indent * 2.0f, thickness * 2.0f); + p.addRectangle (50.0f - thickness, indent, thickness * 2.0f, 50.0f - indent - thickness); + p.addRectangle (50.0f - thickness, 50.0f + thickness, thickness * 2.0f, 50.0f - indent - thickness); + p.setUsingNonZeroWinding (false); + + g.setColour (textColour.withAlpha (button.isDown() ? 0.7f : (button.isOver() ? 0.5f : 0.3f))); + g.fillPath (p, p.getTransformToScaleToFit (2.0f, 2.0f, width - 4.0f, height - 4.0f, true)); + } + + if (button.hasKeyboardFocus (false)) + { + g.setColour (textColour.withAlpha (0.4f)); + g.drawRect (0, 0, width, height); + } +} + static void createRoundedPath (Path& p, const float x, const float y, const float w, const float h, @@ -66545,7 +66561,7 @@ Button* OldSchoolLookAndFeel::createDocumentWindowButton (int buttonType) DrawableButton* b = new DrawableButton ("minimise", DrawableButton::ImageFitted); DrawablePath dp; dp.setPath (shape); - dp.setFillColour (Colours::black.withAlpha (0.3f)); + dp.setFill (Colours::black.withAlpha (0.3f)); b->setImages (&dp); return b; } @@ -66557,7 +66573,7 @@ Button* OldSchoolLookAndFeel::createDocumentWindowButton (int buttonType) DrawableButton* b = new DrawableButton ("maximise", DrawableButton::ImageFitted); DrawablePath dp; dp.setPath (shape); - dp.setFillColour (Colours::black.withAlpha (0.3f)); + dp.setFill (Colours::black.withAlpha (0.3f)); b->setImages (&dp); return b; } @@ -78133,7 +78149,7 @@ const Colour ColourGradient::getColourAtPosition (const float position) const th return col1.interpolatedWith (col2, (integerPos - pos1) / (float) (pos2 - pos1)); } -PixelARGB* ColourGradient::createLookupTable (int& numEntries) const throw() +PixelARGB* ColourGradient::createLookupTable (const AffineTransform& transform, int& numEntries) const throw() { #ifdef JUCE_DEBUG // trying to use the object without setting its co-ordinates? Have a careful read of @@ -79141,6 +79157,87 @@ bool EdgeTable::isEmpty() throw() END_JUCE_NAMESPACE /********* End of inlined file: juce_EdgeTable.cpp *********/ +/********* Start of inlined file: juce_FillType.cpp *********/ + +BEGIN_JUCE_NAMESPACE + +FillType::FillType() throw() + : colour (0xff000000), gradient (0), image (0) +{ +} + +FillType::FillType (const Colour& colour_) throw() + : colour (colour_), gradient (0), image (0) +{ +} + +FillType::FillType (const ColourGradient& gradient) throw() + : colour (0xff000000), gradient (new ColourGradient (gradient)), image (0) +{ +} + +FillType::FillType (const Image& image_, const AffineTransform& transform_) throw() + : colour (0xff000000), gradient (0), + image (&image_), transform (transform_) +{ +} + +FillType::FillType (const FillType& other) throw() + : colour (other.colour), + gradient (other.gradient != 0 ? new ColourGradient (*other.gradient) : 0), + image (other.image), transform (other.transform) +{ +} + +const FillType& FillType::operator= (const FillType& other) throw() +{ + if (this != &other) + { + colour = other.colour; + delete gradient; + gradient = (other.gradient != 0 ? new ColourGradient (*other.gradient) : 0); + image = other.image; + transform = other.transform; + } + + return *this; +} + +FillType::~FillType() throw() +{ + delete gradient; +} + +void FillType::setColour (const Colour& newColour) throw() +{ + deleteAndZero (gradient); + image = 0; + colour = newColour; +} + +void FillType::setGradient (const ColourGradient& newGradient) throw() +{ + if (gradient != 0) + { + *gradient = newGradient; + } + else + { + image = 0; + gradient = new ColourGradient (newGradient); + } +} + +void FillType::setTiledImage (const Image& image_, const AffineTransform& transform_) throw() +{ + deleteAndZero (gradient); + image = &image_; + transform = transform_; +} + +END_JUCE_NAMESPACE +/********* End of inlined file: juce_FillType.cpp *********/ + /********* Start of inlined file: juce_Graphics.cpp *********/ BEGIN_JUCE_NAMESPACE @@ -79194,7 +79291,7 @@ Graphics::~Graphics() throw() void Graphics::resetToDefaultState() throw() { saveStateIfPending(); - context->setColour (Colours::black); + context->setFill (FillType()); context->setFont (Font()); context->setInterpolationQuality (defaultQuality); } @@ -79217,6 +79314,20 @@ bool Graphics::reduceClipRegion (const RectangleList& clipRegion) throw() return context->clipToRectangleList (clipRegion); } +bool Graphics::reduceClipRegion (const Path& path, const AffineTransform& transform) throw() +{ + saveStateIfPending(); + context->clipToPath (path, transform); + return ! context->isClipEmpty(); +} + +bool Graphics::reduceClipRegion (const Image& image, const Rectangle& sourceClipRegion, const AffineTransform& transform) throw() +{ + saveStateIfPending(); + context->clipToImageAlpha (image, sourceClipRegion, transform); + return ! context->isClipEmpty(); +} + void Graphics::excludeClipRegion (const int x, const int y, const int w, const int h) throw() { @@ -79273,7 +79384,7 @@ bool Graphics::clipRegionIntersects (const int x, const int y, void Graphics::setColour (const Colour& newColour) throw() { saveStateIfPending(); - context->setColour (newColour); + context->setFill (FillType (newColour)); } void Graphics::setOpacity (const float newOpacity) throw() @@ -79285,7 +79396,7 @@ void Graphics::setOpacity (const float newOpacity) throw() void Graphics::setGradientFill (const ColourGradient& gradient) throw() { saveStateIfPending(); - context->setGradient (gradient); + context->setFill (FillType (gradient)); } void Graphics::setTiledImageFill (const Image& imageToUse, @@ -79294,10 +79405,16 @@ void Graphics::setTiledImageFill (const Image& imageToUse, const float opacity) throw() { saveStateIfPending(); - context->setTiledFill (imageToUse, anchorX, anchorY); + context->setFill (FillType (imageToUse, AffineTransform::translation ((float) anchorX, (float) anchorY))); context->setOpacity (opacity); } +void Graphics::setFillType (const FillType& newFill) throw() +{ + saveStateIfPending(); + context->setFill (newFill); +} + void Graphics::setFont (const Font& newFont) throw() { saveStateIfPending(); @@ -79449,7 +79566,7 @@ void Graphics::fillAll (const Colour& colourToUse) const throw() const Rectangle clip (context->getClipBounds()); context->saveState(); - context->setColour (colourToUse); + context->setFill (FillType (colourToUse)); context->fillRect (clip, false); context->restoreState(); } @@ -79536,13 +79653,13 @@ void Graphics::drawBevel (const int x, const float op = useGradient ? ramp * (sharpEdgeOnOutside ? bevelThickness - i : i) : oldOpacity; - context->setColour (topLeftColour.withMultipliedAlpha (op)); + context->setFill (FillType (topLeftColour.withMultipliedAlpha (op))); context->fillRect (Rectangle (x + i, y + i, width - i * 2, 1), false); - context->setColour (topLeftColour.withMultipliedAlpha (op * 0.75f)); + context->setFill (FillType (topLeftColour.withMultipliedAlpha (op * 0.75f))); context->fillRect (Rectangle (x + i, y + i + 1, 1, height - i * 2 - 2), false); - context->setColour (bottomRightColour.withMultipliedAlpha (op)); + context->setFill (FillType (bottomRightColour.withMultipliedAlpha (op))); context->fillRect (Rectangle (x + i, y + height - i - 1, width - i * 2, 1), false); - context->setColour (bottomRightColour.withMultipliedAlpha (op * 0.75f)); + context->setFill (FillType (bottomRightColour.withMultipliedAlpha (op * 0.75f))); context->fillRect (Rectangle (x + width - i - 1, y + i + 1, 1, height - i * 2 - 2), false); } @@ -79656,7 +79773,7 @@ void Graphics::fillCheckerBoard (int x, int y, if (colour1 == colour2) { - context->setColour (colour1); + context->setFill (FillType (colour1)); context->fillRect (Rectangle (x, y, width, height), false); } else @@ -79673,7 +79790,7 @@ void Graphics::fillCheckerBoard (int x, int y, for (int xx = x; xx < right; xx += checkWidth) { - context->setColour (((cx++ & 1) == 0) ? colour1 : colour2); + context->setFill (FillType (((cx++ & 1) == 0) ? colour1 : colour2)); context->fillRect (Rectangle (xx, y, jmin (checkWidth, right - xx), jmin (checkHeight, bottom - y)), false); } @@ -79872,79 +79989,6 @@ void Graphics::drawImageTransformed (const Image* const imageToDraw, } } -Graphics::FillType::FillType() throw() - : colour (0xff000000), gradient (0), - image (0), imageX (0), imageY (0) -{ -} - -Graphics::FillType::FillType (const Colour& colour_) throw() - : colour (colour_), gradient (0), - image (0), imageX (0), imageY (0) -{ -} - -Graphics::FillType::FillType (const ColourGradient& gradient) throw() - : colour (0xff000000), gradient (new ColourGradient (gradient)), - image (0), imageX (0), imageY (0) -{ -} - -Graphics::FillType::FillType (Image* const image_, const int x, const int y) throw() - : colour (0xff000000), gradient (0), - image (image_), imageX (x), imageY (y) -{ -} - -Graphics::FillType::FillType (const FillType& other) throw() - : colour (other.colour), - gradient (other.gradient != 0 ? new ColourGradient (*other.gradient) : 0), - image (other.image), imageX (other.imageX), imageY (other.imageY) -{ -} - -const Graphics::FillType& Graphics::FillType::operator= (const FillType& other) throw() -{ - if (this != &other) - { - colour = other.colour; - delete gradient; - gradient = (other.gradient != 0 ? new ColourGradient (*other.gradient) : 0); - image = other.image; - imageX = other.imageX; - imageY = other.imageY; - } - - return *this; -} - -Graphics::FillType::~FillType() throw() -{ - delete gradient; -} - -void Graphics::FillType::setColour (const Colour& newColour) throw() -{ - deleteAndZero (gradient); - colour = newColour; -} - -void Graphics::FillType::setGradient (const ColourGradient& newGradient) throw() -{ - if (gradient != 0) - *gradient = newGradient; - else - gradient = new ColourGradient (newGradient); -} - -void Graphics::FillType::setTiledImage (const Image& image_, const int imageX_, const int imageY_) throw() -{ - deleteAndZero (gradient); - image = &image_; - imageX = imageX_; - imageY = imageY_; -} - END_JUCE_NAMESPACE /********* End of inlined file: juce_Graphics.cpp *********/ @@ -80033,13 +80077,10 @@ LowLevelGraphicsPostScriptRenderer::LowLevelGraphicsPostScriptRenderer (OutputSt : out (resultingPostScript), totalWidth (totalWidth_), totalHeight (totalHeight_), - xOffset (0), - yOffset (0), - needToClip (true), - colour (Colours::black), - gradient (0) + needToClip (true) { - clip = new RectangleList (Rectangle (0, 0, totalWidth_, totalHeight_)); + stateStack.add (new SavedState()); + stateStack.getLast()->clip = Rectangle (0, 0, totalWidth_, totalHeight_); const float scale = jmin ((520.0f / totalWidth_), (750.0f / totalHeight)); @@ -80076,8 +80117,6 @@ LowLevelGraphicsPostScriptRenderer::LowLevelGraphicsPostScriptRenderer (OutputSt LowLevelGraphicsPostScriptRenderer::~LowLevelGraphicsPostScriptRenderer() { - delete clip; - delete gradient; } bool LowLevelGraphicsPostScriptRenderer::isVectorDevice() const @@ -80089,90 +80128,83 @@ void LowLevelGraphicsPostScriptRenderer::setOrigin (int x, int y) { if (x != 0 || y != 0) { - xOffset += x; - yOffset += y; + stateStack.getLast()->xOffset += x; + stateStack.getLast()->yOffset += y; needToClip = true; } } -bool LowLevelGraphicsPostScriptRenderer::reduceClipRegion (int x, int y, int w, int h) +bool LowLevelGraphicsPostScriptRenderer::clipToRectangle (const Rectangle& r) { needToClip = true; - return clip->clipTo (Rectangle (x + xOffset, y + yOffset, w, h)); + return stateStack.getLast()->clip.clipTo (r.translated (stateStack.getLast()->xOffset, stateStack.getLast()->yOffset)); } -bool LowLevelGraphicsPostScriptRenderer::reduceClipRegion (const RectangleList& clipRegion) +bool LowLevelGraphicsPostScriptRenderer::clipToRectangleList (const RectangleList& clipRegion) { needToClip = true; - return clip->clipTo (clipRegion); + return stateStack.getLast()->clip.clipTo (clipRegion); } -void LowLevelGraphicsPostScriptRenderer::excludeClipRegion (int x, int y, int w, int h) +void LowLevelGraphicsPostScriptRenderer::excludeClipRectangle (const Rectangle& r) { needToClip = true; - clip->subtract (Rectangle (x + xOffset, y + yOffset, w, h)); + stateStack.getLast()->clip.subtract (r.translated (stateStack.getLast()->xOffset, stateStack.getLast()->yOffset)); } -bool LowLevelGraphicsPostScriptRenderer::clipRegionIntersects (int x, int y, int w, int h) +void LowLevelGraphicsPostScriptRenderer::clipToPath (const Path& path, const AffineTransform& transform) { - return clip->intersectsRectangle (Rectangle (x + xOffset, y + yOffset, w, h)); + writeClip(); + + Path p (path); + p.applyTransform (transform.translated ((float) stateStack.getLast()->xOffset, (float) stateStack.getLast()->yOffset)); + writePath (p); + out << "clip\n"; +} + +void LowLevelGraphicsPostScriptRenderer::clipToImageAlpha (const Image& sourceImage, const Rectangle& srcClip, const AffineTransform& transform) +{ + needToClip = true; + jassertfalse // xxx +} + +bool LowLevelGraphicsPostScriptRenderer::clipRegionIntersects (const Rectangle& r) +{ + return stateStack.getLast()->clip.intersectsRectangle (r.translated (stateStack.getLast()->xOffset, stateStack.getLast()->yOffset)); } const Rectangle LowLevelGraphicsPostScriptRenderer::getClipBounds() const { - return clip->getBounds().translated (-xOffset, -yOffset); + return stateStack.getLast()->clip.getBounds().translated (-stateStack.getLast()->xOffset, + -stateStack.getLast()->yOffset); } bool LowLevelGraphicsPostScriptRenderer::isClipEmpty() const { - return clip->isEmpty(); + return stateStack.getLast()->clip.isEmpty(); } -LowLevelGraphicsPostScriptRenderer::SavedState::SavedState (RectangleList* const clip_, - const int xOffset_, const int yOffset_, - const Colour& colour_, ColourGradient* const gradient_, - const Font& font_) - : clip (clip_), - xOffset (xOffset_), - yOffset (yOffset_), - colour (colour_), - gradient (gradient_), - font (font_) +LowLevelGraphicsPostScriptRenderer::SavedState::SavedState() + : xOffset (0), + yOffset (0) { } LowLevelGraphicsPostScriptRenderer::SavedState::~SavedState() { - delete clip; - delete gradient; } void LowLevelGraphicsPostScriptRenderer::saveState() { - stateStack.add (new SavedState (new RectangleList (*clip), xOffset, yOffset, colour, - gradient != 0 ? new ColourGradient (*gradient) : 0, font)); + stateStack.add (new SavedState (*stateStack.getLast())); } void LowLevelGraphicsPostScriptRenderer::restoreState() { - SavedState* const top = stateStack.getLast(); - - if (top != 0) - { - swapVariables (clip, top->clip); - swapVariables (gradient, top->gradient); - colour = top->colour; - xOffset = top->xOffset; - yOffset = top->yOffset; - font = top->font; + jassert (stateStack.size() > 0); + if (stateStack.size() > 0) stateStack.removeLast(); - needToClip = true; - } - else - { - jassertfalse // trying to pop with an empty stack! - } } void LowLevelGraphicsPostScriptRenderer::writeClip() @@ -80185,7 +80217,7 @@ void LowLevelGraphicsPostScriptRenderer::writeClip() int itemsOnLine = 0; - for (RectangleList::Iterator i (*clip); i.next();) + for (RectangleList::Iterator i (stateStack.getLast()->clip); i.next();) { if (++itemsOnLine == 6) { @@ -80306,16 +80338,9 @@ void LowLevelGraphicsPostScriptRenderer::writeTransform (const AffineTransform& << trans.mat12 << " ] concat "; } -void LowLevelGraphicsPostScriptRenderer::setColour (const Colour& colour_) +void LowLevelGraphicsPostScriptRenderer::setFill (const FillType& fillType) { - colour = colour_; - deleteAndZero (gradient); -} - -void LowLevelGraphicsPostScriptRenderer::setGradient (const ColourGradient& gradient_) -{ - delete gradient; - gradient = new ColourGradient (gradient_); + stateStack.getLast()->fillType = fillType; } void LowLevelGraphicsPostScriptRenderer::setOpacity (float opacity) @@ -80326,22 +80351,21 @@ void LowLevelGraphicsPostScriptRenderer::setInterpolationQuality (Graphics::Resa { } -void LowLevelGraphicsPostScriptRenderer::fillRect (int x, int y, int w, int h, const bool /*replaceExistingContents*/) +void LowLevelGraphicsPostScriptRenderer::fillRect (const Rectangle& r, const bool /*replaceExistingContents*/) { - if (gradient == 0) + if (stateStack.getLast()->fillType.isColour()) { writeClip(); - writeColour (colour); + writeColour (stateStack.getLast()->fillType.colour); - x += xOffset; - y += yOffset; + Rectangle r2 (r.translated (stateStack.getLast()->xOffset, stateStack.getLast()->yOffset)); - out << x << ' ' << -(y + h) << ' ' << w << ' ' << h << " rectfill\n"; + out << r2.getX() << ' ' << -r2.getBottom() << ' ' << r2.getWidth() << ' ' << r2.getHeight() << " rectfill\n"; } else { Path p; - p.addRectangle ((float) x, (float) y, (float) w, (float) h); + p.addRectangle (r); fillPath (p, AffineTransform::identity); } @@ -80349,19 +80373,20 @@ void LowLevelGraphicsPostScriptRenderer::fillRect (int x, int y, int w, int h, c void LowLevelGraphicsPostScriptRenderer::fillPath (const Path& path, const AffineTransform& t) { - if (gradient == 0) + if (stateStack.getLast()->fillType.isColour()) { writeClip(); Path p (path); - p.applyTransform (t.translated ((float) xOffset, (float) yOffset)); + p.applyTransform (t.translated ((float) stateStack.getLast()->xOffset, + (float) stateStack.getLast()->yOffset)); writePath (p); - writeColour (colour); + writeColour (stateStack.getLast()->fillType.colour); out << "fill\n"; } - else + else if (stateStack.getLast()->fillType.isGradient()) { // this doesn't work correctly yet - it could be improved to handle solid gradients, but // postscript can't do semi-transparent ones. @@ -80372,75 +80397,22 @@ void LowLevelGraphicsPostScriptRenderer::fillPath (const Path& path, const Affin { Path p (path); - p.applyTransform (t.translated ((float) xOffset, (float) yOffset)); + p.applyTransform (t.translated ((float) stateStack.getLast()->xOffset, (float) stateStack.getLast()->yOffset)); writePath (p); out << "clip\n"; } - const Rectangle bounds (clip->getBounds()); + const Rectangle bounds (stateStack.getLast()->clip.getBounds()); // ideally this would draw lots of lines or ellipses to approximate the gradient, but for the // time-being, this just fills it with the average colour.. - writeColour (gradient->getColourAtPosition (0.5)); + writeColour (stateStack.getLast()->fillType.gradient->getColourAtPosition (0.5)); out << bounds.getX() << ' ' << -bounds.getBottom() << ' ' << bounds.getWidth() << ' ' << bounds.getHeight() << " rectfill\n"; out << "grestore\n"; } } -void LowLevelGraphicsPostScriptRenderer::fillPathWithImage (const Path& path, const AffineTransform& transform, - const Image& sourceImage, - int imageX, int imageY) -{ - writeClip(); - - out << "gsave "; - Path p (path); - p.applyTransform (transform.translated ((float) xOffset, (float) yOffset)); - writePath (p); - out << "clip\n"; - - blendImage (sourceImage, imageX, imageY, sourceImage.getWidth(), sourceImage.getHeight(), 0, 0); - - out << "grestore\n"; -} - -void LowLevelGraphicsPostScriptRenderer::fillAlphaChannel (const Image& /*clipImage*/, int x, int y) -{ - x += xOffset; - y += yOffset; - - writeClip(); - - if (gradient == 0) - { - writeColour (colour); - } - - notPossibleInPostscriptAssert // you can disable this warning by setting the WARN_ABOUT_NON_POSTSCRIPT_OPERATIONS flag at the top of this file -} - -void LowLevelGraphicsPostScriptRenderer::fillAlphaChannelWithImage (const Image& /*alphaImage*/, int alphaImageX, int alphaImageY, - const Image& /*fillerImage*/, int fillerImageX, int fillerImageY) -{ - alphaImageX += xOffset; - alphaImageY += yOffset; - - fillerImageX += xOffset; - fillerImageY += yOffset; - - writeClip(); - - notPossibleInPostscriptAssert // you can disable this warning by setting the WARN_ABOUT_NON_POSTSCRIPT_OPERATIONS flag at the top of this file -} - -void LowLevelGraphicsPostScriptRenderer::blendImage (const Image& sourceImage, int dx, int dy, int dw, int dh, int sx, int sy) -{ - blendImageWarping (sourceImage, - sx, sy, dw, dh, - AffineTransform::translation ((float) dx, (float) dy)); -} - void LowLevelGraphicsPostScriptRenderer::writeImage (const Image& im, const int sx, const int sy, const int maxW, const int maxH) const @@ -80499,23 +80471,21 @@ void LowLevelGraphicsPostScriptRenderer::writeImage (const Image& im, out << "\n>}\n"; } -void LowLevelGraphicsPostScriptRenderer::blendImageWarping (const Image& sourceImage, - int srcClipX, int srcClipY, - int srcClipW, int srcClipH, - const AffineTransform& t) +void LowLevelGraphicsPostScriptRenderer::drawImage (const Image& sourceImage, const Rectangle& srcClip, + const AffineTransform& transform, const bool fillEntireClipAsTiles) { - const int w = jmin (sourceImage.getWidth(), srcClipX + srcClipW); - const int h = jmin (sourceImage.getHeight(), srcClipY + srcClipH); + const int w = jmin (sourceImage.getWidth(), srcClip.getRight()); + const int h = jmin (sourceImage.getHeight(), srcClip.getBottom()); writeClip(); out << "gsave "; - writeTransform (t.translated ((float) xOffset, (float) yOffset) - .scaled (1.0f, -1.0f)); + writeTransform (transform.translated ((float) stateStack.getLast()->xOffset, (float) stateStack.getLast()->yOffset) + .scaled (1.0f, -1.0f)); RectangleList imageClip; sourceImage.createSolidAreaMask (imageClip, 0.5f); - imageClip.clipTo (Rectangle (srcClipX, srcClipY, srcClipW, srcClipH)); + imageClip.clipTo (srcClip); out << "newpath "; int itemsOnLine = 0; @@ -80538,7 +80508,7 @@ void LowLevelGraphicsPostScriptRenderer::blendImageWarping (const Image& sourceI out << w << ' ' << h << " scale\n"; out << w << ' ' << h << " 8 [" << w << " 0 0 -" << h << ' ' << (int) 0 << ' ' << h << " ]\n"; - writeImage (sourceImage, srcClipX, srcClipY, srcClipW, srcClipH); + writeImage (sourceImage, srcClip.getX(), srcClip.getY(), srcClip.getWidth(), srcClip.getHeight()); out << "false 3 colorimage grestore\n"; needToClip = true; @@ -80563,19 +80533,19 @@ void LowLevelGraphicsPostScriptRenderer::drawHorizontalLine (const int y, double void LowLevelGraphicsPostScriptRenderer::setFont (const Font& newFont) { - font = newFont; + stateStack.getLast()->font = newFont; } -void LowLevelGraphicsPostScriptRenderer::drawGlyph (int glyphNumber, float x, float y) +const Font LowLevelGraphicsPostScriptRenderer::getFont() { - drawGlyph (glyphNumber, AffineTransform::translation (x, y)); + return stateStack.getLast()->font; } void LowLevelGraphicsPostScriptRenderer::drawGlyph (int glyphNumber, const AffineTransform& transform) { Path p; + Font& font = stateStack.getLast()->font; font.getTypeface()->getOutlineForGlyph (glyphNumber, p); - fillPath (p, AffineTransform::scale (font.getHeight() * font.getHorizontalScale(), font.getHeight()).followedBy (transform)); } @@ -80657,7 +80627,6 @@ private: { dest->blend (colour); ++dest; - } while (--width > 0); } @@ -80720,7 +80689,7 @@ private: class LinearGradientPixelGenerator { public: - LinearGradientPixelGenerator (const ColourGradient& gradient, const PixelARGB* const lookupTable_, const int numEntries_) + LinearGradientPixelGenerator (const ColourGradient& gradient, const AffineTransform& transform, const PixelARGB* const lookupTable_, const int numEntries_) : lookupTable (lookupTable_), numEntries (numEntries_) { jassert (numEntries_ >= 0); @@ -80729,16 +80698,16 @@ public: float x2 = gradient.x2; float y2 = gradient.y2; - if (! gradient.transform.isIdentity()) + if (! transform.isIdentity()) { const Line l (x2, y2, x1, y1); const Point p3 = l.getPointAlongLine (0.0, 100.0f); float x3 = p3.getX(); float y3 = p3.getY(); - gradient.transform.transformPoint (x1, y1); - gradient.transform.transformPoint (x2, y2); - gradient.transform.transformPoint (x3, y3); + transform.transformPoint (x1, y1); + transform.transformPoint (x2, y2); + transform.transformPoint (x3, y3); const Line l2 (x2, y2, x3, y3); const float prop = l2.findNearestPointTo (x1, y1); @@ -80800,7 +80769,7 @@ private: class RadialGradientPixelGenerator { public: - RadialGradientPixelGenerator (const ColourGradient& gradient, + RadialGradientPixelGenerator (const ColourGradient& gradient, const AffineTransform&, const PixelARGB* const lookupTable_, const int numEntries_) throw() : lookupTable (lookupTable_), numEntries (numEntries_), @@ -80843,10 +80812,10 @@ protected: class TransformedRadialGradientPixelGenerator : public RadialGradientPixelGenerator { public: - TransformedRadialGradientPixelGenerator (const ColourGradient& gradient, + TransformedRadialGradientPixelGenerator (const ColourGradient& gradient, const AffineTransform& transform, const PixelARGB* const lookupTable_, const int numEntries_) throw() - : RadialGradientPixelGenerator (gradient, lookupTable_, numEntries_), - inverseTransform (gradient.transform.inverted()) + : RadialGradientPixelGenerator (gradient, transform, lookupTable_, numEntries_), + inverseTransform (transform.inverted()) { tM10 = inverseTransform.mat10; tM00 = inverseTransform.mat00; @@ -80884,9 +80853,9 @@ template class GradientEdgeTableRenderer : public GradientType { public: - GradientEdgeTableRenderer (const Image::BitmapData& destData_, const ColourGradient& gradient, + GradientEdgeTableRenderer (const Image::BitmapData& destData_, const ColourGradient& gradient, const AffineTransform& transform, const PixelARGB* const lookupTable, const int numEntries) throw() - : GradientType (gradient, lookupTable, numEntries - 1), + : GradientType (gradient, transform, lookupTable, numEntries - 1), destData (destData_) { } @@ -80911,7 +80880,6 @@ public: do { (dest++)->blend (GradientType::getPixel (x++), alphaLevel); - } while (--width > 0); } else @@ -80919,7 +80887,6 @@ public: do { (dest++)->blend (GradientType::getPixel (x++)); - } while (--width > 0); } } @@ -81032,7 +80999,6 @@ private: do { dest++ ->blend (*src++); - } while (--width > 0); } @@ -81424,7 +81390,7 @@ class LLGCSavedState { public: LLGCSavedState (const Rectangle& clip_, const int xOffset_, const int yOffset_, - const Font& font_, const Graphics::FillType& fillType_, + const Font& font_, const FillType& fillType_, const Graphics::ResamplingQuality interpolationQuality_) throw() : edgeTable (new EdgeTableHolder (EdgeTable (clip_))), xOffset (xOffset_), yOffset (yOffset_), @@ -81447,15 +81413,17 @@ public: bool clipToRectangle (const Rectangle& r) throw() { dupeEdgeTableIfMultiplyReferenced(); - edgeTable->edgeTable.clipToRectangle (r); + edgeTable->edgeTable.clipToRectangle (r.translated (xOffset, yOffset)); return ! edgeTable->edgeTable.isEmpty(); } bool clipToRectangleList (const RectangleList& r) throw() { dupeEdgeTableIfMultiplyReferenced(); + RectangleList temp (r); + temp.offsetAll (xOffset, yOffset); RectangleList totalArea (edgeTable->edgeTable.getMaximumBounds()); - totalArea.subtract (r); + totalArea.subtract (temp); for (RectangleList::Iterator i (totalArea); i.next();) edgeTable->edgeTable.excludeRectangle (*i.getRectangle()); @@ -81466,14 +81434,14 @@ public: bool excludeClipRectangle (const Rectangle& r) throw() { dupeEdgeTableIfMultiplyReferenced(); - edgeTable->edgeTable.excludeRectangle (r); + edgeTable->edgeTable.excludeRectangle (r.translated (xOffset, yOffset)); return ! edgeTable->edgeTable.isEmpty(); } void clipToPath (const Path& p, const AffineTransform& transform) throw() { dupeEdgeTableIfMultiplyReferenced(); - EdgeTable et (edgeTable->edgeTable.getMaximumBounds(), p, transform); + EdgeTable et (edgeTable->edgeTable.getMaximumBounds(), p, transform.translated ((float) xOffset, (float) yOffset)); edgeTable->edgeTable.clipToEdgeTable (et); } @@ -81488,33 +81456,26 @@ public: jassert (! replaceContents); // that option is just for solid colours ColourGradient g2 (*(fillType.gradient)); - const bool isIdentity = g2.transform.isOnlyTranslation(); + AffineTransform transform (fillType.transform.translated ((float) xOffset, (float) yOffset)); + const bool isIdentity = transform.isOnlyTranslation(); if (isIdentity) { // If our translation doesn't involve any distortion, we can speed it up.. - const float tx = g2.transform.getTranslationX() + xOffset; - const float ty = g2.transform.getTranslationY() + yOffset; - - g2.x1 += tx; - g2.x2 += tx; - g2.y1 += ty; - g2.y2 += ty; - } - else - { - g2.transform = g2.transform.translated ((float) xOffset, (float) yOffset); + transform.transformPoint (g2.x1, g2.y1); + transform.transformPoint (g2.x2, g2.y2); + transform = AffineTransform::identity; } int numLookupEntries; - PixelARGB* const lookupTable = g2.createLookupTable (numLookupEntries); + PixelARGB* const lookupTable = g2.createLookupTable (transform, numLookupEntries); jassert (numLookupEntries > 0); switch (image.getFormat()) { - case Image::ARGB: renderGradient (et, destData, g2, lookupTable, numLookupEntries, isIdentity); break; - case Image::RGB: renderGradient (et, destData, g2, lookupTable, numLookupEntries, isIdentity); break; - default: renderGradient (et, destData, g2, lookupTable, numLookupEntries, isIdentity); break; + case Image::ARGB: renderGradient (et, destData, g2, transform, lookupTable, numLookupEntries, isIdentity); break; + case Image::RGB: renderGradient (et, destData, g2, transform, lookupTable, numLookupEntries, isIdentity); break; + default: renderGradient (et, destData, g2, transform, lookupTable, numLookupEntries, isIdentity); break; } juce_free (lookupTable); @@ -81522,7 +81483,7 @@ public: else if (fillType.isTiledImage()) { renderImage (image, *(fillType.image), Rectangle (0, 0, fillType.image->getWidth(), fillType.image->getHeight()), - AffineTransform::translation ((float) fillType.imageX, (float) fillType.imageY), &et); + fillType.transform, &et); } else { @@ -81596,18 +81557,19 @@ public: } } - void clipToImageAlpha (const Image& image, const Rectangle& srcClip, const AffineTransform& transform) throw() + void clipToImageAlpha (const Image& image, const Rectangle& srcClip, const AffineTransform& t) throw() { if (! image.hasAlphaChannel()) { Path p; p.addRectangle (srcClip); - clipToPath (p, transform); + clipToPath (p, t); return; } dupeEdgeTableIfMultiplyReferenced(); + const AffineTransform transform (t.translated ((float) xOffset, (float) yOffset)); const Image::BitmapData srcData (image, srcClip.getX(), srcClip.getY(), srcClip.getWidth(), srcClip.getHeight()); const bool betterQuality = (interpolationQuality != Graphics::lowResamplingQuality); EdgeTable& et = edgeTable->edgeTable; @@ -81679,9 +81641,7 @@ public: class EdgeTableHolder : public ReferenceCountedObject { public: - EdgeTableHolder (const EdgeTable& e) throw() - : edgeTable (e) - {} + EdgeTableHolder (const EdgeTable& e) throw() : edgeTable (e) {} EdgeTable edgeTable; }; @@ -81689,7 +81649,7 @@ public: ReferenceCountedObjectPtr edgeTable; int xOffset, yOffset; Font font; - Graphics::FillType fillType; + FillType fillType; Graphics::ResamplingQuality interpolationQuality; private: @@ -81702,7 +81662,7 @@ private: } template - void renderGradient (EdgeTable& et, const Image::BitmapData& destData, const ColourGradient& g, + void renderGradient (EdgeTable& et, const Image::BitmapData& destData, const ColourGradient& g, const AffineTransform& transform, const PixelARGB* const lookupTable, const int numLookupEntries, const bool isIdentity) throw() { jassert (destData.pixelStride == sizeof (DestPixelType)); @@ -81711,18 +81671,18 @@ private: { if (isIdentity) { - GradientEdgeTableRenderer renderer (destData, g, lookupTable, numLookupEntries); + GradientEdgeTableRenderer renderer (destData, g, transform, lookupTable, numLookupEntries); et.iterate (renderer); } else { - GradientEdgeTableRenderer renderer (destData, g, lookupTable, numLookupEntries); + GradientEdgeTableRenderer renderer (destData, g, transform, lookupTable, numLookupEntries); et.iterate (renderer); } } else { - GradientEdgeTableRenderer renderer (destData, g, lookupTable, numLookupEntries); + GradientEdgeTableRenderer renderer (destData, g, transform, lookupTable, numLookupEntries); et.iterate (renderer); } } @@ -81814,7 +81774,7 @@ LowLevelGraphicsSoftwareRenderer::LowLevelGraphicsSoftwareRenderer (Image& image stateStack (20) { currentState = new LLGCSavedState (Rectangle (0, 0, image_.getWidth(), image_.getHeight()), - 0, 0, Font(), Graphics::FillType(), Graphics::mediumResamplingQuality); + 0, 0, Font(), FillType(), Graphics::mediumResamplingQuality); } LowLevelGraphicsSoftwareRenderer::~LowLevelGraphicsSoftwareRenderer() @@ -81835,30 +81795,27 @@ void LowLevelGraphicsSoftwareRenderer::setOrigin (int x, int y) bool LowLevelGraphicsSoftwareRenderer::clipToRectangle (const Rectangle& r) { - return currentState->clipToRectangle (r.translated (currentState->xOffset, currentState->yOffset)); + return currentState->clipToRectangle (r); } bool LowLevelGraphicsSoftwareRenderer::clipToRectangleList (const RectangleList& clipRegion) { - RectangleList temp (clipRegion); - temp.offsetAll (currentState->xOffset, currentState->yOffset); - - return currentState->clipToRectangleList (temp); + return currentState->clipToRectangleList (clipRegion); } void LowLevelGraphicsSoftwareRenderer::excludeClipRectangle (const Rectangle& r) { - currentState->excludeClipRectangle (r.translated (currentState->xOffset, currentState->yOffset)); + currentState->excludeClipRectangle (r); } void LowLevelGraphicsSoftwareRenderer::clipToPath (const Path& path, const AffineTransform& transform) { - currentState->clipToPath (path, transform.translated ((float) currentState->xOffset, (float) currentState->yOffset)); + currentState->clipToPath (path, transform); } void LowLevelGraphicsSoftwareRenderer::clipToImageAlpha (const Image& sourceImage, const Rectangle& srcClip, const AffineTransform& transform) { - currentState->clipToImageAlpha (sourceImage, srcClip, transform.translated ((float) currentState->xOffset, (float) currentState->yOffset)); + currentState->clipToImageAlpha (sourceImage, srcClip, transform); } bool LowLevelGraphicsSoftwareRenderer::clipRegionIntersects (const Rectangle& r) @@ -81898,19 +81855,9 @@ void LowLevelGraphicsSoftwareRenderer::restoreState() } } -void LowLevelGraphicsSoftwareRenderer::setColour (const Colour& colour) +void LowLevelGraphicsSoftwareRenderer::setFill (const FillType& fillType) { - currentState->fillType.setColour (colour); -} - -void LowLevelGraphicsSoftwareRenderer::setGradient (const ColourGradient& gradient) -{ - currentState->fillType.setGradient (gradient); -} - -void LowLevelGraphicsSoftwareRenderer::setTiledFill (const Image& image, int x, int y) -{ - currentState->fillType.setTiledImage (image, x, y); + currentState->fillType = fillType; } void LowLevelGraphicsSoftwareRenderer::setOpacity (float opacity) @@ -81977,7 +81924,8 @@ public: GlyphCache() throw() : accessCounter (0), hits (0), misses (0) { - enlargeCache (120); + for (int i = 120; --i >= 0;) + glyphs.add (new CachedGlyph()); } ~GlyphCache() throw() @@ -82012,15 +81960,15 @@ public: } } - ++misses; - - if (hits + misses > (glyphs.size() << 4)) + if (hits + ++misses > (glyphs.size() << 4)) { if (misses * 2 > hits) - enlargeCache (glyphs.size() + 32); + { + for (int i = 32; --i >= 0;) + glyphs.add (new CachedGlyph()); + } - hits = 0; - misses = 0; + hits = misses = 0; oldest = glyphs.getLast(); } @@ -82033,16 +81981,8 @@ public: class CachedGlyph { public: - CachedGlyph() throw() - : glyph (0), lastAccessCount (0) - { - edgeTable = 0; - } - - ~CachedGlyph() throw() - { - delete edgeTable; - } + CachedGlyph() throw() : glyph (0), lastAccessCount (0), edgeTable (0) {} + ~CachedGlyph() throw() { delete edgeTable; } void draw (LLGCSavedState& state, Image& image, const float x, const float y) const throw() { @@ -82093,12 +82033,6 @@ public: juce_UseDebuggingNewOperator private: - void enlargeCache (const int num) throw() - { - while (glyphs.size() < num) - glyphs.add (new CachedGlyph()); - } - OwnedArray glyphs; int accessCounter, hits, misses; @@ -82132,7 +82066,6 @@ void LowLevelGraphicsSoftwareRenderer::drawGlyph (int glyphNumber, const AffineT { Path p; f.getTypeface()->getOutlineForGlyph (glyphNumber, p); - fillPath (p, AffineTransform::scale (f.getHeight() * f.getHorizontalScale(), f.getHeight()).followedBy (transform)); } } @@ -82992,17 +82925,14 @@ END_JUCE_NAMESPACE BEGIN_JUCE_NAMESPACE DrawablePath::DrawablePath() - : fillColour (0xff000000), - fillGradient (0), - strokeGradient (0), + : mainFill (FillType (Colours::black)), + strokeFill (FillType (Colours::transparentBlack)), strokeType (0.0f) { } DrawablePath::~DrawablePath() { - delete fillGradient; - delete strokeGradient; } void DrawablePath::setPath (const Path& newPath) throw() @@ -83011,16 +82941,14 @@ void DrawablePath::setPath (const Path& newPath) throw() updateOutline(); } -void DrawablePath::setFillColour (const Colour& newColour) throw() +void DrawablePath::setFill (const FillType& newFill) throw() { - deleteAndZero (fillGradient); - fillColour = newColour; + mainFill = newFill; } -void DrawablePath::setFillGradient (const ColourGradient& gradient) throw() +void DrawablePath::setStrokeFill (const FillType& newFill) throw() { - delete fillGradient; - fillGradient = new ColourGradient (gradient); + strokeFill = newFill; } void DrawablePath::setStrokeType (const PathStrokeType& newStrokeType) throw() @@ -83034,62 +82962,38 @@ void DrawablePath::setStrokeThickness (const float newThickness) throw() setStrokeType (PathStrokeType (newThickness, strokeType.getJointStyle(), strokeType.getEndStyle())); } -void DrawablePath::setStrokeColour (const Colour& newStrokeColour) throw() -{ - deleteAndZero (strokeGradient); - strokeColour = newStrokeColour; -} - -void DrawablePath::setStrokeGradient (const ColourGradient& newStrokeGradient) throw() -{ - delete strokeGradient; - strokeGradient = new ColourGradient (newStrokeGradient); -} - void DrawablePath::render (const Drawable::RenderingContext& context) const { - if (fillGradient != 0) - { - ColourGradient cg (*fillGradient); - cg.transform = cg.transform.followedBy (context.transform); - cg.multiplyOpacity (context.opacity); - context.g.setGradientFill (cg); - } - else - { - context.g.setColour (fillColour); - } + FillType f (mainFill); + if (f.isGradient()) + f.gradient->multiplyOpacity (context.opacity); + f.transform = f.transform.followedBy (context.transform); + context.g.setFillType (f); context.g.fillPath (path, context.transform); if (strokeType.getStrokeThickness() > 0.0f) { - if (strokeGradient != 0) - { - ColourGradient cg (*strokeGradient); - cg.transform = cg.transform.followedBy (context.transform); - cg.multiplyOpacity (context.opacity); - context.g.setGradientFill (cg); - } - else - { - context.g.setColour (strokeColour); - } + FillType f (strokeFill); + if (f.isGradient()) + f.gradient->multiplyOpacity (context.opacity); - context.g.fillPath (outline, context.transform); + f.transform = f.transform.followedBy (context.transform); + context.g.setFillType (f); + context.g.fillPath (stroke, context.transform); } } void DrawablePath::updateOutline() { - outline.clear(); - strokeType.createStrokedPath (outline, path, AffineTransform::identity, 4.0f); + stroke.clear(); + strokeType.createStrokedPath (stroke, path, AffineTransform::identity, 4.0f); } void DrawablePath::getBounds (float& x, float& y, float& width, float& height) const { if (strokeType.getStrokeThickness() > 0.0f) - outline.getBounds (x, y, width, height); + stroke.getBounds (x, y, width, height); else path.getBounds (x, y, width, height); } @@ -83097,7 +83001,7 @@ void DrawablePath::getBounds (float& x, float& y, float& width, float& height) c bool DrawablePath::hitTest (float x, float y) const { return path.contains (x, y) - || outline.contains (x, y); + || stroke.contains (x, y); } Drawable* DrawablePath::createCopy() const @@ -83105,105 +83009,106 @@ Drawable* DrawablePath::createCopy() const DrawablePath* const dp = new DrawablePath(); dp->path = path; - dp->outline = outline; - dp->fillColour = fillColour; - dp->strokeColour = strokeColour; - dp->fillGradient = (fillGradient != 0) ? new ColourGradient (*fillGradient) : 0; - dp->strokeGradient = (strokeGradient != 0) ? new ColourGradient (*strokeGradient) : 0; + dp->stroke = stroke; + dp->mainFill = mainFill; + dp->strokeFill = strokeFill; dp->strokeType = strokeType; return dp; } -static const Colour readColourFromBinary (InputStream& input, ColourGradient*& gradient) +static const FillType readColourFromBinary (InputStream& input) { - deleteAndZero (gradient); - switch (input.readByte()) { case 1: - return Colour ((uint32) input.readInt()); + return FillType (Colour ((uint32) input.readInt())); case 2: { - gradient = new ColourGradient(); - gradient->x1 = input.readFloat(); - gradient->y1 = input.readFloat(); - gradient->x2 = input.readFloat(); - gradient->y2 = input.readFloat(); - gradient->isRadial = input.readByte() != 0; + ColourGradient g; + g.x1 = input.readFloat(); + g.y1 = input.readFloat(); + g.x2 = input.readFloat(); + g.y2 = input.readFloat(); + g.isRadial = input.readByte() != 0; const int numColours = input.readCompressedInt(); for (int i = 0; i < numColours; ++i) { double proportion = (double) input.readFloat(); const Colour col ((uint32) input.readInt()); - gradient->addColour (proportion, col); + g.addColour (proportion, col); } - break; + return FillType (g); } default: break; } - return Colours::black; + return FillType(); } -static void writeColourToBinary (OutputStream& output, const Colour& colour, const ColourGradient* const gradient) +static void writeColourToBinary (OutputStream& output, const FillType& fillType) { - if (gradient == 0) + if (fillType.isColour()) { output.writeByte (1); - output.writeInt ((int) colour.getARGB()); + output.writeInt ((int) fillType.colour.getARGB()); } - else + else if (fillType.isGradient()) { output.writeByte (2); - output.writeFloat (gradient->x1); - output.writeFloat (gradient->y1); - output.writeFloat (gradient->x2); - output.writeFloat (gradient->y2); - output.writeByte (gradient->isRadial ? 1 : 0); + output.writeFloat (fillType.gradient->x1); + output.writeFloat (fillType.gradient->y1); + output.writeFloat (fillType.gradient->x2); + output.writeFloat (fillType.gradient->y2); + output.writeByte (fillType.gradient->isRadial ? 1 : 0); - output.writeCompressedInt (gradient->getNumColours()); + output.writeCompressedInt (fillType.gradient->getNumColours()); - for (int i = 0; i < gradient->getNumColours(); ++i) + for (int i = 0; i < fillType.gradient->getNumColours(); ++i) { - output.writeFloat ((float) gradient->getColourPosition (i)); - output.writeInt ((int) gradient->getColour (i).getARGB()); + output.writeFloat ((float) fillType.gradient->getColourPosition (i)); + output.writeInt ((int) fillType.gradient->getColour (i).getARGB()); } } + else + { + jassertfalse // xxx + } + } -static const Colour readColourFromXml (const XmlElement* xml, ColourGradient*& gradient) +static const FillType readColourFromXml (const XmlElement* xml) { - deleteAndZero (gradient); - if (xml != 0) { const String type (xml->getStringAttribute (T("type"))); if (type.equalsIgnoreCase (T("solid"))) { - return Colour ((uint32) xml->getStringAttribute (T("colour"), T("ff000000")).getHexValue32()); + return FillType (Colour ((uint32) xml->getStringAttribute (T("colour"), T("ff000000")).getHexValue32())); } else if (type.equalsIgnoreCase (T("gradient"))) { - gradient = new ColourGradient(); - gradient->x1 = (float) xml->getDoubleAttribute (T("x1")); - gradient->y1 = (float) xml->getDoubleAttribute (T("y1")); - gradient->x2 = (float) xml->getDoubleAttribute (T("x2")); - gradient->y2 = (float) xml->getDoubleAttribute (T("y2")); - gradient->isRadial = xml->getBoolAttribute (T("radial"), false); + ColourGradient g; + g.x1 = (float) xml->getDoubleAttribute (T("x1")); + g.y1 = (float) xml->getDoubleAttribute (T("y1")); + g.x2 = (float) xml->getDoubleAttribute (T("x2")); + g.y2 = (float) xml->getDoubleAttribute (T("y2")); + g.isRadial = xml->getBoolAttribute (T("radial"), false); StringArray colours; colours.addTokens (xml->getStringAttribute (T("colours")), false); for (int i = 0; i < colours.size() / 2; ++i) - gradient->addColour (colours[i * 2].getDoubleValue(), - Colour ((uint32) colours[i * 2 + 1].getHexValue32())); + g.addColour (colours[i * 2].getDoubleValue(), + Colour ((uint32) colours[i * 2 + 1].getHexValue32())); + + return FillType (g); } else { @@ -83211,42 +83116,47 @@ static const Colour readColourFromXml (const XmlElement* xml, ColourGradient*& g } } - return Colours::black; + return FillType(); } -static XmlElement* writeColourToXml (const String& tagName, const Colour& colour, const ColourGradient* const gradient) +static XmlElement* writeColourToXml (const String& tagName, const FillType& fillType) { XmlElement* const xml = new XmlElement (tagName); - if (gradient == 0) + if (fillType.isColour()) { xml->setAttribute (T("type"), T("solid")); - xml->setAttribute (T("colour"), String::toHexString ((int) colour.getARGB())); + xml->setAttribute (T("colour"), String::toHexString ((int) fillType.colour.getARGB())); } - else + else if (fillType.isGradient()) { xml->setAttribute (T("type"), T("gradient")); - xml->setAttribute (T("x1"), gradient->x1); - xml->setAttribute (T("y1"), gradient->y1); - xml->setAttribute (T("x2"), gradient->x2); - xml->setAttribute (T("y2"), gradient->y2); - xml->setAttribute (T("radial"), gradient->isRadial); + xml->setAttribute (T("x1"), fillType.gradient->x1); + xml->setAttribute (T("y1"), fillType.gradient->y1); + xml->setAttribute (T("x2"), fillType.gradient->x2); + xml->setAttribute (T("y2"), fillType.gradient->y2); + xml->setAttribute (T("radial"), fillType.gradient->isRadial); String s; - for (int i = 0; i < gradient->getNumColours(); ++i) - s << " " << gradient->getColourPosition (i) << " " << String::toHexString ((int) gradient->getColour(i).getARGB()); + for (int i = 0; i < fillType.gradient->getNumColours(); ++i) + s << " " << fillType.gradient->getColourPosition (i) + << " " << String::toHexString ((int) fillType.gradient->getColour(i).getARGB()); xml->setAttribute (T("colours"), s.trimStart()); } + else + { + jassertfalse //xxx + } return xml; } bool DrawablePath::readBinary (InputStream& input) { - fillColour = readColourFromBinary (input, fillGradient); - strokeColour = readColourFromBinary (input, strokeGradient); + mainFill = readColourFromBinary (input); + strokeFill = readColourFromBinary (input); const float strokeThickness = input.readFloat(); const int jointStyle = input.readByte(); @@ -83275,8 +83185,8 @@ bool DrawablePath::readBinary (InputStream& input) bool DrawablePath::writeBinary (OutputStream& output) const { - writeColourToBinary (output, fillColour, fillGradient); - writeColourToBinary (output, strokeColour, strokeGradient); + writeColourToBinary (output, mainFill); + writeColourToBinary (output, strokeFill); output.writeFloat (strokeType.getStrokeThickness()); output.writeByte (strokeType.getJointStyle() == PathStrokeType::mitered ? 0 @@ -83293,8 +83203,8 @@ bool DrawablePath::writeBinary (OutputStream& output) const bool DrawablePath::readXml (const XmlElement& xml) { - fillColour = readColourFromXml (xml.getChildByName (T("fill")), fillGradient); - strokeColour = readColourFromXml (xml.getChildByName (T("stroke")), strokeGradient); + mainFill = readColourFromXml (xml.getChildByName (T("fill"))); + strokeFill = readColourFromXml (xml.getChildByName (T("stroke"))); const String jointStyle (xml.getStringAttribute (T("jointStyle"), String::empty)); const String endStyle (xml.getStringAttribute (T("capStyle"), String::empty)); @@ -83314,8 +83224,8 @@ bool DrawablePath::readXml (const XmlElement& xml) void DrawablePath::writeXml (XmlElement& xml) const { - xml.addChildElement (writeColourToXml (T("fill"), fillColour, fillGradient)); - xml.addChildElement (writeColourToXml (T("stroke"), strokeColour, strokeGradient)); + xml.addChildElement (writeColourToXml (T("fill"), mainFill)); + xml.addChildElement (writeColourToXml (T("stroke"), strokeFill)); xml.setAttribute (T("strokeWidth"), (double) strokeType.getStrokeThickness()); xml.setAttribute (T("jointStyle"), @@ -83988,7 +83898,7 @@ private: DrawablePath* dp = new DrawablePath(); dp->setName (xml.getStringAttribute (T("id"))); - dp->setFillColour (Colours::transparentBlack); + dp->setFill (FillType (Colours::transparentBlack)); path.applyTransform (transform); dp->setPath (path); @@ -84005,47 +83915,21 @@ private: } } - ColourGradient* fillGradient = 0; - const Colour fillColour (getPathFillType (path, - getStyleAttribute (&xml, T("fill")), - getStyleAttribute (&xml, T("fill-opacity")), - getStyleAttribute (&xml, T("opacity")), - containsClosedSubPath ? Colours::black - : Colours::transparentBlack, - fillGradient)); - - if (fillGradient != 0) - { - fillGradient->transform = fillGradient->transform.followedBy (transform); - dp->setFillGradient (*fillGradient); - delete fillGradient; - } - else - { - dp->setFillColour (fillColour); - } + dp->setFill (getPathFillType (path, + getStyleAttribute (&xml, T("fill")), + getStyleAttribute (&xml, T("fill-opacity")), + getStyleAttribute (&xml, T("opacity")), + containsClosedSubPath ? Colours::black + : Colours::transparentBlack)); const String strokeType (getStyleAttribute (&xml, T("stroke"))); if (strokeType.isNotEmpty() && ! strokeType.equalsIgnoreCase (T("none"))) { - ColourGradient* strokeGradient = 0; - const Colour strokeColour (getPathFillType (path, strokeType, - getStyleAttribute (&xml, T("stroke-opacity")), - getStyleAttribute (&xml, T("opacity")), - Colours::transparentBlack, - strokeGradient)); - - if (strokeGradient != 0) - { - strokeGradient->transform = strokeGradient->transform.followedBy (transform); - dp->setStrokeGradient (*strokeGradient); - delete strokeGradient; - } - else - { - dp->setStrokeColour (strokeColour); - } + dp->setStrokeFill (getPathFillType (path, strokeType, + getStyleAttribute (&xml, T("stroke-opacity")), + getStyleAttribute (&xml, T("opacity")), + Colours::transparentBlack)); dp->setStrokeType (getStrokeFor (&xml)); } @@ -84085,12 +83969,11 @@ private: } } - const Colour getPathFillType (const Path& path, - const String& fill, - const String& fillOpacity, - const String& overallOpacity, - const Colour& defaultColour, - ColourGradient*& gradient) const + const FillType getPathFillType (const Path& path, + const String& fill, + const String& fillOpacity, + const String& overallOpacity, + const Colour& defaultColour) const { float opacity = 1.0f; @@ -84113,29 +83996,28 @@ private: { const XmlElement* inheritedFrom = findLinkedElement (fillXml); - gradient = new ColourGradient(); + ColourGradient gradient; - addGradientStopsIn (*gradient, inheritedFrom); - addGradientStopsIn (*gradient, fillXml); + addGradientStopsIn (gradient, inheritedFrom); + addGradientStopsIn (gradient, fillXml); - if (gradient->getNumColours() > 0) + if (gradient.getNumColours() > 0) { - gradient->addColour (0.0, gradient->getColour (0)); - gradient->addColour (1.0, gradient->getColour (gradient->getNumColours() - 1)); + gradient.addColour (0.0, gradient.getColour (0)); + gradient.addColour (1.0, gradient.getColour (gradient.getNumColours() - 1)); } else { - gradient->addColour (0.0, Colours::black); - gradient->addColour (1.0, Colours::black); + gradient.addColour (0.0, Colours::black); + gradient.addColour (1.0, Colours::black); } if (overallOpacity.isNotEmpty()) - gradient->multiplyOpacity (overallOpacity.getFloatValue()); + gradient.multiplyOpacity (overallOpacity.getFloatValue()); - jassert (gradient->getNumColours() > 0); + jassert (gradient.getNumColours() > 0); - gradient->isRadial = fillXml->hasTagName (T("radialGradient")); - gradient->transform = parseTransform (fillXml->getStringAttribute (T("gradientTransform"))); + gradient.isRadial = fillXml->hasTagName (T("radialGradient")); float width = viewBoxW; float height = viewBoxH; @@ -84147,35 +84029,34 @@ private: if (! userSpace) path.getBounds (dx, dy, width, height); - if (gradient->isRadial) + if (gradient.isRadial) { - gradient->x1 = dx + getCoordLength (fillXml->getStringAttribute (T("cx"), T("50%")), width); - gradient->y1 = dy + getCoordLength (fillXml->getStringAttribute (T("cy"), T("50%")), height); + gradient.x1 = dx + getCoordLength (fillXml->getStringAttribute (T("cx"), T("50%")), width); + gradient.y1 = dy + getCoordLength (fillXml->getStringAttribute (T("cy"), T("50%")), height); const float radius = getCoordLength (fillXml->getStringAttribute (T("r"), T("50%")), width); - gradient->x2 = gradient->x1 + radius; - gradient->y2 = gradient->y1; + gradient.x2 = gradient.x1 + radius; + gradient.y2 = gradient.y1; //xxx (the fx, fy focal point isn't handled properly here..) } else { - gradient->x1 = dx + getCoordLength (fillXml->getStringAttribute (T("x1"), T("0%")), width); - gradient->y1 = dy + getCoordLength (fillXml->getStringAttribute (T("y1"), T("0%")), height); + gradient.x1 = dx + getCoordLength (fillXml->getStringAttribute (T("x1"), T("0%")), width); + gradient.y1 = dy + getCoordLength (fillXml->getStringAttribute (T("y1"), T("0%")), height); - gradient->x2 = dx + getCoordLength (fillXml->getStringAttribute (T("x2"), T("100%")), width); - gradient->y2 = dy + getCoordLength (fillXml->getStringAttribute (T("y2"), T("0%")), height); + gradient.x2 = dx + getCoordLength (fillXml->getStringAttribute (T("x2"), T("100%")), width); + gradient.y2 = dy + getCoordLength (fillXml->getStringAttribute (T("y2"), T("0%")), height); - if (gradient->x1 == gradient->x2 && gradient->y1 == gradient->y2) - { - const Colour col (gradient->getColour (gradient->getNumColours() - 1)); - deleteAndZero (gradient); - return col; - } + if (gradient.x1 == gradient.x2 && gradient.y1 == gradient.y2) + return Colour (gradient.getColour (gradient.getNumColours() - 1)); } - return defaultColour; + FillType type (gradient); + type.transform = parseTransform (fillXml->getStringAttribute (T("gradientTransform"))) + .followedBy (transform); + return type; } } @@ -84183,7 +84064,7 @@ private: return Colours::transparentBlack; int i = 0; - Colour colour (parseColour (fill, i, defaultColour)); + const Colour colour (parseColour (fill, i, defaultColour)); return colour.withMultipliedAlpha (opacity); } @@ -254655,7 +254536,7 @@ private: context.setOrigin (-totalArea.getX(), -totalArea.getY()); - if (context.reduceClipRegion (regionsNeedingRepaint)) + if (context.clipToRectangleList (regionsNeedingRepaint)) peer->handlePaint (context); if (! peer->maskedRegion.isEmpty()) @@ -255419,31 +255300,52 @@ void juce_updateMultiMonitorInfo (Array & monitorCoords, const bool / #if JUCE_USE_XINERAMA int major_opcode, first_event, first_error; - if (XQueryExtension (display, "XINERAMA", &major_opcode, &first_event, &first_error) - && XineramaIsActive (display)) + if (XQueryExtension (display, "XINERAMA", &major_opcode, &first_event, &first_error)) { - int numMonitors = 0; - XineramaScreenInfo* const screens = XineramaQueryScreens (display, &numMonitors); + typedef Bool (*tXineramaIsActive) (Display*); + typedef XineramaScreenInfo* (*tXineramaQueryScreens) (Display*, int*); - if (screens != 0) + static tXineramaIsActive xXineramaIsActive = 0; + static tXineramaQueryScreens xXineramaQueryScreens = 0; + + if (xXineramaIsActive == 0 || xXineramaQueryScreens == 0) { - for (int i = numMonitors; --i >= 0;) + void* h = dlopen ("libXinerama.so", RTLD_GLOBAL | RTLD_NOW); + + if (h != 0) { - int index = screens[i].screen_number; + xXineramaIsActive = (tXineramaIsActive) dlsym (h, "XineramaIsActive"); + xXineramaQueryScreens = (tXineramaQueryScreens) dlsym (h, "XineramaQueryScreens"); + } + } + + if (xXineramaIsActive != 0 + && xXineramaQueryScreens != 0 + && xXineramaIsActive (display)) + { + int numMonitors = 0; + XineramaScreenInfo* const screens = xXineramaQueryScreens (display, &numMonitors); - if (index >= 0) + if (screens != 0) + { + for (int i = numMonitors; --i >= 0;) { - while (monitorCoords.size() < index) - monitorCoords.add (Rectangle (0, 0, 0, 0)); + int index = screens[i].screen_number; - monitorCoords.set (index, Rectangle (screens[i].x_org, - screens[i].y_org, - screens[i].width, - screens[i].height)); + if (index >= 0) + { + while (monitorCoords.size() < index) + monitorCoords.add (Rectangle (0, 0, 0, 0)); + + monitorCoords.set (index, Rectangle (screens[i].x_org, + screens[i].y_org, + screens[i].width, + screens[i].height)); + } } - } - XFree (screens); + XFree (screens); + } } } @@ -261582,24 +261484,16 @@ public: } } - void setColour (const Colour& colour) + void setFill (const FillType& fillType) { - state->fillType.setColour (colour); + state->fillType = fillType; - CGContextSetRGBFillColor (context, - colour.getFloatRed(), colour.getFloatGreen(), - colour.getFloatBlue(), colour.getFloatAlpha()); - CGContextSetAlpha (context, 1.0f); - } - - void setGradient (const ColourGradient& gradient) - { - state->fillType.setGradient (gradient); - } - - void setTiledFill (const Image& image, int x, int y) - { - state->fillType.setTiledImage (image, x, y); + if (fillType.isColour()) + { + CGContextSetRGBFillColor (context, fillType.colour.getFloatRed(), fillType.colour.getFloatGreen(), + fillType.colour.getFloatBlue(), fillType.colour.getFloatAlpha()); + CGContextSetAlpha (context, 1.0f); + } } void setOpacity (float opacity) @@ -261644,7 +261538,6 @@ public: { CGContextSaveGState (context); CGContextClipToRect (context, cgRect); - flip(); drawGradient(); CGContextRestoreGState (context); } @@ -261653,7 +261546,7 @@ public: CGContextSaveGState (context); CGContextClipToRect (context, cgRect); drawImage (*(state->fillType.image), Rectangle (0, 0, state->fillType.image->getWidth(), state->fillType.image->getHeight()), - AffineTransform::translation (state->fillType.imageX, state->fillType.imageY), true); + state->fillType.transform, true); CGContextRestoreGState (context); } } @@ -261674,20 +261567,20 @@ public: else CGContextEOFillPath (context); } - else if (state->fillType.isGradient()) - { - createPath (path, transform); - CGContextClip (context); - flip(); - applyTransform (state->fillType.gradient->transform); - drawGradient(); - } else { createPath (path, transform); - CGContextClip (context); - drawImage (*(state->fillType.image), Rectangle (0, 0, state->fillType.image->getWidth(), state->fillType.image->getHeight()), - AffineTransform::translation (state->fillType.imageX, state->fillType.imageY), true); + + if (path.isUsingNonZeroWinding()) + CGContextClip (context); + else + CGContextEOClip (context); + + if (state->fillType.isGradient()) + drawGradient(); + else + drawImage (*(state->fillType.image), Rectangle (0, 0, state->fillType.image->getWidth(), state->fillType.image->getHeight()), + state->fillType.transform, true); } CGContextRestoreGState (context); @@ -261862,7 +261755,7 @@ private: { } - Graphics::FillType fillType; + FillType fillType; Font font; CGFontRef fontRef; CGAffineTransform fontTransform; @@ -261887,10 +261780,10 @@ private: outData[3] = colour.getAlpha() / 255.0f; } - CGShadingRef createGradient (const ColourGradient* const gradient) throw() + CGShadingRef createGradient (const AffineTransform& transform, const ColourGradient* const gradient) throw() { delete gradientLookupTable; - gradientLookupTable = gradient->createLookupTable (numGradientLookupEntries); + gradientLookupTable = gradient->createLookupTable (transform, numGradientLookupEntries); --numGradientLookupEntries; CGShadingRef result = 0; @@ -261916,10 +261809,13 @@ private: void drawGradient() throw() { + flip(); + applyTransform (state->fillType.transform); + CGContextSetAlpha (context, 1.0f); CGContextSetInterpolationQuality (context, kCGInterpolationDefault); // (This is required for 10.4, where there's a crash if // you draw a gradient with high quality interp enabled). - CGShadingRef shading = createGradient (state->fillType.gradient); + CGShadingRef shading = createGradient (state->fillType.transform, state->fillType.gradient); CGContextDrawShading (context, shading); CGShadingRelease (shading); } @@ -266037,24 +265933,16 @@ public: } } - void setColour (const Colour& colour) + void setFill (const FillType& fillType) { - state->fillType.setColour (colour); + state->fillType = fillType; - CGContextSetRGBFillColor (context, - colour.getFloatRed(), colour.getFloatGreen(), - colour.getFloatBlue(), colour.getFloatAlpha()); - CGContextSetAlpha (context, 1.0f); - } - - void setGradient (const ColourGradient& gradient) - { - state->fillType.setGradient (gradient); - } - - void setTiledFill (const Image& image, int x, int y) - { - state->fillType.setTiledImage (image, x, y); + if (fillType.isColour()) + { + CGContextSetRGBFillColor (context, fillType.colour.getFloatRed(), fillType.colour.getFloatGreen(), + fillType.colour.getFloatBlue(), fillType.colour.getFloatAlpha()); + CGContextSetAlpha (context, 1.0f); + } } void setOpacity (float opacity) @@ -266099,7 +265987,6 @@ public: { CGContextSaveGState (context); CGContextClipToRect (context, cgRect); - flip(); drawGradient(); CGContextRestoreGState (context); } @@ -266108,7 +265995,7 @@ public: CGContextSaveGState (context); CGContextClipToRect (context, cgRect); drawImage (*(state->fillType.image), Rectangle (0, 0, state->fillType.image->getWidth(), state->fillType.image->getHeight()), - AffineTransform::translation (state->fillType.imageX, state->fillType.imageY), true); + state->fillType.transform, true); CGContextRestoreGState (context); } } @@ -266129,20 +266016,20 @@ public: else CGContextEOFillPath (context); } - else if (state->fillType.isGradient()) - { - createPath (path, transform); - CGContextClip (context); - flip(); - applyTransform (state->fillType.gradient->transform); - drawGradient(); - } else { createPath (path, transform); - CGContextClip (context); - drawImage (*(state->fillType.image), Rectangle (0, 0, state->fillType.image->getWidth(), state->fillType.image->getHeight()), - AffineTransform::translation (state->fillType.imageX, state->fillType.imageY), true); + + if (path.isUsingNonZeroWinding()) + CGContextClip (context); + else + CGContextEOClip (context); + + if (state->fillType.isGradient()) + drawGradient(); + else + drawImage (*(state->fillType.image), Rectangle (0, 0, state->fillType.image->getWidth(), state->fillType.image->getHeight()), + state->fillType.transform, true); } CGContextRestoreGState (context); @@ -266317,7 +266204,7 @@ private: { } - Graphics::FillType fillType; + FillType fillType; Font font; CGFontRef fontRef; CGAffineTransform fontTransform; @@ -266342,10 +266229,10 @@ private: outData[3] = colour.getAlpha() / 255.0f; } - CGShadingRef createGradient (const ColourGradient* const gradient) throw() + CGShadingRef createGradient (const AffineTransform& transform, const ColourGradient* const gradient) throw() { delete gradientLookupTable; - gradientLookupTable = gradient->createLookupTable (numGradientLookupEntries); + gradientLookupTable = gradient->createLookupTable (transform, numGradientLookupEntries); --numGradientLookupEntries; CGShadingRef result = 0; @@ -266371,10 +266258,13 @@ private: void drawGradient() throw() { + flip(); + applyTransform (state->fillType.transform); + CGContextSetAlpha (context, 1.0f); CGContextSetInterpolationQuality (context, kCGInterpolationDefault); // (This is required for 10.4, where there's a crash if // you draw a gradient with high quality interp enabled). - CGShadingRef shading = createGradient (state->fillType.gradient); + CGShadingRef shading = createGradient (state->fillType.transform, state->fillType.gradient); CGContextDrawShading (context, shading); CGShadingRelease (shading); } diff --git a/juce_amalgamated.h b/juce_amalgamated.h index 63b1aeeddd..7089ea8ae2 100644 --- a/juce_amalgamated.h +++ b/juce_amalgamated.h @@ -19703,6 +19703,10 @@ private: #endif // __JUCE_COLOURS_JUCEHEADER__ /********* End of inlined file: juce_Colours.h *********/ +/********* Start of inlined file: juce_FillType.h *********/ +#ifndef __JUCE_GRAPHICS_JUCEHEADER__x +#define __JUCE_GRAPHICS_JUCEHEADER__x + /********* Start of inlined file: juce_ColourGradient.h *********/ #ifndef __JUCE_COLOURGRADIENT_JUCEHEADER__ #define __JUCE_COLOURGRADIENT_JUCEHEADER__ @@ -19798,7 +19802,7 @@ public: The caller must delete the array that is returned using juce_free(). */ - PixelARGB* createLookupTable (int& numEntries) const throw(); + PixelARGB* createLookupTable (const AffineTransform& transform, int& numEntries) const throw(); /** Returns true if all colours are opaque. */ bool isOpaque() const throw(); @@ -19819,9 +19823,6 @@ public: */ bool isRadial; - /** A transform to apply to the resultant gradient shape */ - AffineTransform transform; - juce_UseDebuggingNewOperator private: @@ -19831,6 +19832,92 @@ private: #endif // __JUCE_COLOURGRADIENT_JUCEHEADER__ /********* End of inlined file: juce_ColourGradient.h *********/ +class Image; + +/** + Represents a colour or fill pattern to use for rendering paths. + + This is used by the Graphics and DrawablePath classes as a way to encapsulate + a brush type. It can either be a solid colour, a gradient, or a tiled image. + + @see Graphics::setFillType, DrawablePath::setFill +*/ +class JUCE_API FillType +{ +public: + /** Creates a default fill type, of solid black. */ + FillType() throw(); + + /** Creates a fill type of a solid colour. + @see setColour + */ + FillType (const Colour& colour) throw(); + + /** Creates a gradient fill type. + @see setGradient + */ + FillType (const ColourGradient& gradient) throw(); + + /** Creates a tiled image fill type. The transform allows you to set the scaling, offset + and rotation of the pattern. + @see setTiledImage + */ + FillType (const Image& image, const AffineTransform& transform) throw(); + + /** Creates a copy of another FillType. */ + FillType (const FillType& other) throw(); + + /** Makes a copy of another FillType. */ + const FillType& operator= (const FillType& other) throw(); + + /** Destructor. */ + ~FillType() throw(); + + /** Returns true if this is a solid colour fill, and not a gradient or image. */ + bool isColour() const throw() { return gradient == 0 && image == 0; } + + /** Returns true if this is a gradient fill. */ + bool isGradient() const throw() { return gradient != 0; } + + /** Returns true if this is a tiled image pattern fill. */ + bool isTiledImage() const throw() { return image != 0; } + + /** Turns this object into a solid colour fill. + If the object was an image or gradient, those fields will no longer be valid. */ + void setColour (const Colour& newColour) throw(); + + /** Turns this object into a gradient fill. */ + void setGradient (const ColourGradient& newGradient) throw(); + + /** Turns this object into a tiled image fill type. The transform allows you to set + the scaling, offset and rotation of the pattern. + */ + void setTiledImage (const Image& image, const AffineTransform& transform) throw(); + + /** Returns the solid colour being used. */ + Colour colour; + + /** Returns the gradient that should be used for filling. + This will be zero if the object is some other type of fill. + */ + ColourGradient* gradient; + + /** Returns the image that should be used for tiling. + The FillType object just keeps a pointer to this image, it doesn't own it, so you have to + be careful to make sure the image doesn't get deleted while it's being used. + */ + const Image* image; + + /** The transform that should be applied to the image or gradient that's being drawn. + */ + AffineTransform transform; + + juce_UseDebuggingNewOperator +}; + +#endif // __JUCE_GRAPHICS_JUCEHEADER__ +/********* End of inlined file: juce_FillType.h *********/ + /********* Start of inlined file: juce_RectanglePlacement.h *********/ #ifndef __JUCE_RECTANGLEPLACEMENT_JUCEHEADER__ #define __JUCE_RECTANGLEPLACEMENT_JUCEHEADER__ @@ -20027,6 +20114,11 @@ public: const int anchorY, const float opacity) throw(); + /** Changes the current fill settings. + @see setColour, setGradientFill, setTiledImageFill + */ + void setFillType (const FillType& newFill) throw(); + /** Changes the font to use for subsequent text-drawing functions. Note there's also a setFont (float, int) method to quickly change the size and @@ -20533,7 +20625,7 @@ public: /** Intersects the current clipping region with another region. @returns true if the resulting clipping region is non-zero in size - @see setOrigin, clipRegionIntersects, getClipLeft, getClipRight, getClipWidth, getClipHeight + @see setOrigin, clipRegionIntersects */ bool reduceClipRegion (const int x, const int y, const int width, const int height) throw(); @@ -20541,10 +20633,34 @@ public: /** Intersects the current clipping region with a rectangle list region. @returns true if the resulting clipping region is non-zero in size - @see setOrigin, clipRegionIntersects, getClipLeft, getClipRight, getClipWidth, getClipHeight + @see setOrigin, clipRegionIntersects */ bool reduceClipRegion (const RectangleList& clipRegion) throw(); + /** Intersects the current clipping region with a path. + + @returns true if the resulting clipping region is non-zero in size + @see reduceClipRegion + */ + bool reduceClipRegion (const Path& path, const AffineTransform& transform = AffineTransform::identity) throw(); + + /** Intersects the current clipping region with an image's alpha-channel. + + The current clipping path is intersected with the area covered by this image's + alpha-channel, after the image has been transformed by the specified matrix. + + @param image the image whose alpha-channel should be used. If the image doesn't + have an alpha-channel, it is treated as entirely opaque. + @param sourceClipRegion a subsection of the image that should be used. To use the + entire image, just pass a rectangle of bounds + (0, 0, image.getWidth(), image.getHeight()). + @param transform a matrix to apply to the image + @returns true if the resulting clipping region is non-zero in size + @see reduceClipRegion + */ + bool reduceClipRegion (const Image& image, const Rectangle& sourceClipRegion, + const AffineTransform& transform) throw(); + /** Excludes a rectangle to stop it being drawn into. */ void excludeClipRegion (const int x, const int y, const int width, const int height) throw(); @@ -20594,33 +20710,6 @@ public: /** @internal */ LowLevelGraphicsContext* getInternalContext() const throw() { return context; } - class FillType - { - public: - FillType() throw(); - FillType (const Colour& colour) throw(); - FillType (const ColourGradient& gradient) throw(); - FillType (Image* const image, const int x, const int y) throw(); - FillType (const FillType& other) throw(); - const FillType& operator= (const FillType& other) throw(); - ~FillType() throw(); - - bool isColour() const throw() { return gradient == 0 && image == 0; } - bool isGradient() const throw() { return gradient != 0; } - bool isTiledImage() const throw() { return image != 0; } - - void setColour (const Colour& newColour) throw(); - void setGradient (const ColourGradient& newGradient) throw(); - void setTiledImage (const Image& image, const int imageX, const int imageY) throw(); - - Colour colour; - ColourGradient* gradient; - const Image* image; - int imageX, imageY; - - juce_UseDebuggingNewOperator - }; - private: LowLevelGraphicsContext* const context; @@ -39717,9 +39806,7 @@ public: virtual void saveState() = 0; virtual void restoreState() = 0; - virtual void setColour (const Colour& colour) = 0; - virtual void setGradient (const ColourGradient& gradient) = 0; - virtual void setTiledFill (const Image& image, int x, int y) = 0; + virtual void setFill (const FillType& fillType) = 0; virtual void setOpacity (float opacity) = 0; virtual void setInterpolationQuality (Graphics::ResamplingQuality quality) = 0; @@ -39782,14 +39869,10 @@ public: void saveState(); void restoreState(); - void setColour (const Colour& colour); - void setGradient (const ColourGradient& gradient); - void setTiledFill (const Image& image, int x, int y); - + void setFill (const FillType& fillType); void setOpacity (float opacity); void setInterpolationQuality (Graphics::ResamplingQuality quality); - void fillAll (const bool replaceContents); void fillRect (const Rectangle& r, const bool replaceExistingContents); void fillPath (const Path& path, const AffineTransform& transform); @@ -39848,45 +39931,36 @@ public: bool isVectorDevice() const; void setOrigin (int x, int y); - bool reduceClipRegion (int x, int y, int w, int h); - bool reduceClipRegion (const RectangleList& clipRegion); - void excludeClipRegion (int x, int y, int w, int h); + bool clipToRectangle (const Rectangle& r); + bool clipToRectangleList (const RectangleList& clipRegion); + void excludeClipRectangle (const Rectangle& r); + void clipToPath (const Path& path, const AffineTransform& transform); + void clipToImageAlpha (const Image& sourceImage, const Rectangle& srcClip, const AffineTransform& transform); void saveState(); void restoreState(); - bool clipRegionIntersects (int x, int y, int w, int h); + bool clipRegionIntersects (const Rectangle& r); const Rectangle getClipBounds() const; bool isClipEmpty() const; - void setColour (const Colour& colour); - void setGradient (const ColourGradient& gradient); + void setFill (const FillType& fillType); void setOpacity (float opacity); void setInterpolationQuality (Graphics::ResamplingQuality quality); - void fillRect (int x, int y, int w, int h, const bool replaceExistingContents); + void fillRect (const Rectangle& r, const bool replaceExistingContents); void fillPath (const Path& path, const AffineTransform& transform); - void fillPathWithImage (const Path& path, const AffineTransform& transform, - const Image& image, int imageX, int imageY); - - void fillAlphaChannel (const Image& alphaImage, int imageX, int imageY); - void fillAlphaChannelWithImage (const Image& alphaImage, int alphaImageX, int alphaImageY, - const Image& fillerImage, int fillerImageX, int fillerImageY); - - void blendImage (const Image& sourceImage, int destX, int destY, int destW, int destH, - int sourceX, int sourceY); - - void blendImageWarping (const Image& sourceImage, int srcClipX, int srcClipY, int srcClipW, int srcClipH, - const AffineTransform& transform); + void drawImage (const Image& sourceImage, const Rectangle& srcClip, + const AffineTransform& transform, const bool fillEntireClipAsTiles); void drawLine (double x1, double y1, double x2, double y2); void drawVerticalLine (const int x, double top, double bottom); void drawHorizontalLine (const int x, double top, double bottom); + const Font getFont(); void setFont (const Font& newFont); - void drawGlyph (int glyphNumber, float x, float y); void drawGlyph (int glyphNumber, const AffineTransform& transform); juce_UseDebuggingNewOperator @@ -39894,27 +39968,21 @@ public: protected: OutputStream& out; - RectangleList* clip; - int totalWidth, totalHeight, xOffset, yOffset; + int totalWidth, totalHeight; bool needToClip; - Colour lastColour, colour; - ColourGradient* gradient; - Font font; + Colour lastColour; struct SavedState { - SavedState (RectangleList* const clip, const int xOffset, const int yOffset, - const Colour& colour, ColourGradient* const gradient, const Font& font); + SavedState(); ~SavedState(); - RectangleList* clip; - const int xOffset, yOffset; - Colour colour; - ColourGradient* gradient; + RectangleList clip; + int xOffset, yOffset; + FillType fillType; Font font; private: - SavedState (const SavedState&); const SavedState& operator= (const SavedState&); }; @@ -41434,33 +41502,33 @@ public: /** Returns the current path. */ const Path& getPath() const throw() { return path; } - /** Sets a colour to fill the path with. + /** Sets a fill type for the path. This colour is used to fill the path - if you don't want the path to be - filled (e.g. if you're just drawing an outline), set this colour to be - transparent. + filled (e.g. if you're just drawing an outline), set this to a transparent + colour. - @see setPath, setOutlineColour, setFillGradient + @see setPath, setStrokeFill */ - void setFillColour (const Colour& newColour) throw(); + void setFill (const FillType& newFill) throw(); - /** Sets a gradient to use to fill the path. + /** Returns the current fill type. + @see setFill */ - void setFillGradient (const ColourGradient& newGradient) throw(); + const FillType& getFill() const throw() { return mainFill; } - /** Sets the colour with which the outline will be drawn. - @see setStrokeGradient + /** Sets the fill type with which the outline will be drawn. + @see setFill */ - void setStrokeColour (const Colour& newStrokeColour) throw(); + void setStrokeFill (const FillType& newStrokeFill) throw(); - /** Sets a gradient with with the outline will be drawn. - @see setStrokeColour + /** Returns the current stroke fill. + @see setStrokeFill */ - void setStrokeGradient (const ColourGradient& newStrokeGradient) throw(); + const FillType& getStrokeFill() const throw() { return strokeFill; } /** Changes the properties of the outline that will be drawn around the path. If the stroke has 0 thickness, no stroke will be drawn. - @see setStrokeThickness, setStrokeColour */ void setStrokeType (const PathStrokeType& newStrokeType) throw(); @@ -41471,7 +41539,7 @@ public: void setStrokeThickness (const float newThickness) throw(); /** Returns the current outline style. */ - const PathStrokeType& getStrokeType() const throw() { return strokeType; } + const PathStrokeType& getStrokeType() const throw() { return strokeType; } /** @internal */ void render (const Drawable::RenderingContext& context) const; @@ -41493,10 +41561,8 @@ public: juce_UseDebuggingNewOperator private: - Path path, outline; - Colour fillColour, strokeColour; - ColourGradient* fillGradient; - ColourGradient* strokeGradient; + Path path, stroke; + FillType mainFill, strokeFill; PathStrokeType strokeType; void updateOutline(); @@ -44093,6 +44159,21 @@ public: */ virtual const String getDescriptionForKeyPress (const KeyPress& key); + /** A set of colour IDs to use to change the colour of various aspects of the editor. + + These constants can be used either via the Component::setColour(), or LookAndFeel::setColour() + methods. + + To change the colours of the menu that pops up + + @see Component::setColour, Component::findColour, LookAndFeel::setColour, LookAndFeel::findColour + */ + enum ColourIds + { + backgroundColourId = 0x100ad00, /**< The background colour to fill the editor background. */ + textColourId = 0x100ad01, /**< The colour for the text. */ + }; + /** @internal */ void parentHierarchyChanged(); /** @internal */ @@ -44116,7 +44197,6 @@ private: friend class KeyCategoryTreeViewItem; friend class KeyMappingItemComponent; friend class KeyMappingChangeButton; - Colour backgroundColour, textColour; TextButton* resetButton; void assignNewKey (const CommandID commandID, int index); @@ -54872,6 +54952,8 @@ public: virtual void drawLevelMeter (Graphics& g, int width, int height, float level); + virtual void drawKeymapChangeButton (Graphics& g, int width, int height, Button& button, const String& keyDescription); + /** */ virtual void playAlertSound(); diff --git a/src/audio/plugins/formats/juce_AudioUnitPluginFormat.mm b/src/audio/plugins/formats/juce_AudioUnitPluginFormat.mm index 88b7681390..9392fb7205 100644 --- a/src/audio/plugins/formats/juce_AudioUnitPluginFormat.mm +++ b/src/audio/plugins/formats/juce_AudioUnitPluginFormat.mm @@ -1521,7 +1521,10 @@ const String AudioUnitPluginFormat::getNameOfPluginFromIdentifier (const String& bool AudioUnitPluginFormat::doesPluginStillExist (const PluginDescription& desc) { - return File (desc.fileOrIdentifier).exists(); + if (desc.fileOrIdentifier.startsWithIgnoreCase (auIdentifierPrefix)) + return fileMightContainThisPluginType (desc.fileOrIdentifier); + else + return File (desc.fileOrIdentifier).exists(); } const FileSearchPath AudioUnitPluginFormat::getDefaultLocationsToSearch() diff --git a/src/gui/components/filebrowser/juce_FileSearchPathListComponent.cpp b/src/gui/components/filebrowser/juce_FileSearchPathListComponent.cpp index 7eddd5042c..948a4ad334 100644 --- a/src/gui/components/filebrowser/juce_FileSearchPathListComponent.cpp +++ b/src/gui/components/filebrowser/juce_FileSearchPathListComponent.cpp @@ -62,7 +62,7 @@ FileSearchPathListComponent::FileSearchPathListComponent() Path arrowPath; arrowPath.addArrow (50.0f, 100.0f, 50.0f, 0.0, 40.0f, 100.0f, 50.0f); DrawablePath arrowImage; - arrowImage.setFillColour (Colours::black.withAlpha (0.4f)); + arrowImage.setFill (Colours::black.withAlpha (0.4f)); arrowImage.setPath (arrowPath); ((DrawableButton*) upButton)->setImages (&arrowImage); @@ -75,7 +75,7 @@ FileSearchPathListComponent::FileSearchPathListComponent() Path arrowPath; arrowPath.addArrow (50.0f, 0.0f, 50.0f, 100.0f, 40.0f, 100.0f, 50.0f); DrawablePath arrowImage; - arrowImage.setFillColour (Colours::black.withAlpha (0.4f)); + arrowImage.setFill (Colours::black.withAlpha (0.4f)); arrowImage.setPath (arrowPath); ((DrawableButton*) downButton)->setImages (&arrowImage); diff --git a/src/gui/components/keyboard/juce_KeyMappingEditorComponent.cpp b/src/gui/components/keyboard/juce_KeyMappingEditorComponent.cpp index 879355cd9c..b21eadacd3 100644 --- a/src/gui/components/keyboard/juce_KeyMappingEditorComponent.cpp +++ b/src/gui/components/keyboard/juce_KeyMappingEditorComponent.cpp @@ -35,6 +35,7 @@ BEGIN_JUCE_NAMESPACE #include "juce_KeyMappingEditorComponent.h" #include "../menus/juce_PopupMenu.h" #include "../windows/juce_AlertWindow.h" +#include "../lookandfeel/juce_LookAndFeel.h" #include "../../../text/juce_LocalisedStrings.h" const int maxKeys = 3; @@ -67,44 +68,8 @@ public: void paintButton (Graphics& g, bool isOver, bool isDown) { - if (keyNum >= 0) - { - if (isEnabled()) - { - const float alpha = isDown ? 0.3f : (isOver ? 0.15f : 0.08f); - g.fillAll (owner->textColour.withAlpha (alpha)); - - g.setOpacity (0.3f); - g.drawBevel (0, 0, getWidth(), getHeight(), 2); - } - - g.setColour (owner->textColour); - g.setFont (getHeight() * 0.6f); - g.drawFittedText (getName(), - 3, 0, getWidth() - 6, getHeight(), - Justification::centred, 1); - } - else - { - const float thickness = 7.0f; - const float indent = 22.0f; - - Path p; - p.addEllipse (0.0f, 0.0f, 100.0f, 100.0f); - p.addRectangle (indent, 50.0f - thickness, 100.0f - indent * 2.0f, thickness * 2.0f); - p.addRectangle (50.0f - thickness, indent, thickness * 2.0f, 50.0f - indent - thickness); - p.addRectangle (50.0f - thickness, 50.0f + thickness, thickness * 2.0f, 50.0f - indent - thickness); - p.setUsingNonZeroWinding (false); - - g.setColour (owner->textColour.withAlpha (isDown ? 0.7f : (isOver ? 0.5f : 0.3f))); - g.fillPath (p, p.getTransformToScaleToFit (2.0f, 2.0f, getWidth() - 4.0f, getHeight() - 4.0f, true)); - } - - if (hasKeyboardFocus (false)) - { - g.setColour (owner->textColour.withAlpha (0.4f)); - g.drawRect (0, 0, getWidth(), getHeight()); - } + getLookAndFeel().drawKeymapChangeButton (g, getWidth(), getHeight(), *this, + keyNum >= 0 ? getName() : String::empty); } void clicked() @@ -199,7 +164,7 @@ public: void paint (Graphics& g) { g.setFont (getHeight() * 0.7f); - g.setColour (owner->textColour); + g.setColour (findColour (KeyMappingEditorComponent::textColourId)); g.drawFittedText (owner->getMappings()->getCommandManager()->getNameOfCommand (commandID), 4, 0, jmax (40, getChildComponent (0)->getX() - 5), getHeight(), @@ -287,7 +252,7 @@ public: void paintItem (Graphics& g, int width, int height) { g.setFont (height * 0.6f, Font::bold); - g.setColour (owner->textColour); + g.setColour (owner->findColour (KeyMappingEditorComponent::textColourId)); g.drawText (categoryName, 2, 0, width - 2, height, @@ -329,8 +294,7 @@ private: //============================================================================== KeyMappingEditorComponent::KeyMappingEditorComponent (KeyPressMappingSet* const mappingManager, const bool showResetToDefaultButton) - : mappings (mappingManager), - textColour (Colours::black) + : mappings (mappingManager) { jassert (mappingManager != 0); // can't be null! @@ -347,7 +311,7 @@ KeyMappingEditorComponent::KeyMappingEditorComponent (KeyPressMappingSet* const } addAndMakeVisible (tree = new TreeView()); - tree->setColour (TreeView::backgroundColourId, backgroundColour); + tree->setColour (TreeView::backgroundColourId, findColour (backgroundColourId)); tree->setRootItemVisible (false); tree->setDefaultOpenness (true); tree->setRootItem (this); @@ -371,11 +335,11 @@ const String KeyMappingEditorComponent::getUniqueName() const } void KeyMappingEditorComponent::setColours (const Colour& mainBackground, - const Colour& textColour_) + const Colour& textColour) { - backgroundColour = mainBackground; - textColour = textColour_; - tree->setColour (TreeView::backgroundColourId, backgroundColour); + setColour (backgroundColourId, mainBackground); + setColour (textColourId, textColour); + tree->setColour (TreeView::backgroundColourId, mainBackground); } void KeyMappingEditorComponent::parentHierarchyChanged() diff --git a/src/gui/components/keyboard/juce_KeyMappingEditorComponent.h b/src/gui/components/keyboard/juce_KeyMappingEditorComponent.h index ff62eefca3..a4fd5b05df 100644 --- a/src/gui/components/keyboard/juce_KeyMappingEditorComponent.h +++ b/src/gui/components/keyboard/juce_KeyMappingEditorComponent.h @@ -99,6 +99,21 @@ public: */ virtual const String getDescriptionForKeyPress (const KeyPress& key); + //============================================================================== + /** A set of colour IDs to use to change the colour of various aspects of the editor. + + These constants can be used either via the Component::setColour(), or LookAndFeel::setColour() + methods. + + To change the colours of the menu that pops up + + @see Component::setColour, Component::findColour, LookAndFeel::setColour, LookAndFeel::findColour + */ + enum ColourIds + { + backgroundColourId = 0x100ad00, /**< The background colour to fill the editor background. */ + textColourId = 0x100ad01, /**< The colour for the text. */ + }; //============================================================================== /** @internal */ @@ -124,7 +139,6 @@ private: friend class KeyCategoryTreeViewItem; friend class KeyMappingItemComponent; friend class KeyMappingChangeButton; - Colour backgroundColour, textColour; TextButton* resetButton; void assignNewKey (const CommandID commandID, int index); diff --git a/src/gui/components/keyboard/juce_KeyPress.cpp b/src/gui/components/keyboard/juce_KeyPress.cpp index 5223c754ee..ec8deaab35 100644 --- a/src/gui/components/keyboard/juce_KeyPress.cpp +++ b/src/gui/components/keyboard/juce_KeyPress.cpp @@ -46,6 +46,9 @@ KeyPress::KeyPress (const int keyCode_, mods (mods_), textCharacter (textCharacter_) { + // If you specify an upper-case letter but no shift key, how is the user supposed to press it!? + // Stick to lower-case letters when defining a keypress, to avoid ambiguity. + jassert (! (CharacterFunctions::isUpperCase (textCharacter_) && ! mods.isShiftDown())); } KeyPress::KeyPress (const int keyCode_) throw() diff --git a/src/gui/components/lookandfeel/juce_LookAndFeel.cpp b/src/gui/components/lookandfeel/juce_LookAndFeel.cpp index ed3566109a..647075f525 100644 --- a/src/gui/components/lookandfeel/juce_LookAndFeel.cpp +++ b/src/gui/components/lookandfeel/juce_LookAndFeel.cpp @@ -49,6 +49,7 @@ BEGIN_JUCE_NAMESPACE #include "../controls/juce_ToolbarItemComponent.h" #include "../controls/juce_ProgressBar.h" #include "../controls/juce_TreeView.h" +#include "../keyboard/juce_KeyMappingEditorComponent.h" #include "../code_editor/juce_CodeEditorComponent.h" #include "../filebrowser/juce_FilenameComponent.h" #include "../filebrowser/juce_DirectoryContentsDisplayComponent.h" @@ -218,6 +219,9 @@ LookAndFeel::LookAndFeel() ColourSelector::backgroundColourId, 0xffe5e5e5, ColourSelector::labelTextColourId, 0xff000000, + KeyMappingEditorComponent::backgroundColourId, 0x00000000, + KeyMappingEditorComponent::textColourId, 0xff000000, + FileSearchPathListComponent::backgroundColourId, 0xffffffff, }; @@ -2340,7 +2344,7 @@ Button* LookAndFeel::createTabBarExtrasButton() DrawablePath ellipse; ellipse.setPath (p); - ellipse.setFillColour (Colour (0x99ffffff)); + ellipse.setFill (Colour (0x99ffffff)); p.clear(); p.addEllipse (0.0f, 0.0f, 100.0f, 100.0f); @@ -2351,13 +2355,13 @@ Button* LookAndFeel::createTabBarExtrasButton() DrawablePath dp; dp.setPath (p); - dp.setFillColour (Colour (0x59000000)); + dp.setFill (Colour (0x59000000)); DrawableComposite normalImage; normalImage.insertDrawable (ellipse); normalImage.insertDrawable (dp); - dp.setFillColour (Colour (0xcc000000)); + dp.setFill (Colour (0xcc000000)); DrawableComposite overImage; overImage.insertDrawable (ellipse); @@ -2604,7 +2608,7 @@ Button* LookAndFeel::createFileBrowserGoUpButton() arrowPath.addArrow (50.0f, 100.0f, 50.0f, 0.0, 40.0f, 100.0f, 50.0f); DrawablePath arrowImage; - arrowImage.setFillColour (Colours::black.withAlpha (0.4f)); + arrowImage.setFill (Colours::black.withAlpha (0.4f)); arrowImage.setPath (arrowPath); goUpButton->setImages (&arrowImage); @@ -2757,6 +2761,51 @@ void LookAndFeel::drawLevelMeter (Graphics& g, int width, int height, float leve } } +//============================================================================== +void LookAndFeel::drawKeymapChangeButton (Graphics& g, int width, int height, Button& button, const String& keyDescription) +{ + const Colour textColour (button.findColour (KeyMappingEditorComponent::textColourId, true)); + + if (keyDescription.isNotEmpty()) + { + if (button.isEnabled()) + { + const float alpha = button.isDown() ? 0.3f : (button.isOver() ? 0.15f : 0.08f); + g.fillAll (textColour.withAlpha (alpha)); + + g.setOpacity (0.3f); + g.drawBevel (0, 0, width, height, 2); + } + + g.setColour (textColour); + g.setFont (height * 0.6f); + g.drawFittedText (keyDescription, + 3, 0, width - 6, height, + Justification::centred, 1); + } + else + { + const float thickness = 7.0f; + const float indent = 22.0f; + + Path p; + p.addEllipse (0.0f, 0.0f, 100.0f, 100.0f); + p.addRectangle (indent, 50.0f - thickness, 100.0f - indent * 2.0f, thickness * 2.0f); + p.addRectangle (50.0f - thickness, indent, thickness * 2.0f, 50.0f - indent - thickness); + p.addRectangle (50.0f - thickness, 50.0f + thickness, thickness * 2.0f, 50.0f - indent - thickness); + p.setUsingNonZeroWinding (false); + + g.setColour (textColour.withAlpha (button.isDown() ? 0.7f : (button.isOver() ? 0.5f : 0.3f))); + g.fillPath (p, p.getTransformToScaleToFit (2.0f, 2.0f, width - 4.0f, height - 4.0f, true)); + } + + if (button.hasKeyboardFocus (false)) + { + g.setColour (textColour.withAlpha (0.4f)); + g.drawRect (0, 0, width, height); + } +} + //============================================================================== static void createRoundedPath (Path& p, const float x, const float y, diff --git a/src/gui/components/lookandfeel/juce_LookAndFeel.h b/src/gui/components/lookandfeel/juce_LookAndFeel.h index 0389a75d3b..2e9c2a0b13 100644 --- a/src/gui/components/lookandfeel/juce_LookAndFeel.h +++ b/src/gui/components/lookandfeel/juce_LookAndFeel.h @@ -594,6 +594,8 @@ public: //============================================================================== virtual void drawLevelMeter (Graphics& g, int width, int height, float level); + virtual void drawKeymapChangeButton (Graphics& g, int width, int height, Button& button, const String& keyDescription); + //============================================================================== /** */ diff --git a/src/gui/components/lookandfeel/juce_OldSchoolLookAndFeel.cpp b/src/gui/components/lookandfeel/juce_OldSchoolLookAndFeel.cpp index 18a9786966..beb0280650 100644 --- a/src/gui/components/lookandfeel/juce_OldSchoolLookAndFeel.cpp +++ b/src/gui/components/lookandfeel/juce_OldSchoolLookAndFeel.cpp @@ -557,7 +557,7 @@ Button* OldSchoolLookAndFeel::createDocumentWindowButton (int buttonType) DrawableButton* b = new DrawableButton ("minimise", DrawableButton::ImageFitted); DrawablePath dp; dp.setPath (shape); - dp.setFillColour (Colours::black.withAlpha (0.3f)); + dp.setFill (Colours::black.withAlpha (0.3f)); b->setImages (&dp); return b; } @@ -569,7 +569,7 @@ Button* OldSchoolLookAndFeel::createDocumentWindowButton (int buttonType) DrawableButton* b = new DrawableButton ("maximise", DrawableButton::ImageFitted); DrawablePath dp; dp.setPath (shape); - dp.setFillColour (Colours::black.withAlpha (0.3f)); + dp.setFill (Colours::black.withAlpha (0.3f)); b->setImages (&dp); return b; } diff --git a/src/gui/graphics/colour/juce_ColourGradient.cpp b/src/gui/graphics/colour/juce_ColourGradient.cpp index e50f44ee0b..127756c4ac 100644 --- a/src/gui/graphics/colour/juce_ColourGradient.cpp +++ b/src/gui/graphics/colour/juce_ColourGradient.cpp @@ -138,7 +138,7 @@ const Colour ColourGradient::getColourAtPosition (const float position) const th } //============================================================================== -PixelARGB* ColourGradient::createLookupTable (int& numEntries) const throw() +PixelARGB* ColourGradient::createLookupTable (const AffineTransform& transform, int& numEntries) const throw() { #ifdef JUCE_DEBUG // trying to use the object without setting its co-ordinates? Have a careful read of diff --git a/src/gui/graphics/colour/juce_ColourGradient.h b/src/gui/graphics/colour/juce_ColourGradient.h index d9130a1029..711d53a59c 100644 --- a/src/gui/graphics/colour/juce_ColourGradient.h +++ b/src/gui/graphics/colour/juce_ColourGradient.h @@ -126,7 +126,7 @@ public: The caller must delete the array that is returned using juce_free(). */ - PixelARGB* createLookupTable (int& numEntries) const throw(); + PixelARGB* createLookupTable (const AffineTransform& transform, int& numEntries) const throw(); /** Returns true if all colours are opaque. */ bool isOpaque() const throw(); @@ -148,9 +148,6 @@ public: */ bool isRadial; - /** A transform to apply to the resultant gradient shape */ - AffineTransform transform; - //============================================================================== juce_UseDebuggingNewOperator diff --git a/src/gui/graphics/contexts/juce_FillType.cpp b/src/gui/graphics/contexts/juce_FillType.cpp new file mode 100644 index 0000000000..506ffcf666 --- /dev/null +++ b/src/gui/graphics/contexts/juce_FillType.cpp @@ -0,0 +1,109 @@ +/* + ============================================================================== + + This file is part of the JUCE library - "Jules' Utility Class Extensions" + Copyright 2004-9 by Raw Material Software Ltd. + + ------------------------------------------------------------------------------ + + JUCE can be redistributed and/or modified under the terms of the GNU General + Public License (Version 2), as published by the Free Software Foundation. + A copy of the license is included in the JUCE distribution, or can be found + online at www.gnu.org/licenses. + + JUCE is distributed in the hope that it will be useful, but WITHOUT ANY + WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS FOR + A PARTICULAR PURPOSE. See the GNU General Public License for more details. + + ------------------------------------------------------------------------------ + + To release a closed-source product which uses JUCE, commercial licenses are + available: visit www.rawmaterialsoftware.com/juce for more information. + + ============================================================================== +*/ + +#include "../../../core/juce_StandardHeader.h" + +BEGIN_JUCE_NAMESPACE + +#include "juce_FillType.h" + + +//============================================================================== +FillType::FillType() throw() + : colour (0xff000000), gradient (0), image (0) +{ +} + +FillType::FillType (const Colour& colour_) throw() + : colour (colour_), gradient (0), image (0) +{ +} + +FillType::FillType (const ColourGradient& gradient) throw() + : colour (0xff000000), gradient (new ColourGradient (gradient)), image (0) +{ +} + +FillType::FillType (const Image& image_, const AffineTransform& transform_) throw() + : colour (0xff000000), gradient (0), + image (&image_), transform (transform_) +{ +} + +FillType::FillType (const FillType& other) throw() + : colour (other.colour), + gradient (other.gradient != 0 ? new ColourGradient (*other.gradient) : 0), + image (other.image), transform (other.transform) +{ +} + +const FillType& FillType::operator= (const FillType& other) throw() +{ + if (this != &other) + { + colour = other.colour; + delete gradient; + gradient = (other.gradient != 0 ? new ColourGradient (*other.gradient) : 0); + image = other.image; + transform = other.transform; + } + + return *this; +} + +FillType::~FillType() throw() +{ + delete gradient; +} + +void FillType::setColour (const Colour& newColour) throw() +{ + deleteAndZero (gradient); + image = 0; + colour = newColour; +} + +void FillType::setGradient (const ColourGradient& newGradient) throw() +{ + if (gradient != 0) + { + *gradient = newGradient; + } + else + { + image = 0; + gradient = new ColourGradient (newGradient); + } +} + +void FillType::setTiledImage (const Image& image_, const AffineTransform& transform_) throw() +{ + deleteAndZero (gradient); + image = &image_; + transform = transform_; +} + + +END_JUCE_NAMESPACE diff --git a/src/gui/graphics/contexts/juce_FillType.h b/src/gui/graphics/contexts/juce_FillType.h new file mode 100644 index 0000000000..c22adbe53b --- /dev/null +++ b/src/gui/graphics/contexts/juce_FillType.h @@ -0,0 +1,116 @@ +/* + ============================================================================== + + This file is part of the JUCE library - "Jules' Utility Class Extensions" + Copyright 2004-9 by Raw Material Software Ltd. + + ------------------------------------------------------------------------------ + + JUCE can be redistributed and/or modified under the terms of the GNU General + Public License (Version 2), as published by the Free Software Foundation. + A copy of the license is included in the JUCE distribution, or can be found + online at www.gnu.org/licenses. + + JUCE is distributed in the hope that it will be useful, but WITHOUT ANY + WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS FOR + A PARTICULAR PURPOSE. See the GNU General Public License for more details. + + ------------------------------------------------------------------------------ + + To release a closed-source product which uses JUCE, commercial licenses are + available: visit www.rawmaterialsoftware.com/juce for more information. + + ============================================================================== +*/ + +#ifndef __JUCE_GRAPHICS_JUCEHEADER__x +#define __JUCE_GRAPHICS_JUCEHEADER__x + +#include "../colour/juce_ColourGradient.h" +class Image; + + +//============================================================================== +/** + Represents a colour or fill pattern to use for rendering paths. + + This is used by the Graphics and DrawablePath classes as a way to encapsulate + a brush type. It can either be a solid colour, a gradient, or a tiled image. + + @see Graphics::setFillType, DrawablePath::setFill +*/ +class JUCE_API FillType +{ +public: + /** Creates a default fill type, of solid black. */ + FillType() throw(); + + /** Creates a fill type of a solid colour. + @see setColour + */ + FillType (const Colour& colour) throw(); + + /** Creates a gradient fill type. + @see setGradient + */ + FillType (const ColourGradient& gradient) throw(); + + /** Creates a tiled image fill type. The transform allows you to set the scaling, offset + and rotation of the pattern. + @see setTiledImage + */ + FillType (const Image& image, const AffineTransform& transform) throw(); + + /** Creates a copy of another FillType. */ + FillType (const FillType& other) throw(); + + /** Makes a copy of another FillType. */ + const FillType& operator= (const FillType& other) throw(); + + /** Destructor. */ + ~FillType() throw(); + + /** Returns true if this is a solid colour fill, and not a gradient or image. */ + bool isColour() const throw() { return gradient == 0 && image == 0; } + + /** Returns true if this is a gradient fill. */ + bool isGradient() const throw() { return gradient != 0; } + + /** Returns true if this is a tiled image pattern fill. */ + bool isTiledImage() const throw() { return image != 0; } + + /** Turns this object into a solid colour fill. + If the object was an image or gradient, those fields will no longer be valid. */ + void setColour (const Colour& newColour) throw(); + + /** Turns this object into a gradient fill. */ + void setGradient (const ColourGradient& newGradient) throw(); + + /** Turns this object into a tiled image fill type. The transform allows you to set + the scaling, offset and rotation of the pattern. + */ + void setTiledImage (const Image& image, const AffineTransform& transform) throw(); + + /** Returns the solid colour being used. */ + Colour colour; + + /** Returns the gradient that should be used for filling. + This will be zero if the object is some other type of fill. + */ + ColourGradient* gradient; + + /** Returns the image that should be used for tiling. + The FillType object just keeps a pointer to this image, it doesn't own it, so you have to + be careful to make sure the image doesn't get deleted while it's being used. + */ + const Image* image; + + /** The transform that should be applied to the image or gradient that's being drawn. + */ + AffineTransform transform; + + juce_UseDebuggingNewOperator +}; + + +#endif // __JUCE_GRAPHICS_JUCEHEADER__ diff --git a/src/gui/graphics/contexts/juce_Graphics.cpp b/src/gui/graphics/contexts/juce_Graphics.cpp index 0b34985706..b31345ad65 100644 --- a/src/gui/graphics/contexts/juce_Graphics.cpp +++ b/src/gui/graphics/contexts/juce_Graphics.cpp @@ -86,7 +86,7 @@ Graphics::~Graphics() throw() void Graphics::resetToDefaultState() throw() { saveStateIfPending(); - context->setColour (Colours::black); + context->setFill (FillType()); context->setFont (Font()); context->setInterpolationQuality (defaultQuality); } @@ -109,6 +109,20 @@ bool Graphics::reduceClipRegion (const RectangleList& clipRegion) throw() return context->clipToRectangleList (clipRegion); } +bool Graphics::reduceClipRegion (const Path& path, const AffineTransform& transform) throw() +{ + saveStateIfPending(); + context->clipToPath (path, transform); + return ! context->isClipEmpty(); +} + +bool Graphics::reduceClipRegion (const Image& image, const Rectangle& sourceClipRegion, const AffineTransform& transform) throw() +{ + saveStateIfPending(); + context->clipToImageAlpha (image, sourceClipRegion, transform); + return ! context->isClipEmpty(); +} + void Graphics::excludeClipRegion (const int x, const int y, const int w, const int h) throw() { @@ -166,7 +180,7 @@ bool Graphics::clipRegionIntersects (const int x, const int y, void Graphics::setColour (const Colour& newColour) throw() { saveStateIfPending(); - context->setColour (newColour); + context->setFill (FillType (newColour)); } void Graphics::setOpacity (const float newOpacity) throw() @@ -178,7 +192,7 @@ void Graphics::setOpacity (const float newOpacity) throw() void Graphics::setGradientFill (const ColourGradient& gradient) throw() { saveStateIfPending(); - context->setGradient (gradient); + context->setFill (FillType (gradient)); } void Graphics::setTiledImageFill (const Image& imageToUse, @@ -187,10 +201,16 @@ void Graphics::setTiledImageFill (const Image& imageToUse, const float opacity) throw() { saveStateIfPending(); - context->setTiledFill (imageToUse, anchorX, anchorY); + context->setFill (FillType (imageToUse, AffineTransform::translation ((float) anchorX, (float) anchorY))); context->setOpacity (opacity); } +void Graphics::setFillType (const FillType& newFill) throw() +{ + saveStateIfPending(); + context->setFill (newFill); +} + //============================================================================== void Graphics::setFont (const Font& newFont) throw() { @@ -345,7 +365,7 @@ void Graphics::fillAll (const Colour& colourToUse) const throw() const Rectangle clip (context->getClipBounds()); context->saveState(); - context->setColour (colourToUse); + context->setFill (FillType (colourToUse)); context->fillRect (clip, false); context->restoreState(); } @@ -435,13 +455,13 @@ void Graphics::drawBevel (const int x, const float op = useGradient ? ramp * (sharpEdgeOnOutside ? bevelThickness - i : i) : oldOpacity; - context->setColour (topLeftColour.withMultipliedAlpha (op)); + context->setFill (FillType (topLeftColour.withMultipliedAlpha (op))); context->fillRect (Rectangle (x + i, y + i, width - i * 2, 1), false); - context->setColour (topLeftColour.withMultipliedAlpha (op * 0.75f)); + context->setFill (FillType (topLeftColour.withMultipliedAlpha (op * 0.75f))); context->fillRect (Rectangle (x + i, y + i + 1, 1, height - i * 2 - 2), false); - context->setColour (bottomRightColour.withMultipliedAlpha (op)); + context->setFill (FillType (bottomRightColour.withMultipliedAlpha (op))); context->fillRect (Rectangle (x + i, y + height - i - 1, width - i * 2, 1), false); - context->setColour (bottomRightColour.withMultipliedAlpha (op * 0.75f)); + context->setFill (FillType (bottomRightColour.withMultipliedAlpha (op * 0.75f))); context->fillRect (Rectangle (x + width - i - 1, y + i + 1, 1, height - i * 2 - 2), false); } @@ -557,7 +577,7 @@ void Graphics::fillCheckerBoard (int x, int y, if (colour1 == colour2) { - context->setColour (colour1); + context->setFill (FillType (colour1)); context->fillRect (Rectangle (x, y, width, height), false); } else @@ -574,7 +594,7 @@ void Graphics::fillCheckerBoard (int x, int y, for (int xx = x; xx < right; xx += checkWidth) { - context->setColour (((cx++ & 1) == 0) ? colour1 : colour2); + context->setFill (FillType (((cx++ & 1) == 0) ? colour1 : colour2)); context->fillRect (Rectangle (xx, y, jmin (checkWidth, right - xx), jmin (checkHeight, bottom - y)), false); } @@ -776,78 +796,5 @@ void Graphics::drawImageTransformed (const Image* const imageToDraw, } } -//============================================================================== -Graphics::FillType::FillType() throw() - : colour (0xff000000), gradient (0), - image (0), imageX (0), imageY (0) -{ -} - -Graphics::FillType::FillType (const Colour& colour_) throw() - : colour (colour_), gradient (0), - image (0), imageX (0), imageY (0) -{ -} - -Graphics::FillType::FillType (const ColourGradient& gradient) throw() - : colour (0xff000000), gradient (new ColourGradient (gradient)), - image (0), imageX (0), imageY (0) -{ -} - -Graphics::FillType::FillType (Image* const image_, const int x, const int y) throw() - : colour (0xff000000), gradient (0), - image (image_), imageX (x), imageY (y) -{ -} - -Graphics::FillType::FillType (const FillType& other) throw() - : colour (other.colour), - gradient (other.gradient != 0 ? new ColourGradient (*other.gradient) : 0), - image (other.image), imageX (other.imageX), imageY (other.imageY) -{ -} - -const Graphics::FillType& Graphics::FillType::operator= (const FillType& other) throw() -{ - if (this != &other) - { - colour = other.colour; - delete gradient; - gradient = (other.gradient != 0 ? new ColourGradient (*other.gradient) : 0); - image = other.image; - imageX = other.imageX; - imageY = other.imageY; - } - - return *this; -} - -Graphics::FillType::~FillType() throw() -{ - delete gradient; -} - -void Graphics::FillType::setColour (const Colour& newColour) throw() -{ - deleteAndZero (gradient); - colour = newColour; -} - -void Graphics::FillType::setGradient (const ColourGradient& newGradient) throw() -{ - if (gradient != 0) - *gradient = newGradient; - else - gradient = new ColourGradient (newGradient); -} - -void Graphics::FillType::setTiledImage (const Image& image_, const int imageX_, const int imageY_) throw() -{ - deleteAndZero (gradient); - image = &image_; - imageX = imageX_; - imageY = imageY_; -} END_JUCE_NAMESPACE diff --git a/src/gui/graphics/contexts/juce_Graphics.h b/src/gui/graphics/contexts/juce_Graphics.h index e853d18055..ba82d0f25d 100644 --- a/src/gui/graphics/contexts/juce_Graphics.h +++ b/src/gui/graphics/contexts/juce_Graphics.h @@ -31,7 +31,7 @@ #include "../geometry/juce_PathStrokeType.h" #include "../geometry/juce_Line.h" #include "../colour/juce_Colours.h" -#include "../colour/juce_ColourGradient.h" +#include "juce_FillType.h" #include "juce_RectanglePlacement.h" class LowLevelGraphicsContext; class Image; @@ -106,6 +106,11 @@ public: const int anchorY, const float opacity) throw(); + /** Changes the current fill settings. + @see setColour, setGradientFill, setTiledImageFill + */ + void setFillType (const FillType& newFill) throw(); + //============================================================================== /** Changes the font to use for subsequent text-drawing functions. @@ -622,7 +627,7 @@ public: /** Intersects the current clipping region with another region. @returns true if the resulting clipping region is non-zero in size - @see setOrigin, clipRegionIntersects, getClipLeft, getClipRight, getClipWidth, getClipHeight + @see setOrigin, clipRegionIntersects */ bool reduceClipRegion (const int x, const int y, const int width, const int height) throw(); @@ -630,10 +635,34 @@ public: /** Intersects the current clipping region with a rectangle list region. @returns true if the resulting clipping region is non-zero in size - @see setOrigin, clipRegionIntersects, getClipLeft, getClipRight, getClipWidth, getClipHeight + @see setOrigin, clipRegionIntersects */ bool reduceClipRegion (const RectangleList& clipRegion) throw(); + /** Intersects the current clipping region with a path. + + @returns true if the resulting clipping region is non-zero in size + @see reduceClipRegion + */ + bool reduceClipRegion (const Path& path, const AffineTransform& transform = AffineTransform::identity) throw(); + + /** Intersects the current clipping region with an image's alpha-channel. + + The current clipping path is intersected with the area covered by this image's + alpha-channel, after the image has been transformed by the specified matrix. + + @param image the image whose alpha-channel should be used. If the image doesn't + have an alpha-channel, it is treated as entirely opaque. + @param sourceClipRegion a subsection of the image that should be used. To use the + entire image, just pass a rectangle of bounds + (0, 0, image.getWidth(), image.getHeight()). + @param transform a matrix to apply to the image + @returns true if the resulting clipping region is non-zero in size + @see reduceClipRegion + */ + bool reduceClipRegion (const Image& image, const Rectangle& sourceClipRegion, + const AffineTransform& transform) throw(); + /** Excludes a rectangle to stop it being drawn into. */ void excludeClipRegion (const int x, const int y, const int width, const int height) throw(); @@ -684,34 +713,6 @@ public: /** @internal */ LowLevelGraphicsContext* getInternalContext() const throw() { return context; } - //============================================================================== - class FillType - { - public: - FillType() throw(); - FillType (const Colour& colour) throw(); - FillType (const ColourGradient& gradient) throw(); - FillType (Image* const image, const int x, const int y) throw(); - FillType (const FillType& other) throw(); - const FillType& operator= (const FillType& other) throw(); - ~FillType() throw(); - - bool isColour() const throw() { return gradient == 0 && image == 0; } - bool isGradient() const throw() { return gradient != 0; } - bool isTiledImage() const throw() { return image != 0; } - - void setColour (const Colour& newColour) throw(); - void setGradient (const ColourGradient& newGradient) throw(); - void setTiledImage (const Image& image, const int imageX, const int imageY) throw(); - - Colour colour; - ColourGradient* gradient; - const Image* image; - int imageX, imageY; - - juce_UseDebuggingNewOperator - }; - private: //============================================================================== LowLevelGraphicsContext* const context; diff --git a/src/gui/graphics/contexts/juce_LowLevelGraphicsContext.h b/src/gui/graphics/contexts/juce_LowLevelGraphicsContext.h index 456d52180d..ea9431e681 100644 --- a/src/gui/graphics/contexts/juce_LowLevelGraphicsContext.h +++ b/src/gui/graphics/contexts/juce_LowLevelGraphicsContext.h @@ -80,9 +80,7 @@ public: virtual void restoreState() = 0; //============================================================================== - virtual void setColour (const Colour& colour) = 0; - virtual void setGradient (const ColourGradient& gradient) = 0; - virtual void setTiledFill (const Image& image, int x, int y) = 0; + virtual void setFill (const FillType& fillType) = 0; virtual void setOpacity (float opacity) = 0; virtual void setInterpolationQuality (Graphics::ResamplingQuality quality) = 0; diff --git a/src/gui/graphics/contexts/juce_LowLevelGraphicsPostScriptRenderer.cpp b/src/gui/graphics/contexts/juce_LowLevelGraphicsPostScriptRenderer.cpp index 49f96c55e7..05066bc80f 100644 --- a/src/gui/graphics/contexts/juce_LowLevelGraphicsPostScriptRenderer.cpp +++ b/src/gui/graphics/contexts/juce_LowLevelGraphicsPostScriptRenderer.cpp @@ -59,13 +59,10 @@ LowLevelGraphicsPostScriptRenderer::LowLevelGraphicsPostScriptRenderer (OutputSt : out (resultingPostScript), totalWidth (totalWidth_), totalHeight (totalHeight_), - xOffset (0), - yOffset (0), - needToClip (true), - colour (Colours::black), - gradient (0) + needToClip (true) { - clip = new RectangleList (Rectangle (0, 0, totalWidth_, totalHeight_)); + stateStack.add (new SavedState()); + stateStack.getLast()->clip = Rectangle (0, 0, totalWidth_, totalHeight_); const float scale = jmin ((520.0f / totalWidth_), (750.0f / totalHeight)); @@ -102,8 +99,6 @@ LowLevelGraphicsPostScriptRenderer::LowLevelGraphicsPostScriptRenderer (OutputSt LowLevelGraphicsPostScriptRenderer::~LowLevelGraphicsPostScriptRenderer() { - delete clip; - delete gradient; } //============================================================================== @@ -116,91 +111,84 @@ void LowLevelGraphicsPostScriptRenderer::setOrigin (int x, int y) { if (x != 0 || y != 0) { - xOffset += x; - yOffset += y; + stateStack.getLast()->xOffset += x; + stateStack.getLast()->yOffset += y; needToClip = true; } } -bool LowLevelGraphicsPostScriptRenderer::reduceClipRegion (int x, int y, int w, int h) +bool LowLevelGraphicsPostScriptRenderer::clipToRectangle (const Rectangle& r) { needToClip = true; - return clip->clipTo (Rectangle (x + xOffset, y + yOffset, w, h)); + return stateStack.getLast()->clip.clipTo (r.translated (stateStack.getLast()->xOffset, stateStack.getLast()->yOffset)); } -bool LowLevelGraphicsPostScriptRenderer::reduceClipRegion (const RectangleList& clipRegion) +bool LowLevelGraphicsPostScriptRenderer::clipToRectangleList (const RectangleList& clipRegion) { needToClip = true; - return clip->clipTo (clipRegion); + return stateStack.getLast()->clip.clipTo (clipRegion); } -void LowLevelGraphicsPostScriptRenderer::excludeClipRegion (int x, int y, int w, int h) +void LowLevelGraphicsPostScriptRenderer::excludeClipRectangle (const Rectangle& r) { needToClip = true; - clip->subtract (Rectangle (x + xOffset, y + yOffset, w, h)); + stateStack.getLast()->clip.subtract (r.translated (stateStack.getLast()->xOffset, stateStack.getLast()->yOffset)); } -bool LowLevelGraphicsPostScriptRenderer::clipRegionIntersects (int x, int y, int w, int h) +void LowLevelGraphicsPostScriptRenderer::clipToPath (const Path& path, const AffineTransform& transform) { - return clip->intersectsRectangle (Rectangle (x + xOffset, y + yOffset, w, h)); + writeClip(); + + Path p (path); + p.applyTransform (transform.translated ((float) stateStack.getLast()->xOffset, (float) stateStack.getLast()->yOffset)); + writePath (p); + out << "clip\n"; +} + +void LowLevelGraphicsPostScriptRenderer::clipToImageAlpha (const Image& sourceImage, const Rectangle& srcClip, const AffineTransform& transform) +{ + needToClip = true; + jassertfalse // xxx +} + +bool LowLevelGraphicsPostScriptRenderer::clipRegionIntersects (const Rectangle& r) +{ + return stateStack.getLast()->clip.intersectsRectangle (r.translated (stateStack.getLast()->xOffset, stateStack.getLast()->yOffset)); } const Rectangle LowLevelGraphicsPostScriptRenderer::getClipBounds() const { - return clip->getBounds().translated (-xOffset, -yOffset); + return stateStack.getLast()->clip.getBounds().translated (-stateStack.getLast()->xOffset, + -stateStack.getLast()->yOffset); } bool LowLevelGraphicsPostScriptRenderer::isClipEmpty() const { - return clip->isEmpty(); + return stateStack.getLast()->clip.isEmpty(); } //============================================================================== -LowLevelGraphicsPostScriptRenderer::SavedState::SavedState (RectangleList* const clip_, - const int xOffset_, const int yOffset_, - const Colour& colour_, ColourGradient* const gradient_, - const Font& font_) - : clip (clip_), - xOffset (xOffset_), - yOffset (yOffset_), - colour (colour_), - gradient (gradient_), - font (font_) +LowLevelGraphicsPostScriptRenderer::SavedState::SavedState() + : xOffset (0), + yOffset (0) { } LowLevelGraphicsPostScriptRenderer::SavedState::~SavedState() { - delete clip; - delete gradient; } void LowLevelGraphicsPostScriptRenderer::saveState() { - stateStack.add (new SavedState (new RectangleList (*clip), xOffset, yOffset, colour, - gradient != 0 ? new ColourGradient (*gradient) : 0, font)); + stateStack.add (new SavedState (*stateStack.getLast())); } void LowLevelGraphicsPostScriptRenderer::restoreState() { - SavedState* const top = stateStack.getLast(); - - if (top != 0) - { - swapVariables (clip, top->clip); - swapVariables (gradient, top->gradient); - colour = top->colour; - xOffset = top->xOffset; - yOffset = top->yOffset; - font = top->font; + jassert (stateStack.size() > 0); + if (stateStack.size() > 0) stateStack.removeLast(); - needToClip = true; - } - else - { - jassertfalse // trying to pop with an empty stack! - } } //============================================================================== @@ -214,7 +202,7 @@ void LowLevelGraphicsPostScriptRenderer::writeClip() int itemsOnLine = 0; - for (RectangleList::Iterator i (*clip); i.next();) + for (RectangleList::Iterator i (stateStack.getLast()->clip); i.next();) { if (++itemsOnLine == 6) { @@ -336,16 +324,9 @@ void LowLevelGraphicsPostScriptRenderer::writeTransform (const AffineTransform& } //============================================================================== -void LowLevelGraphicsPostScriptRenderer::setColour (const Colour& colour_) -{ - colour = colour_; - deleteAndZero (gradient); -} - -void LowLevelGraphicsPostScriptRenderer::setGradient (const ColourGradient& gradient_) +void LowLevelGraphicsPostScriptRenderer::setFill (const FillType& fillType) { - delete gradient; - gradient = new ColourGradient (gradient_); + stateStack.getLast()->fillType = fillType; } void LowLevelGraphicsPostScriptRenderer::setOpacity (float opacity) @@ -357,22 +338,21 @@ void LowLevelGraphicsPostScriptRenderer::setInterpolationQuality (Graphics::Resa } //============================================================================== -void LowLevelGraphicsPostScriptRenderer::fillRect (int x, int y, int w, int h, const bool /*replaceExistingContents*/) +void LowLevelGraphicsPostScriptRenderer::fillRect (const Rectangle& r, const bool /*replaceExistingContents*/) { - if (gradient == 0) + if (stateStack.getLast()->fillType.isColour()) { writeClip(); - writeColour (colour); + writeColour (stateStack.getLast()->fillType.colour); - x += xOffset; - y += yOffset; + Rectangle r2 (r.translated (stateStack.getLast()->xOffset, stateStack.getLast()->yOffset)); - out << x << ' ' << -(y + h) << ' ' << w << ' ' << h << " rectfill\n"; + out << r2.getX() << ' ' << -r2.getBottom() << ' ' << r2.getWidth() << ' ' << r2.getHeight() << " rectfill\n"; } else { Path p; - p.addRectangle ((float) x, (float) y, (float) w, (float) h); + p.addRectangle (r); fillPath (p, AffineTransform::identity); } @@ -381,19 +361,20 @@ void LowLevelGraphicsPostScriptRenderer::fillRect (int x, int y, int w, int h, c //============================================================================== void LowLevelGraphicsPostScriptRenderer::fillPath (const Path& path, const AffineTransform& t) { - if (gradient == 0) + if (stateStack.getLast()->fillType.isColour()) { writeClip(); Path p (path); - p.applyTransform (t.translated ((float) xOffset, (float) yOffset)); + p.applyTransform (t.translated ((float) stateStack.getLast()->xOffset, + (float) stateStack.getLast()->yOffset)); writePath (p); - writeColour (colour); + writeColour (stateStack.getLast()->fillType.colour); out << "fill\n"; } - else + else if (stateStack.getLast()->fillType.isGradient()) { // this doesn't work correctly yet - it could be improved to handle solid gradients, but // postscript can't do semi-transparent ones. @@ -404,78 +385,22 @@ void LowLevelGraphicsPostScriptRenderer::fillPath (const Path& path, const Affin { Path p (path); - p.applyTransform (t.translated ((float) xOffset, (float) yOffset)); + p.applyTransform (t.translated ((float) stateStack.getLast()->xOffset, (float) stateStack.getLast()->yOffset)); writePath (p); out << "clip\n"; } - const Rectangle bounds (clip->getBounds()); + const Rectangle bounds (stateStack.getLast()->clip.getBounds()); // ideally this would draw lots of lines or ellipses to approximate the gradient, but for the // time-being, this just fills it with the average colour.. - writeColour (gradient->getColourAtPosition (0.5)); + writeColour (stateStack.getLast()->fillType.gradient->getColourAtPosition (0.5)); out << bounds.getX() << ' ' << -bounds.getBottom() << ' ' << bounds.getWidth() << ' ' << bounds.getHeight() << " rectfill\n"; out << "grestore\n"; } } -void LowLevelGraphicsPostScriptRenderer::fillPathWithImage (const Path& path, const AffineTransform& transform, - const Image& sourceImage, - int imageX, int imageY) -{ - writeClip(); - - out << "gsave "; - Path p (path); - p.applyTransform (transform.translated ((float) xOffset, (float) yOffset)); - writePath (p); - out << "clip\n"; - - blendImage (sourceImage, imageX, imageY, sourceImage.getWidth(), sourceImage.getHeight(), 0, 0); - - out << "grestore\n"; -} - - -//============================================================================== -void LowLevelGraphicsPostScriptRenderer::fillAlphaChannel (const Image& /*clipImage*/, int x, int y) -{ - x += xOffset; - y += yOffset; - - writeClip(); - - if (gradient == 0) - { - writeColour (colour); - } - - notPossibleInPostscriptAssert // you can disable this warning by setting the WARN_ABOUT_NON_POSTSCRIPT_OPERATIONS flag at the top of this file -} - -void LowLevelGraphicsPostScriptRenderer::fillAlphaChannelWithImage (const Image& /*alphaImage*/, int alphaImageX, int alphaImageY, - const Image& /*fillerImage*/, int fillerImageX, int fillerImageY) -{ - alphaImageX += xOffset; - alphaImageY += yOffset; - - fillerImageX += xOffset; - fillerImageY += yOffset; - - writeClip(); - - notPossibleInPostscriptAssert // you can disable this warning by setting the WARN_ABOUT_NON_POSTSCRIPT_OPERATIONS flag at the top of this file -} - -//============================================================================== -void LowLevelGraphicsPostScriptRenderer::blendImage (const Image& sourceImage, int dx, int dy, int dw, int dh, int sx, int sy) -{ - blendImageWarping (sourceImage, - sx, sy, dw, dh, - AffineTransform::translation ((float) dx, (float) dy)); -} - //============================================================================== void LowLevelGraphicsPostScriptRenderer::writeImage (const Image& im, const int sx, const int sy, @@ -535,23 +460,21 @@ void LowLevelGraphicsPostScriptRenderer::writeImage (const Image& im, out << "\n>}\n"; } -void LowLevelGraphicsPostScriptRenderer::blendImageWarping (const Image& sourceImage, - int srcClipX, int srcClipY, - int srcClipW, int srcClipH, - const AffineTransform& t) +void LowLevelGraphicsPostScriptRenderer::drawImage (const Image& sourceImage, const Rectangle& srcClip, + const AffineTransform& transform, const bool fillEntireClipAsTiles) { - const int w = jmin (sourceImage.getWidth(), srcClipX + srcClipW); - const int h = jmin (sourceImage.getHeight(), srcClipY + srcClipH); + const int w = jmin (sourceImage.getWidth(), srcClip.getRight()); + const int h = jmin (sourceImage.getHeight(), srcClip.getBottom()); writeClip(); out << "gsave "; - writeTransform (t.translated ((float) xOffset, (float) yOffset) - .scaled (1.0f, -1.0f)); + writeTransform (transform.translated ((float) stateStack.getLast()->xOffset, (float) stateStack.getLast()->yOffset) + .scaled (1.0f, -1.0f)); RectangleList imageClip; sourceImage.createSolidAreaMask (imageClip, 0.5f); - imageClip.clipTo (Rectangle (srcClipX, srcClipY, srcClipW, srcClipH)); + imageClip.clipTo (srcClip); out << "newpath "; int itemsOnLine = 0; @@ -574,7 +497,7 @@ void LowLevelGraphicsPostScriptRenderer::blendImageWarping (const Image& sourceI out << w << ' ' << h << " scale\n"; out << w << ' ' << h << " 8 [" << w << " 0 0 -" << h << ' ' << (int) 0 << ' ' << h << " ]\n"; - writeImage (sourceImage, srcClipX, srcClipY, srcClipW, srcClipH); + writeImage (sourceImage, srcClip.getX(), srcClip.getY(), srcClip.getWidth(), srcClip.getHeight()); out << "false 3 colorimage grestore\n"; needToClip = true; @@ -603,19 +526,19 @@ void LowLevelGraphicsPostScriptRenderer::drawHorizontalLine (const int y, double //============================================================================== void LowLevelGraphicsPostScriptRenderer::setFont (const Font& newFont) { - font = newFont; + stateStack.getLast()->font = newFont; } -void LowLevelGraphicsPostScriptRenderer::drawGlyph (int glyphNumber, float x, float y) +const Font LowLevelGraphicsPostScriptRenderer::getFont() { - drawGlyph (glyphNumber, AffineTransform::translation (x, y)); + return stateStack.getLast()->font; } void LowLevelGraphicsPostScriptRenderer::drawGlyph (int glyphNumber, const AffineTransform& transform) { Path p; + Font& font = stateStack.getLast()->font; font.getTypeface()->getOutlineForGlyph (glyphNumber, p); - fillPath (p, AffineTransform::scale (font.getHeight() * font.getHorizontalScale(), font.getHeight()).followedBy (transform)); } diff --git a/src/gui/graphics/contexts/juce_LowLevelGraphicsPostScriptRenderer.h b/src/gui/graphics/contexts/juce_LowLevelGraphicsPostScriptRenderer.h index 007a1746b7..9e8127d74f 100644 --- a/src/gui/graphics/contexts/juce_LowLevelGraphicsPostScriptRenderer.h +++ b/src/gui/graphics/contexts/juce_LowLevelGraphicsPostScriptRenderer.h @@ -50,50 +50,39 @@ public: bool isVectorDevice() const; void setOrigin (int x, int y); - bool reduceClipRegion (int x, int y, int w, int h); - bool reduceClipRegion (const RectangleList& clipRegion); - void excludeClipRegion (int x, int y, int w, int h); + bool clipToRectangle (const Rectangle& r); + bool clipToRectangleList (const RectangleList& clipRegion); + void excludeClipRectangle (const Rectangle& r); + void clipToPath (const Path& path, const AffineTransform& transform); + void clipToImageAlpha (const Image& sourceImage, const Rectangle& srcClip, const AffineTransform& transform); void saveState(); void restoreState(); - bool clipRegionIntersects (int x, int y, int w, int h); + bool clipRegionIntersects (const Rectangle& r); const Rectangle getClipBounds() const; bool isClipEmpty() const; //============================================================================== - void setColour (const Colour& colour); - void setGradient (const ColourGradient& gradient); + void setFill (const FillType& fillType); void setOpacity (float opacity); void setInterpolationQuality (Graphics::ResamplingQuality quality); //============================================================================== - void fillRect (int x, int y, int w, int h, const bool replaceExistingContents); + void fillRect (const Rectangle& r, const bool replaceExistingContents); void fillPath (const Path& path, const AffineTransform& transform); - void fillPathWithImage (const Path& path, const AffineTransform& transform, - const Image& image, int imageX, int imageY); + void drawImage (const Image& sourceImage, const Rectangle& srcClip, + const AffineTransform& transform, const bool fillEntireClipAsTiles); - void fillAlphaChannel (const Image& alphaImage, int imageX, int imageY); - void fillAlphaChannelWithImage (const Image& alphaImage, int alphaImageX, int alphaImageY, - const Image& fillerImage, int fillerImageX, int fillerImageY); - - //============================================================================== - void blendImage (const Image& sourceImage, int destX, int destY, int destW, int destH, - int sourceX, int sourceY); - - void blendImageWarping (const Image& sourceImage, int srcClipX, int srcClipY, int srcClipW, int srcClipH, - const AffineTransform& transform); - - //============================================================================== void drawLine (double x1, double y1, double x2, double y2); void drawVerticalLine (const int x, double top, double bottom); void drawHorizontalLine (const int x, double top, double bottom); //============================================================================== + const Font getFont(); void setFont (const Font& newFont); - void drawGlyph (int glyphNumber, float x, float y); void drawGlyph (int glyphNumber, const AffineTransform& transform); //============================================================================== @@ -102,27 +91,21 @@ public: protected: //============================================================================== OutputStream& out; - RectangleList* clip; - int totalWidth, totalHeight, xOffset, yOffset; + int totalWidth, totalHeight; bool needToClip; - Colour lastColour, colour; - ColourGradient* gradient; - Font font; + Colour lastColour; struct SavedState { - SavedState (RectangleList* const clip, const int xOffset, const int yOffset, - const Colour& colour, ColourGradient* const gradient, const Font& font); + SavedState(); ~SavedState(); - RectangleList* clip; - const int xOffset, yOffset; - Colour colour; - ColourGradient* gradient; + RectangleList clip; + int xOffset, yOffset; + FillType fillType; Font font; private: - SavedState (const SavedState&); const SavedState& operator= (const SavedState&); }; diff --git a/src/gui/graphics/contexts/juce_LowLevelGraphicsSoftwareRenderer.cpp b/src/gui/graphics/contexts/juce_LowLevelGraphicsSoftwareRenderer.cpp index 5aac7a5e47..e2e8faf274 100644 --- a/src/gui/graphics/contexts/juce_LowLevelGraphicsSoftwareRenderer.cpp +++ b/src/gui/graphics/contexts/juce_LowLevelGraphicsSoftwareRenderer.cpp @@ -109,7 +109,6 @@ private: { dest->blend (colour); ++dest; - } while (--width > 0); } @@ -173,7 +172,7 @@ private: class LinearGradientPixelGenerator { public: - LinearGradientPixelGenerator (const ColourGradient& gradient, const PixelARGB* const lookupTable_, const int numEntries_) + LinearGradientPixelGenerator (const ColourGradient& gradient, const AffineTransform& transform, const PixelARGB* const lookupTable_, const int numEntries_) : lookupTable (lookupTable_), numEntries (numEntries_) { jassert (numEntries_ >= 0); @@ -182,16 +181,16 @@ public: float x2 = gradient.x2; float y2 = gradient.y2; - if (! gradient.transform.isIdentity()) + if (! transform.isIdentity()) { const Line l (x2, y2, x1, y1); const Point p3 = l.getPointAlongLine (0.0, 100.0f); float x3 = p3.getX(); float y3 = p3.getY(); - gradient.transform.transformPoint (x1, y1); - gradient.transform.transformPoint (x2, y2); - gradient.transform.transformPoint (x3, y3); + transform.transformPoint (x1, y1); + transform.transformPoint (x2, y2); + transform.transformPoint (x3, y3); const Line l2 (x2, y2, x3, y3); const float prop = l2.findNearestPointTo (x1, y1); @@ -254,7 +253,7 @@ private: class RadialGradientPixelGenerator { public: - RadialGradientPixelGenerator (const ColourGradient& gradient, + RadialGradientPixelGenerator (const ColourGradient& gradient, const AffineTransform&, const PixelARGB* const lookupTable_, const int numEntries_) throw() : lookupTable (lookupTable_), numEntries (numEntries_), @@ -298,10 +297,10 @@ protected: class TransformedRadialGradientPixelGenerator : public RadialGradientPixelGenerator { public: - TransformedRadialGradientPixelGenerator (const ColourGradient& gradient, + TransformedRadialGradientPixelGenerator (const ColourGradient& gradient, const AffineTransform& transform, const PixelARGB* const lookupTable_, const int numEntries_) throw() - : RadialGradientPixelGenerator (gradient, lookupTable_, numEntries_), - inverseTransform (gradient.transform.inverted()) + : RadialGradientPixelGenerator (gradient, transform, lookupTable_, numEntries_), + inverseTransform (transform.inverted()) { tM10 = inverseTransform.mat10; tM00 = inverseTransform.mat00; @@ -340,9 +339,9 @@ template class GradientEdgeTableRenderer : public GradientType { public: - GradientEdgeTableRenderer (const Image::BitmapData& destData_, const ColourGradient& gradient, + GradientEdgeTableRenderer (const Image::BitmapData& destData_, const ColourGradient& gradient, const AffineTransform& transform, const PixelARGB* const lookupTable, const int numEntries) throw() - : GradientType (gradient, lookupTable, numEntries - 1), + : GradientType (gradient, transform, lookupTable, numEntries - 1), destData (destData_) { } @@ -367,7 +366,6 @@ public: do { (dest++)->blend (GradientType::getPixel (x++), alphaLevel); - } while (--width > 0); } else @@ -375,7 +373,6 @@ public: do { (dest++)->blend (GradientType::getPixel (x++)); - } while (--width > 0); } } @@ -490,7 +487,6 @@ private: do { dest++ ->blend (*src++); - } while (--width > 0); } @@ -886,7 +882,7 @@ class LLGCSavedState { public: LLGCSavedState (const Rectangle& clip_, const int xOffset_, const int yOffset_, - const Font& font_, const Graphics::FillType& fillType_, + const Font& font_, const FillType& fillType_, const Graphics::ResamplingQuality interpolationQuality_) throw() : edgeTable (new EdgeTableHolder (EdgeTable (clip_))), xOffset (xOffset_), yOffset (yOffset_), @@ -909,15 +905,17 @@ public: bool clipToRectangle (const Rectangle& r) throw() { dupeEdgeTableIfMultiplyReferenced(); - edgeTable->edgeTable.clipToRectangle (r); + edgeTable->edgeTable.clipToRectangle (r.translated (xOffset, yOffset)); return ! edgeTable->edgeTable.isEmpty(); } bool clipToRectangleList (const RectangleList& r) throw() { dupeEdgeTableIfMultiplyReferenced(); + RectangleList temp (r); + temp.offsetAll (xOffset, yOffset); RectangleList totalArea (edgeTable->edgeTable.getMaximumBounds()); - totalArea.subtract (r); + totalArea.subtract (temp); for (RectangleList::Iterator i (totalArea); i.next();) edgeTable->edgeTable.excludeRectangle (*i.getRectangle()); @@ -928,14 +926,14 @@ public: bool excludeClipRectangle (const Rectangle& r) throw() { dupeEdgeTableIfMultiplyReferenced(); - edgeTable->edgeTable.excludeRectangle (r); + edgeTable->edgeTable.excludeRectangle (r.translated (xOffset, yOffset)); return ! edgeTable->edgeTable.isEmpty(); } void clipToPath (const Path& p, const AffineTransform& transform) throw() { dupeEdgeTableIfMultiplyReferenced(); - EdgeTable et (edgeTable->edgeTable.getMaximumBounds(), p, transform); + EdgeTable et (edgeTable->edgeTable.getMaximumBounds(), p, transform.translated ((float) xOffset, (float) yOffset)); edgeTable->edgeTable.clipToEdgeTable (et); } @@ -951,33 +949,26 @@ public: jassert (! replaceContents); // that option is just for solid colours ColourGradient g2 (*(fillType.gradient)); - const bool isIdentity = g2.transform.isOnlyTranslation(); + AffineTransform transform (fillType.transform.translated ((float) xOffset, (float) yOffset)); + const bool isIdentity = transform.isOnlyTranslation(); if (isIdentity) { // If our translation doesn't involve any distortion, we can speed it up.. - const float tx = g2.transform.getTranslationX() + xOffset; - const float ty = g2.transform.getTranslationY() + yOffset; - - g2.x1 += tx; - g2.x2 += tx; - g2.y1 += ty; - g2.y2 += ty; - } - else - { - g2.transform = g2.transform.translated ((float) xOffset, (float) yOffset); + transform.transformPoint (g2.x1, g2.y1); + transform.transformPoint (g2.x2, g2.y2); + transform = AffineTransform::identity; } int numLookupEntries; - PixelARGB* const lookupTable = g2.createLookupTable (numLookupEntries); + PixelARGB* const lookupTable = g2.createLookupTable (transform, numLookupEntries); jassert (numLookupEntries > 0); switch (image.getFormat()) { - case Image::ARGB: renderGradient (et, destData, g2, lookupTable, numLookupEntries, isIdentity); break; - case Image::RGB: renderGradient (et, destData, g2, lookupTable, numLookupEntries, isIdentity); break; - default: renderGradient (et, destData, g2, lookupTable, numLookupEntries, isIdentity); break; + case Image::ARGB: renderGradient (et, destData, g2, transform, lookupTable, numLookupEntries, isIdentity); break; + case Image::RGB: renderGradient (et, destData, g2, transform, lookupTable, numLookupEntries, isIdentity); break; + default: renderGradient (et, destData, g2, transform, lookupTable, numLookupEntries, isIdentity); break; } juce_free (lookupTable); @@ -985,7 +976,7 @@ public: else if (fillType.isTiledImage()) { renderImage (image, *(fillType.image), Rectangle (0, 0, fillType.image->getWidth(), fillType.image->getHeight()), - AffineTransform::translation ((float) fillType.imageX, (float) fillType.imageY), &et); + fillType.transform, &et); } else { @@ -1061,18 +1052,19 @@ public: } //============================================================================== - void clipToImageAlpha (const Image& image, const Rectangle& srcClip, const AffineTransform& transform) throw() + void clipToImageAlpha (const Image& image, const Rectangle& srcClip, const AffineTransform& t) throw() { if (! image.hasAlphaChannel()) { Path p; p.addRectangle (srcClip); - clipToPath (p, transform); + clipToPath (p, t); return; } dupeEdgeTableIfMultiplyReferenced(); + const AffineTransform transform (t.translated ((float) xOffset, (float) yOffset)); const Image::BitmapData srcData (image, srcClip.getX(), srcClip.getY(), srcClip.getWidth(), srcClip.getHeight()); const bool betterQuality = (interpolationQuality != Graphics::lowResamplingQuality); EdgeTable& et = edgeTable->edgeTable; @@ -1145,9 +1137,7 @@ public: class EdgeTableHolder : public ReferenceCountedObject { public: - EdgeTableHolder (const EdgeTable& e) throw() - : edgeTable (e) - {} + EdgeTableHolder (const EdgeTable& e) throw() : edgeTable (e) {} EdgeTable edgeTable; }; @@ -1155,7 +1145,7 @@ public: ReferenceCountedObjectPtr edgeTable; int xOffset, yOffset; Font font; - Graphics::FillType fillType; + FillType fillType; Graphics::ResamplingQuality interpolationQuality; private: @@ -1169,7 +1159,7 @@ private: //============================================================================== template - void renderGradient (EdgeTable& et, const Image::BitmapData& destData, const ColourGradient& g, + void renderGradient (EdgeTable& et, const Image::BitmapData& destData, const ColourGradient& g, const AffineTransform& transform, const PixelARGB* const lookupTable, const int numLookupEntries, const bool isIdentity) throw() { jassert (destData.pixelStride == sizeof (DestPixelType)); @@ -1178,18 +1168,18 @@ private: { if (isIdentity) { - GradientEdgeTableRenderer renderer (destData, g, lookupTable, numLookupEntries); + GradientEdgeTableRenderer renderer (destData, g, transform, lookupTable, numLookupEntries); et.iterate (renderer); } else { - GradientEdgeTableRenderer renderer (destData, g, lookupTable, numLookupEntries); + GradientEdgeTableRenderer renderer (destData, g, transform, lookupTable, numLookupEntries); et.iterate (renderer); } } else { - GradientEdgeTableRenderer renderer (destData, g, lookupTable, numLookupEntries); + GradientEdgeTableRenderer renderer (destData, g, transform, lookupTable, numLookupEntries); et.iterate (renderer); } } @@ -1286,7 +1276,7 @@ LowLevelGraphicsSoftwareRenderer::LowLevelGraphicsSoftwareRenderer (Image& image stateStack (20) { currentState = new LLGCSavedState (Rectangle (0, 0, image_.getWidth(), image_.getHeight()), - 0, 0, Font(), Graphics::FillType(), Graphics::mediumResamplingQuality); + 0, 0, Font(), FillType(), Graphics::mediumResamplingQuality); } LowLevelGraphicsSoftwareRenderer::~LowLevelGraphicsSoftwareRenderer() @@ -1308,30 +1298,27 @@ void LowLevelGraphicsSoftwareRenderer::setOrigin (int x, int y) bool LowLevelGraphicsSoftwareRenderer::clipToRectangle (const Rectangle& r) { - return currentState->clipToRectangle (r.translated (currentState->xOffset, currentState->yOffset)); + return currentState->clipToRectangle (r); } bool LowLevelGraphicsSoftwareRenderer::clipToRectangleList (const RectangleList& clipRegion) { - RectangleList temp (clipRegion); - temp.offsetAll (currentState->xOffset, currentState->yOffset); - - return currentState->clipToRectangleList (temp); + return currentState->clipToRectangleList (clipRegion); } void LowLevelGraphicsSoftwareRenderer::excludeClipRectangle (const Rectangle& r) { - currentState->excludeClipRectangle (r.translated (currentState->xOffset, currentState->yOffset)); + currentState->excludeClipRectangle (r); } void LowLevelGraphicsSoftwareRenderer::clipToPath (const Path& path, const AffineTransform& transform) { - currentState->clipToPath (path, transform.translated ((float) currentState->xOffset, (float) currentState->yOffset)); + currentState->clipToPath (path, transform); } void LowLevelGraphicsSoftwareRenderer::clipToImageAlpha (const Image& sourceImage, const Rectangle& srcClip, const AffineTransform& transform) { - currentState->clipToImageAlpha (sourceImage, srcClip, transform.translated ((float) currentState->xOffset, (float) currentState->yOffset)); + currentState->clipToImageAlpha (sourceImage, srcClip, transform); } bool LowLevelGraphicsSoftwareRenderer::clipRegionIntersects (const Rectangle& r) @@ -1373,19 +1360,9 @@ void LowLevelGraphicsSoftwareRenderer::restoreState() } //============================================================================== -void LowLevelGraphicsSoftwareRenderer::setColour (const Colour& colour) -{ - currentState->fillType.setColour (colour); -} - -void LowLevelGraphicsSoftwareRenderer::setGradient (const ColourGradient& gradient) +void LowLevelGraphicsSoftwareRenderer::setFill (const FillType& fillType) { - currentState->fillType.setGradient (gradient); -} - -void LowLevelGraphicsSoftwareRenderer::setTiledFill (const Image& image, int x, int y) -{ - currentState->fillType.setTiledImage (image, x, y); + currentState->fillType = fillType; } void LowLevelGraphicsSoftwareRenderer::setOpacity (float opacity) @@ -1455,7 +1432,8 @@ public: GlyphCache() throw() : accessCounter (0), hits (0), misses (0) { - enlargeCache (120); + for (int i = 120; --i >= 0;) + glyphs.add (new CachedGlyph()); } ~GlyphCache() throw() @@ -1491,15 +1469,15 @@ public: } } - ++misses; - - if (hits + misses > (glyphs.size() << 4)) + if (hits + ++misses > (glyphs.size() << 4)) { if (misses * 2 > hits) - enlargeCache (glyphs.size() + 32); + { + for (int i = 32; --i >= 0;) + glyphs.add (new CachedGlyph()); + } - hits = 0; - misses = 0; + hits = misses = 0; oldest = glyphs.getLast(); } @@ -1513,16 +1491,8 @@ public: class CachedGlyph { public: - CachedGlyph() throw() - : glyph (0), lastAccessCount (0) - { - edgeTable = 0; - } - - ~CachedGlyph() throw() - { - delete edgeTable; - } + CachedGlyph() throw() : glyph (0), lastAccessCount (0), edgeTable (0) {} + ~CachedGlyph() throw() { delete edgeTable; } void draw (LLGCSavedState& state, Image& image, const float x, const float y) const throw() { @@ -1575,12 +1545,6 @@ public: juce_UseDebuggingNewOperator private: - void enlargeCache (const int num) throw() - { - while (glyphs.size() < num) - glyphs.add (new CachedGlyph()); - } - OwnedArray glyphs; int accessCounter, hits, misses; @@ -1615,7 +1579,6 @@ void LowLevelGraphicsSoftwareRenderer::drawGlyph (int glyphNumber, const AffineT { Path p; f.getTypeface()->getOutlineForGlyph (glyphNumber, p); - fillPath (p, AffineTransform::scale (f.getHeight() * f.getHorizontalScale(), f.getHeight()).followedBy (transform)); } } diff --git a/src/gui/graphics/contexts/juce_LowLevelGraphicsSoftwareRenderer.h b/src/gui/graphics/contexts/juce_LowLevelGraphicsSoftwareRenderer.h index a88a2d4a70..7495eb98aa 100644 --- a/src/gui/graphics/contexts/juce_LowLevelGraphicsSoftwareRenderer.h +++ b/src/gui/graphics/contexts/juce_LowLevelGraphicsSoftwareRenderer.h @@ -63,15 +63,11 @@ public: void restoreState(); //============================================================================== - void setColour (const Colour& colour); - void setGradient (const ColourGradient& gradient); - void setTiledFill (const Image& image, int x, int y); - + void setFill (const FillType& fillType); void setOpacity (float opacity); void setInterpolationQuality (Graphics::ResamplingQuality quality); //============================================================================== - void fillAll (const bool replaceContents); void fillRect (const Rectangle& r, const bool replaceExistingContents); void fillPath (const Path& path, const AffineTransform& transform); diff --git a/src/gui/graphics/drawables/juce_DrawablePath.cpp b/src/gui/graphics/drawables/juce_DrawablePath.cpp index beb2bf7628..7d567bf4d8 100644 --- a/src/gui/graphics/drawables/juce_DrawablePath.cpp +++ b/src/gui/graphics/drawables/juce_DrawablePath.cpp @@ -33,17 +33,14 @@ BEGIN_JUCE_NAMESPACE //============================================================================== DrawablePath::DrawablePath() - : fillColour (0xff000000), - fillGradient (0), - strokeGradient (0), + : mainFill (FillType (Colours::black)), + strokeFill (FillType (Colours::transparentBlack)), strokeType (0.0f) { } DrawablePath::~DrawablePath() { - delete fillGradient; - delete strokeGradient; } //============================================================================== @@ -53,16 +50,14 @@ void DrawablePath::setPath (const Path& newPath) throw() updateOutline(); } -void DrawablePath::setFillColour (const Colour& newColour) throw() +void DrawablePath::setFill (const FillType& newFill) throw() { - deleteAndZero (fillGradient); - fillColour = newColour; + mainFill = newFill; } -void DrawablePath::setFillGradient (const ColourGradient& gradient) throw() +void DrawablePath::setStrokeFill (const FillType& newFill) throw() { - delete fillGradient; - fillGradient = new ColourGradient (gradient); + strokeFill = newFill; } void DrawablePath::setStrokeType (const PathStrokeType& newStrokeType) throw() @@ -76,63 +71,39 @@ void DrawablePath::setStrokeThickness (const float newThickness) throw() setStrokeType (PathStrokeType (newThickness, strokeType.getJointStyle(), strokeType.getEndStyle())); } -void DrawablePath::setStrokeColour (const Colour& newStrokeColour) throw() -{ - deleteAndZero (strokeGradient); - strokeColour = newStrokeColour; -} - -void DrawablePath::setStrokeGradient (const ColourGradient& newStrokeGradient) throw() -{ - delete strokeGradient; - strokeGradient = new ColourGradient (newStrokeGradient); -} - //============================================================================== void DrawablePath::render (const Drawable::RenderingContext& context) const { - if (fillGradient != 0) - { - ColourGradient cg (*fillGradient); - cg.transform = cg.transform.followedBy (context.transform); - cg.multiplyOpacity (context.opacity); - context.g.setGradientFill (cg); - } - else - { - context.g.setColour (fillColour); - } + FillType f (mainFill); + if (f.isGradient()) + f.gradient->multiplyOpacity (context.opacity); + f.transform = f.transform.followedBy (context.transform); + context.g.setFillType (f); context.g.fillPath (path, context.transform); if (strokeType.getStrokeThickness() > 0.0f) { - if (strokeGradient != 0) - { - ColourGradient cg (*strokeGradient); - cg.transform = cg.transform.followedBy (context.transform); - cg.multiplyOpacity (context.opacity); - context.g.setGradientFill (cg); - } - else - { - context.g.setColour (strokeColour); - } + FillType f (strokeFill); + if (f.isGradient()) + f.gradient->multiplyOpacity (context.opacity); - context.g.fillPath (outline, context.transform); + f.transform = f.transform.followedBy (context.transform); + context.g.setFillType (f); + context.g.fillPath (stroke, context.transform); } } void DrawablePath::updateOutline() { - outline.clear(); - strokeType.createStrokedPath (outline, path, AffineTransform::identity, 4.0f); + stroke.clear(); + strokeType.createStrokedPath (stroke, path, AffineTransform::identity, 4.0f); } void DrawablePath::getBounds (float& x, float& y, float& width, float& height) const { if (strokeType.getStrokeThickness() > 0.0f) - outline.getBounds (x, y, width, height); + stroke.getBounds (x, y, width, height); else path.getBounds (x, y, width, height); } @@ -140,7 +111,7 @@ void DrawablePath::getBounds (float& x, float& y, float& width, float& height) c bool DrawablePath::hitTest (float x, float y) const { return path.contains (x, y) - || outline.contains (x, y); + || stroke.contains (x, y); } Drawable* DrawablePath::createCopy() const @@ -148,106 +119,107 @@ Drawable* DrawablePath::createCopy() const DrawablePath* const dp = new DrawablePath(); dp->path = path; - dp->outline = outline; - dp->fillColour = fillColour; - dp->strokeColour = strokeColour; - dp->fillGradient = (fillGradient != 0) ? new ColourGradient (*fillGradient) : 0; - dp->strokeGradient = (strokeGradient != 0) ? new ColourGradient (*strokeGradient) : 0; + dp->stroke = stroke; + dp->mainFill = mainFill; + dp->strokeFill = strokeFill; dp->strokeType = strokeType; return dp; } //============================================================================== -static const Colour readColourFromBinary (InputStream& input, ColourGradient*& gradient) +static const FillType readColourFromBinary (InputStream& input) { - deleteAndZero (gradient); - switch (input.readByte()) { case 1: - return Colour ((uint32) input.readInt()); + return FillType (Colour ((uint32) input.readInt())); case 2: { - gradient = new ColourGradient(); - gradient->x1 = input.readFloat(); - gradient->y1 = input.readFloat(); - gradient->x2 = input.readFloat(); - gradient->y2 = input.readFloat(); - gradient->isRadial = input.readByte() != 0; + ColourGradient g; + g.x1 = input.readFloat(); + g.y1 = input.readFloat(); + g.x2 = input.readFloat(); + g.y2 = input.readFloat(); + g.isRadial = input.readByte() != 0; const int numColours = input.readCompressedInt(); for (int i = 0; i < numColours; ++i) { double proportion = (double) input.readFloat(); const Colour col ((uint32) input.readInt()); - gradient->addColour (proportion, col); + g.addColour (proportion, col); } - break; + return FillType (g); } default: break; } - return Colours::black; + return FillType(); } -static void writeColourToBinary (OutputStream& output, const Colour& colour, const ColourGradient* const gradient) +static void writeColourToBinary (OutputStream& output, const FillType& fillType) { - if (gradient == 0) + if (fillType.isColour()) { output.writeByte (1); - output.writeInt ((int) colour.getARGB()); + output.writeInt ((int) fillType.colour.getARGB()); } - else + else if (fillType.isGradient()) { output.writeByte (2); - output.writeFloat (gradient->x1); - output.writeFloat (gradient->y1); - output.writeFloat (gradient->x2); - output.writeFloat (gradient->y2); - output.writeByte (gradient->isRadial ? 1 : 0); + output.writeFloat (fillType.gradient->x1); + output.writeFloat (fillType.gradient->y1); + output.writeFloat (fillType.gradient->x2); + output.writeFloat (fillType.gradient->y2); + output.writeByte (fillType.gradient->isRadial ? 1 : 0); - output.writeCompressedInt (gradient->getNumColours()); + output.writeCompressedInt (fillType.gradient->getNumColours()); - for (int i = 0; i < gradient->getNumColours(); ++i) + for (int i = 0; i < fillType.gradient->getNumColours(); ++i) { - output.writeFloat ((float) gradient->getColourPosition (i)); - output.writeInt ((int) gradient->getColour (i).getARGB()); + output.writeFloat ((float) fillType.gradient->getColourPosition (i)); + output.writeInt ((int) fillType.gradient->getColour (i).getARGB()); } } + else + { + jassertfalse // xxx + } + } -static const Colour readColourFromXml (const XmlElement* xml, ColourGradient*& gradient) +static const FillType readColourFromXml (const XmlElement* xml) { - deleteAndZero (gradient); - if (xml != 0) { const String type (xml->getStringAttribute (T("type"))); if (type.equalsIgnoreCase (T("solid"))) { - return Colour ((uint32) xml->getStringAttribute (T("colour"), T("ff000000")).getHexValue32()); + return FillType (Colour ((uint32) xml->getStringAttribute (T("colour"), T("ff000000")).getHexValue32())); } else if (type.equalsIgnoreCase (T("gradient"))) { - gradient = new ColourGradient(); - gradient->x1 = (float) xml->getDoubleAttribute (T("x1")); - gradient->y1 = (float) xml->getDoubleAttribute (T("y1")); - gradient->x2 = (float) xml->getDoubleAttribute (T("x2")); - gradient->y2 = (float) xml->getDoubleAttribute (T("y2")); - gradient->isRadial = xml->getBoolAttribute (T("radial"), false); + ColourGradient g; + g.x1 = (float) xml->getDoubleAttribute (T("x1")); + g.y1 = (float) xml->getDoubleAttribute (T("y1")); + g.x2 = (float) xml->getDoubleAttribute (T("x2")); + g.y2 = (float) xml->getDoubleAttribute (T("y2")); + g.isRadial = xml->getBoolAttribute (T("radial"), false); StringArray colours; colours.addTokens (xml->getStringAttribute (T("colours")), false); for (int i = 0; i < colours.size() / 2; ++i) - gradient->addColour (colours[i * 2].getDoubleValue(), - Colour ((uint32) colours[i * 2 + 1].getHexValue32())); + g.addColour (colours[i * 2].getDoubleValue(), + Colour ((uint32) colours[i * 2 + 1].getHexValue32())); + + return FillType (g); } else { @@ -255,42 +227,47 @@ static const Colour readColourFromXml (const XmlElement* xml, ColourGradient*& g } } - return Colours::black; + return FillType(); } -static XmlElement* writeColourToXml (const String& tagName, const Colour& colour, const ColourGradient* const gradient) +static XmlElement* writeColourToXml (const String& tagName, const FillType& fillType) { XmlElement* const xml = new XmlElement (tagName); - if (gradient == 0) + if (fillType.isColour()) { xml->setAttribute (T("type"), T("solid")); - xml->setAttribute (T("colour"), String::toHexString ((int) colour.getARGB())); + xml->setAttribute (T("colour"), String::toHexString ((int) fillType.colour.getARGB())); } - else + else if (fillType.isGradient()) { xml->setAttribute (T("type"), T("gradient")); - xml->setAttribute (T("x1"), gradient->x1); - xml->setAttribute (T("y1"), gradient->y1); - xml->setAttribute (T("x2"), gradient->x2); - xml->setAttribute (T("y2"), gradient->y2); - xml->setAttribute (T("radial"), gradient->isRadial); + xml->setAttribute (T("x1"), fillType.gradient->x1); + xml->setAttribute (T("y1"), fillType.gradient->y1); + xml->setAttribute (T("x2"), fillType.gradient->x2); + xml->setAttribute (T("y2"), fillType.gradient->y2); + xml->setAttribute (T("radial"), fillType.gradient->isRadial); String s; - for (int i = 0; i < gradient->getNumColours(); ++i) - s << " " << gradient->getColourPosition (i) << " " << String::toHexString ((int) gradient->getColour(i).getARGB()); + for (int i = 0; i < fillType.gradient->getNumColours(); ++i) + s << " " << fillType.gradient->getColourPosition (i) + << " " << String::toHexString ((int) fillType.gradient->getColour(i).getARGB()); xml->setAttribute (T("colours"), s.trimStart()); } + else + { + jassertfalse //xxx + } return xml; } bool DrawablePath::readBinary (InputStream& input) { - fillColour = readColourFromBinary (input, fillGradient); - strokeColour = readColourFromBinary (input, strokeGradient); + mainFill = readColourFromBinary (input); + strokeFill = readColourFromBinary (input); const float strokeThickness = input.readFloat(); const int jointStyle = input.readByte(); @@ -319,8 +296,8 @@ bool DrawablePath::readBinary (InputStream& input) bool DrawablePath::writeBinary (OutputStream& output) const { - writeColourToBinary (output, fillColour, fillGradient); - writeColourToBinary (output, strokeColour, strokeGradient); + writeColourToBinary (output, mainFill); + writeColourToBinary (output, strokeFill); output.writeFloat (strokeType.getStrokeThickness()); output.writeByte (strokeType.getJointStyle() == PathStrokeType::mitered ? 0 @@ -337,8 +314,8 @@ bool DrawablePath::writeBinary (OutputStream& output) const bool DrawablePath::readXml (const XmlElement& xml) { - fillColour = readColourFromXml (xml.getChildByName (T("fill")), fillGradient); - strokeColour = readColourFromXml (xml.getChildByName (T("stroke")), strokeGradient); + mainFill = readColourFromXml (xml.getChildByName (T("fill"))); + strokeFill = readColourFromXml (xml.getChildByName (T("stroke"))); const String jointStyle (xml.getStringAttribute (T("jointStyle"), String::empty)); const String endStyle (xml.getStringAttribute (T("capStyle"), String::empty)); @@ -358,8 +335,8 @@ bool DrawablePath::readXml (const XmlElement& xml) void DrawablePath::writeXml (XmlElement& xml) const { - xml.addChildElement (writeColourToXml (T("fill"), fillColour, fillGradient)); - xml.addChildElement (writeColourToXml (T("stroke"), strokeColour, strokeGradient)); + xml.addChildElement (writeColourToXml (T("fill"), mainFill)); + xml.addChildElement (writeColourToXml (T("stroke"), strokeFill)); xml.setAttribute (T("strokeWidth"), (double) strokeType.getStrokeThickness()); xml.setAttribute (T("jointStyle"), diff --git a/src/gui/graphics/drawables/juce_DrawablePath.h b/src/gui/graphics/drawables/juce_DrawablePath.h index aadb454f4c..b3276129d0 100644 --- a/src/gui/graphics/drawables/juce_DrawablePath.h +++ b/src/gui/graphics/drawables/juce_DrawablePath.h @@ -57,33 +57,33 @@ public: /** Returns the current path. */ const Path& getPath() const throw() { return path; } - /** Sets a colour to fill the path with. + /** Sets a fill type for the path. This colour is used to fill the path - if you don't want the path to be - filled (e.g. if you're just drawing an outline), set this colour to be - transparent. + filled (e.g. if you're just drawing an outline), set this to a transparent + colour. - @see setPath, setOutlineColour, setFillGradient + @see setPath, setStrokeFill */ - void setFillColour (const Colour& newColour) throw(); + void setFill (const FillType& newFill) throw(); - /** Sets a gradient to use to fill the path. + /** Returns the current fill type. + @see setFill */ - void setFillGradient (const ColourGradient& newGradient) throw(); + const FillType& getFill() const throw() { return mainFill; } - /** Sets the colour with which the outline will be drawn. - @see setStrokeGradient + /** Sets the fill type with which the outline will be drawn. + @see setFill */ - void setStrokeColour (const Colour& newStrokeColour) throw(); + void setStrokeFill (const FillType& newStrokeFill) throw(); - /** Sets a gradient with with the outline will be drawn. - @see setStrokeColour + /** Returns the current stroke fill. + @see setStrokeFill */ - void setStrokeGradient (const ColourGradient& newStrokeGradient) throw(); + const FillType& getStrokeFill() const throw() { return strokeFill; } /** Changes the properties of the outline that will be drawn around the path. If the stroke has 0 thickness, no stroke will be drawn. - @see setStrokeThickness, setStrokeColour */ void setStrokeType (const PathStrokeType& newStrokeType) throw(); @@ -94,7 +94,7 @@ public: void setStrokeThickness (const float newThickness) throw(); /** Returns the current outline style. */ - const PathStrokeType& getStrokeType() const throw() { return strokeType; } + const PathStrokeType& getStrokeType() const throw() { return strokeType; } //============================================================================== @@ -119,10 +119,8 @@ public: juce_UseDebuggingNewOperator private: - Path path, outline; - Colour fillColour, strokeColour; - ColourGradient* fillGradient; - ColourGradient* strokeGradient; + Path path, stroke; + FillType mainFill, strokeFill; PathStrokeType strokeType; void updateOutline(); diff --git a/src/gui/graphics/drawables/juce_SVGParser.cpp b/src/gui/graphics/drawables/juce_SVGParser.cpp index 71552478c7..3b43bb3b56 100644 --- a/src/gui/graphics/drawables/juce_SVGParser.cpp +++ b/src/gui/graphics/drawables/juce_SVGParser.cpp @@ -607,7 +607,7 @@ private: DrawablePath* dp = new DrawablePath(); dp->setName (xml.getStringAttribute (T("id"))); - dp->setFillColour (Colours::transparentBlack); + dp->setFill (FillType (Colours::transparentBlack)); path.applyTransform (transform); dp->setPath (path); @@ -624,47 +624,21 @@ private: } } - ColourGradient* fillGradient = 0; - const Colour fillColour (getPathFillType (path, - getStyleAttribute (&xml, T("fill")), - getStyleAttribute (&xml, T("fill-opacity")), - getStyleAttribute (&xml, T("opacity")), - containsClosedSubPath ? Colours::black - : Colours::transparentBlack, - fillGradient)); - - if (fillGradient != 0) - { - fillGradient->transform = fillGradient->transform.followedBy (transform); - dp->setFillGradient (*fillGradient); - delete fillGradient; - } - else - { - dp->setFillColour (fillColour); - } + dp->setFill (getPathFillType (path, + getStyleAttribute (&xml, T("fill")), + getStyleAttribute (&xml, T("fill-opacity")), + getStyleAttribute (&xml, T("opacity")), + containsClosedSubPath ? Colours::black + : Colours::transparentBlack)); const String strokeType (getStyleAttribute (&xml, T("stroke"))); if (strokeType.isNotEmpty() && ! strokeType.equalsIgnoreCase (T("none"))) { - ColourGradient* strokeGradient = 0; - const Colour strokeColour (getPathFillType (path, strokeType, - getStyleAttribute (&xml, T("stroke-opacity")), - getStyleAttribute (&xml, T("opacity")), - Colours::transparentBlack, - strokeGradient)); - - if (strokeGradient != 0) - { - strokeGradient->transform = strokeGradient->transform.followedBy (transform); - dp->setStrokeGradient (*strokeGradient); - delete strokeGradient; - } - else - { - dp->setStrokeColour (strokeColour); - } + dp->setStrokeFill (getPathFillType (path, strokeType, + getStyleAttribute (&xml, T("stroke-opacity")), + getStyleAttribute (&xml, T("opacity")), + Colours::transparentBlack)); dp->setStrokeType (getStrokeFor (&xml)); } @@ -704,12 +678,11 @@ private: } } - const Colour getPathFillType (const Path& path, - const String& fill, - const String& fillOpacity, - const String& overallOpacity, - const Colour& defaultColour, - ColourGradient*& gradient) const + const FillType getPathFillType (const Path& path, + const String& fill, + const String& fillOpacity, + const String& overallOpacity, + const Colour& defaultColour) const { float opacity = 1.0f; @@ -732,29 +705,28 @@ private: { const XmlElement* inheritedFrom = findLinkedElement (fillXml); - gradient = new ColourGradient(); + ColourGradient gradient; - addGradientStopsIn (*gradient, inheritedFrom); - addGradientStopsIn (*gradient, fillXml); + addGradientStopsIn (gradient, inheritedFrom); + addGradientStopsIn (gradient, fillXml); - if (gradient->getNumColours() > 0) + if (gradient.getNumColours() > 0) { - gradient->addColour (0.0, gradient->getColour (0)); - gradient->addColour (1.0, gradient->getColour (gradient->getNumColours() - 1)); + gradient.addColour (0.0, gradient.getColour (0)); + gradient.addColour (1.0, gradient.getColour (gradient.getNumColours() - 1)); } else { - gradient->addColour (0.0, Colours::black); - gradient->addColour (1.0, Colours::black); + gradient.addColour (0.0, Colours::black); + gradient.addColour (1.0, Colours::black); } if (overallOpacity.isNotEmpty()) - gradient->multiplyOpacity (overallOpacity.getFloatValue()); + gradient.multiplyOpacity (overallOpacity.getFloatValue()); - jassert (gradient->getNumColours() > 0); + jassert (gradient.getNumColours() > 0); - gradient->isRadial = fillXml->hasTagName (T("radialGradient")); - gradient->transform = parseTransform (fillXml->getStringAttribute (T("gradientTransform"))); + gradient.isRadial = fillXml->hasTagName (T("radialGradient")); float width = viewBoxW; float height = viewBoxH; @@ -766,35 +738,34 @@ private: if (! userSpace) path.getBounds (dx, dy, width, height); - if (gradient->isRadial) + if (gradient.isRadial) { - gradient->x1 = dx + getCoordLength (fillXml->getStringAttribute (T("cx"), T("50%")), width); - gradient->y1 = dy + getCoordLength (fillXml->getStringAttribute (T("cy"), T("50%")), height); + gradient.x1 = dx + getCoordLength (fillXml->getStringAttribute (T("cx"), T("50%")), width); + gradient.y1 = dy + getCoordLength (fillXml->getStringAttribute (T("cy"), T("50%")), height); const float radius = getCoordLength (fillXml->getStringAttribute (T("r"), T("50%")), width); - gradient->x2 = gradient->x1 + radius; - gradient->y2 = gradient->y1; + gradient.x2 = gradient.x1 + radius; + gradient.y2 = gradient.y1; //xxx (the fx, fy focal point isn't handled properly here..) } else { - gradient->x1 = dx + getCoordLength (fillXml->getStringAttribute (T("x1"), T("0%")), width); - gradient->y1 = dy + getCoordLength (fillXml->getStringAttribute (T("y1"), T("0%")), height); + gradient.x1 = dx + getCoordLength (fillXml->getStringAttribute (T("x1"), T("0%")), width); + gradient.y1 = dy + getCoordLength (fillXml->getStringAttribute (T("y1"), T("0%")), height); - gradient->x2 = dx + getCoordLength (fillXml->getStringAttribute (T("x2"), T("100%")), width); - gradient->y2 = dy + getCoordLength (fillXml->getStringAttribute (T("y2"), T("0%")), height); + gradient.x2 = dx + getCoordLength (fillXml->getStringAttribute (T("x2"), T("100%")), width); + gradient.y2 = dy + getCoordLength (fillXml->getStringAttribute (T("y2"), T("0%")), height); - if (gradient->x1 == gradient->x2 && gradient->y1 == gradient->y2) - { - const Colour col (gradient->getColour (gradient->getNumColours() - 1)); - deleteAndZero (gradient); - return col; - } + if (gradient.x1 == gradient.x2 && gradient.y1 == gradient.y2) + return Colour (gradient.getColour (gradient.getNumColours() - 1)); } - return defaultColour; + FillType type (gradient); + type.transform = parseTransform (fillXml->getStringAttribute (T("gradientTransform"))) + .followedBy (transform); + return type; } } @@ -802,7 +773,7 @@ private: return Colours::transparentBlack; int i = 0; - Colour colour (parseColour (fill, i, defaultColour)); + const Colour colour (parseColour (fill, i, defaultColour)); return colour.withMultipliedAlpha (opacity); } diff --git a/src/juce_amalgamated_template.cpp b/src/juce_amalgamated_template.cpp index 997e4eb8a0..affd191bcf 100644 --- a/src/juce_amalgamated_template.cpp +++ b/src/juce_amalgamated_template.cpp @@ -288,6 +288,7 @@ #include "gui/graphics/colour/juce_ColourGradient.cpp" #include "gui/graphics/colour/juce_Colours.cpp" #include "gui/graphics/contexts/juce_EdgeTable.cpp" +#include "gui/graphics/contexts/juce_FillType.cpp" #include "gui/graphics/contexts/juce_Graphics.cpp" #include "gui/graphics/contexts/juce_Justification.cpp" #include "gui/graphics/contexts/juce_LowLevelGraphicsPostScriptRenderer.cpp" diff --git a/src/native/linux/juce_linux_Windowing.cpp b/src/native/linux/juce_linux_Windowing.cpp index 8ba89c2347..323b941250 100644 --- a/src/native/linux/juce_linux_Windowing.cpp +++ b/src/native/linux/juce_linux_Windowing.cpp @@ -1799,7 +1799,7 @@ private: context.setOrigin (-totalArea.getX(), -totalArea.getY()); - if (context.reduceClipRegion (regionsNeedingRepaint)) + if (context.clipToRectangleList (regionsNeedingRepaint)) peer->handlePaint (context); if (! peer->maskedRegion.isEmpty()) @@ -2570,31 +2570,52 @@ void juce_updateMultiMonitorInfo (Array & monitorCoords, const bool / #if JUCE_USE_XINERAMA int major_opcode, first_event, first_error; - if (XQueryExtension (display, "XINERAMA", &major_opcode, &first_event, &first_error) - && XineramaIsActive (display)) + if (XQueryExtension (display, "XINERAMA", &major_opcode, &first_event, &first_error)) { - int numMonitors = 0; - XineramaScreenInfo* const screens = XineramaQueryScreens (display, &numMonitors); + typedef Bool (*tXineramaIsActive) (Display*); + typedef XineramaScreenInfo* (*tXineramaQueryScreens) (Display*, int*); - if (screens != 0) + static tXineramaIsActive xXineramaIsActive = 0; + static tXineramaQueryScreens xXineramaQueryScreens = 0; + + if (xXineramaIsActive == 0 || xXineramaQueryScreens == 0) { - for (int i = numMonitors; --i >= 0;) + void* h = dlopen ("libXinerama.so", RTLD_GLOBAL | RTLD_NOW); + + if (h != 0) { - int index = screens[i].screen_number; + xXineramaIsActive = (tXineramaIsActive) dlsym (h, "XineramaIsActive"); + xXineramaQueryScreens = (tXineramaQueryScreens) dlsym (h, "XineramaQueryScreens"); + } + } + + if (xXineramaIsActive != 0 + && xXineramaQueryScreens != 0 + && xXineramaIsActive (display)) + { + int numMonitors = 0; + XineramaScreenInfo* const screens = xXineramaQueryScreens (display, &numMonitors); - if (index >= 0) + if (screens != 0) + { + for (int i = numMonitors; --i >= 0;) { - while (monitorCoords.size() < index) - monitorCoords.add (Rectangle (0, 0, 0, 0)); + int index = screens[i].screen_number; + + if (index >= 0) + { + while (monitorCoords.size() < index) + monitorCoords.add (Rectangle (0, 0, 0, 0)); - monitorCoords.set (index, Rectangle (screens[i].x_org, - screens[i].y_org, - screens[i].width, - screens[i].height)); + monitorCoords.set (index, Rectangle (screens[i].x_org, + screens[i].y_org, + screens[i].width, + screens[i].height)); + } } - } - XFree (screens); + XFree (screens); + } } } diff --git a/src/native/mac/juce_mac_CoreGraphicsContext.mm b/src/native/mac/juce_mac_CoreGraphicsContext.mm index 57fcaf573c..4c172fbf84 100644 --- a/src/native/mac/juce_mac_CoreGraphicsContext.mm +++ b/src/native/mac/juce_mac_CoreGraphicsContext.mm @@ -209,24 +209,16 @@ public: } //============================================================================== - void setColour (const Colour& colour) + void setFill (const FillType& fillType) { - state->fillType.setColour (colour); + state->fillType = fillType; - CGContextSetRGBFillColor (context, - colour.getFloatRed(), colour.getFloatGreen(), - colour.getFloatBlue(), colour.getFloatAlpha()); - CGContextSetAlpha (context, 1.0f); - } - - void setGradient (const ColourGradient& gradient) - { - state->fillType.setGradient (gradient); - } - - void setTiledFill (const Image& image, int x, int y) - { - state->fillType.setTiledImage (image, x, y); + if (fillType.isColour()) + { + CGContextSetRGBFillColor (context, fillType.colour.getFloatRed(), fillType.colour.getFloatGreen(), + fillType.colour.getFloatBlue(), fillType.colour.getFloatAlpha()); + CGContextSetAlpha (context, 1.0f); + } } void setOpacity (float opacity) @@ -272,7 +264,6 @@ public: { CGContextSaveGState (context); CGContextClipToRect (context, cgRect); - flip(); drawGradient(); CGContextRestoreGState (context); } @@ -281,7 +272,7 @@ public: CGContextSaveGState (context); CGContextClipToRect (context, cgRect); drawImage (*(state->fillType.image), Rectangle (0, 0, state->fillType.image->getWidth(), state->fillType.image->getHeight()), - AffineTransform::translation (state->fillType.imageX, state->fillType.imageY), true); + state->fillType.transform, true); CGContextRestoreGState (context); } } @@ -302,22 +293,21 @@ public: else CGContextEOFillPath (context); } - else if (state->fillType.isGradient()) - { - createPath (path, transform); - CGContextClip (context); - flip(); - applyTransform (state->fillType.gradient->transform); - drawGradient(); - } else { createPath (path, transform); - CGContextClip (context); - drawImage (*(state->fillType.image), Rectangle (0, 0, state->fillType.image->getWidth(), state->fillType.image->getHeight()), - AffineTransform::translation (state->fillType.imageX, state->fillType.imageY), true); - } + if (path.isUsingNonZeroWinding()) + CGContextClip (context); + else + CGContextEOClip (context); + + if (state->fillType.isGradient()) + drawGradient(); + else + drawImage (*(state->fillType.image), Rectangle (0, 0, state->fillType.image->getWidth(), state->fillType.image->getHeight()), + state->fillType.transform, true); + } CGContextRestoreGState (context); } @@ -492,7 +482,7 @@ private: { } - Graphics::FillType fillType; + FillType fillType; Font font; CGFontRef fontRef; CGAffineTransform fontTransform; @@ -517,10 +507,10 @@ private: outData[3] = colour.getAlpha() / 255.0f; } - CGShadingRef createGradient (const ColourGradient* const gradient) throw() + CGShadingRef createGradient (const AffineTransform& transform, const ColourGradient* const gradient) throw() { delete gradientLookupTable; - gradientLookupTable = gradient->createLookupTable (numGradientLookupEntries); + gradientLookupTable = gradient->createLookupTable (transform, numGradientLookupEntries); --numGradientLookupEntries; CGShadingRef result = 0; @@ -546,10 +536,13 @@ private: void drawGradient() throw() { + flip(); + applyTransform (state->fillType.transform); + CGContextSetAlpha (context, 1.0f); CGContextSetInterpolationQuality (context, kCGInterpolationDefault); // (This is required for 10.4, where there's a crash if // you draw a gradient with high quality interp enabled). - CGShadingRef shading = createGradient (state->fillType.gradient); + CGShadingRef shading = createGradient (state->fillType.transform, state->fillType.gradient); CGContextDrawShading (context, shading); CGShadingRelease (shading); }