Browse Source

Updated the demo to have a new graphics rendering test page - this tests a lot of the new graphics features and lets you swap between software/OS rendering engines. Also fixed a mac menu bug, and mac mouse event timestamps.

tags/2021-05-28
Julian Storer 15 years ago
parent
commit
ded840d456
18 changed files with 464 additions and 188 deletions
  1. +14
    -14
      extras/juce demo/build/linux/JuceDemo.make
  2. +6
    -4
      extras/juce demo/build/macosx/jucedemo.xcodeproj/project.pbxproj
  3. +6
    -20
      extras/juce demo/build/win32_vc8/jucedemo.vcproj
  4. +25
    -12
      extras/juce demo/src/MainDemoWindow.cpp
  5. +1
    -1
      extras/juce demo/src/jucedemo_headers.h
  6. +186
    -71
      juce_amalgamated.cpp
  7. +25
    -3
      juce_amalgamated.h
  8. +16
    -0
      src/gui/components/windows/juce_ComponentPeer.cpp
  9. +5
    -0
      src/gui/components/windows/juce_ComponentPeer.h
  10. +7
    -0
      src/gui/graphics/contexts/juce_FillType.cpp
  11. +20
    -1
      src/gui/graphics/contexts/juce_FillType.h
  12. +1
    -2
      src/gui/graphics/contexts/juce_LowLevelGraphicsContext.h
  13. +16
    -9
      src/gui/graphics/contexts/juce_LowLevelGraphicsSoftwareRenderer.cpp
  14. +5
    -1
      src/native/mac/juce_iphone_UIViewComponentPeer.mm
  15. +11
    -11
      src/native/mac/juce_mac_CoreGraphicsContext.mm
  16. +22
    -0
      src/native/mac/juce_mac_MainMenu.mm
  17. +80
    -35
      src/native/mac/juce_mac_NSViewComponentPeer.mm
  18. +18
    -4
      src/text/juce_XmlElement.cpp

+ 14
- 14
extras/juce demo/build/linux/JuceDemo.make View File

@@ -39,10 +39,10 @@ ifeq ($(CONFIG),Release)
endif

OBJECTS := \
$(OBJDIR)/MainDemoWindow.o \
$(OBJDIR)/BinaryData.o \
$(OBJDIR)/ApplicationStartup.o \
$(OBJDIR)/juce_LibrarySource.o \
$(OBJDIR)/MainDemoWindow.o \
$(OBJDIR)/AudioDemoLatencyPage.o \
$(OBJDIR)/AudioDemoPlaybackPage.o \
$(OBJDIR)/AudioDemoRecordPage.o \
@@ -51,17 +51,17 @@ OBJECTS := \
$(OBJDIR)/AudioDemoTabComponent.o \
$(OBJDIR)/CameraDemo.o \
$(OBJDIR)/DragAndDropDemo.o \
$(OBJDIR)/FontsAndTextDemo.o \
$(OBJDIR)/InterprocessCommsDemo.o \
$(OBJDIR)/OpenGLDemo.o \
$(OBJDIR)/RenderingTestComponent.o \
$(OBJDIR)/QuickTimeDemo.o \
$(OBJDIR)/TableDemo.o \
$(OBJDIR)/ThreadingDemo.o \
$(OBJDIR)/TreeViewDemo.o \
$(OBJDIR)/WebBrowserDemo.o \
$(OBJDIR)/WidgetsDemo.o \
$(OBJDIR)/CodeEditorDemo.o \
$(OBJDIR)/PathsAndTransformsDemo.o \
$(OBJDIR)/FontsAndTextDemo.o \
$(OBJDIR)/WidgetsDemo.o \

MKDIR_TYPE := msdos
CMD := $(subst \,\\,$(ComSpec)$(COMSPEC))
@@ -103,22 +103,22 @@ else
-@if exist $(subst /,\,$(OBJDIR)) rmdir /s /q $(subst /,\,$(OBJDIR))
endif

$(OBJDIR)/BinaryData.o: ../../src/BinaryData.cpp
$(OBJDIR)/MainDemoWindow.o: ../../src/MainDemoWindow.cpp
-@$(CMD_MKOBJDIR)
@echo $(notdir $<)
@$(CXX) $(CXXFLAGS) -o "$@" -c "$<"

$(OBJDIR)/ApplicationStartup.o: ../../src/ApplicationStartup.cpp
$(OBJDIR)/BinaryData.o: ../../src/BinaryData.cpp
-@$(CMD_MKOBJDIR)
@echo $(notdir $<)
@$(CXX) $(CXXFLAGS) -o "$@" -c "$<"

$(OBJDIR)/juce_LibrarySource.o: ../../src/juce_LibrarySource.cpp
$(OBJDIR)/ApplicationStartup.o: ../../src/ApplicationStartup.cpp
-@$(CMD_MKOBJDIR)
@echo $(notdir $<)
@$(CXX) $(CXXFLAGS) -o "$@" -c "$<"

$(OBJDIR)/MainDemoWindow.o: ../../src/MainDemoWindow.cpp
$(OBJDIR)/juce_LibrarySource.o: ../../src/juce_LibrarySource.cpp
-@$(CMD_MKOBJDIR)
@echo $(notdir $<)
@$(CXX) $(CXXFLAGS) -o "$@" -c "$<"
@@ -163,17 +163,17 @@ $(OBJDIR)/DragAndDropDemo.o: ../../src/demos/DragAndDropDemo.cpp
@echo $(notdir $<)
@$(CXX) $(CXXFLAGS) -o "$@" -c "$<"

$(OBJDIR)/FontsAndTextDemo.o: ../../src/demos/FontsAndTextDemo.cpp
$(OBJDIR)/InterprocessCommsDemo.o: ../../src/demos/InterprocessCommsDemo.cpp
-@$(CMD_MKOBJDIR)
@echo $(notdir $<)
@$(CXX) $(CXXFLAGS) -o "$@" -c "$<"

$(OBJDIR)/InterprocessCommsDemo.o: ../../src/demos/InterprocessCommsDemo.cpp
$(OBJDIR)/OpenGLDemo.o: ../../src/demos/OpenGLDemo.cpp
-@$(CMD_MKOBJDIR)
@echo $(notdir $<)
@$(CXX) $(CXXFLAGS) -o "$@" -c "$<"

$(OBJDIR)/OpenGLDemo.o: ../../src/demos/OpenGLDemo.cpp
$(OBJDIR)/RenderingTestComponent.o: ../../src/demos/RenderingTestComponent.cpp
-@$(CMD_MKOBJDIR)
@echo $(notdir $<)
@$(CXX) $(CXXFLAGS) -o "$@" -c "$<"
@@ -203,17 +203,17 @@ $(OBJDIR)/WebBrowserDemo.o: ../../src/demos/WebBrowserDemo.cpp
@echo $(notdir $<)
@$(CXX) $(CXXFLAGS) -o "$@" -c "$<"

$(OBJDIR)/WidgetsDemo.o: ../../src/demos/WidgetsDemo.cpp
$(OBJDIR)/CodeEditorDemo.o: ../../src/demos/CodeEditorDemo.cpp
-@$(CMD_MKOBJDIR)
@echo $(notdir $<)
@$(CXX) $(CXXFLAGS) -o "$@" -c "$<"

$(OBJDIR)/CodeEditorDemo.o: ../../src/demos/CodeEditorDemo.cpp
$(OBJDIR)/FontsAndTextDemo.o: ../../src/demos/FontsAndTextDemo.cpp
-@$(CMD_MKOBJDIR)
@echo $(notdir $<)
@$(CXX) $(CXXFLAGS) -o "$@" -c "$<"

$(OBJDIR)/PathsAndTransformsDemo.o: ../../src/demos/PathsAndTransformsDemo.cpp
$(OBJDIR)/WidgetsDemo.o: ../../src/demos/WidgetsDemo.cpp
-@$(CMD_MKOBJDIR)
@echo $(notdir $<)
@$(CXX) $(CXXFLAGS) -o "$@" -c "$<"


+ 6
- 4
extras/juce demo/build/macosx/jucedemo.xcodeproj/project.pbxproj View File

@@ -12,13 +12,13 @@
841FE43F0E8ABDD4003C3263 /* IOKit.framework in Frameworks */ = {isa = PBXBuildFile; fileRef = 841FE4390E8ABDD4003C3263 /* IOKit.framework */; };
841FE4400E8ABDD4003C3263 /* OpenGL.framework in Frameworks */ = {isa = PBXBuildFile; fileRef = 841FE43A0E8ABDD4003C3263 /* OpenGL.framework */; };
841FE4410E8ABDD4003C3263 /* WebKit.framework in Frameworks */ = {isa = PBXBuildFile; fileRef = 841FE43B0E8ABDD4003C3263 /* WebKit.framework */; };
8429581F10BDF8AA0029323B /* RenderingTestComponent.cpp in Sources */ = {isa = PBXBuildFile; fileRef = 8429581D10BDF8AA0029323B /* RenderingTestComponent.cpp */; };
8450577A0EB52CE500029DFF /* QuickTime.framework in Frameworks */ = {isa = PBXBuildFile; fileRef = 845057790EB52CE500029DFF /* QuickTime.framework */; };
847F4D900E8AC35C00F64426 /* QTKit.framework in Frameworks */ = {isa = PBXBuildFile; fileRef = 847F4D8F0E8AC35C00F64426 /* QTKit.framework */; };
847F4EA60E8BA9C300F64426 /* DragAndDropDemo.cpp in Sources */ = {isa = PBXBuildFile; fileRef = 847F4E9B0E8BA9C300F64426 /* DragAndDropDemo.cpp */; };
847F4EA70E8BA9C300F64426 /* FontsAndTextDemo.cpp in Sources */ = {isa = PBXBuildFile; fileRef = 847F4E9C0E8BA9C300F64426 /* FontsAndTextDemo.cpp */; };
847F4EA80E8BA9C300F64426 /* InterprocessCommsDemo.cpp in Sources */ = {isa = PBXBuildFile; fileRef = 847F4E9D0E8BA9C300F64426 /* InterprocessCommsDemo.cpp */; };
847F4EA90E8BA9C300F64426 /* OpenGLDemo.cpp in Sources */ = {isa = PBXBuildFile; fileRef = 847F4E9E0E8BA9C300F64426 /* OpenGLDemo.cpp */; };
847F4EAA0E8BA9C300F64426 /* PathsAndTransformsDemo.cpp in Sources */ = {isa = PBXBuildFile; fileRef = 847F4E9F0E8BA9C300F64426 /* PathsAndTransformsDemo.cpp */; };
847F4EAB0E8BA9C300F64426 /* QuickTimeDemo.cpp in Sources */ = {isa = PBXBuildFile; fileRef = 847F4EA00E8BA9C300F64426 /* QuickTimeDemo.cpp */; };
847F4EAC0E8BA9C300F64426 /* TableDemo.cpp in Sources */ = {isa = PBXBuildFile; fileRef = 847F4EA10E8BA9C300F64426 /* TableDemo.cpp */; };
847F4EAD0E8BA9C300F64426 /* ThreadingDemo.cpp in Sources */ = {isa = PBXBuildFile; fileRef = 847F4EA20E8BA9C300F64426 /* ThreadingDemo.cpp */; };
@@ -50,13 +50,14 @@
841FE4390E8ABDD4003C3263 /* IOKit.framework */ = {isa = PBXFileReference; lastKnownFileType = wrapper.framework; name = IOKit.framework; path = /System/Library/Frameworks/IOKit.framework; sourceTree = "<absolute>"; };
841FE43A0E8ABDD4003C3263 /* OpenGL.framework */ = {isa = PBXFileReference; lastKnownFileType = wrapper.framework; name = OpenGL.framework; path = /System/Library/Frameworks/OpenGL.framework; sourceTree = "<absolute>"; };
841FE43B0E8ABDD4003C3263 /* WebKit.framework */ = {isa = PBXFileReference; lastKnownFileType = wrapper.framework; name = WebKit.framework; path = /System/Library/Frameworks/WebKit.framework; sourceTree = "<absolute>"; };
8429581D10BDF8AA0029323B /* RenderingTestComponent.cpp */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.cpp.cpp; name = RenderingTestComponent.cpp; path = ../../src/demos/RenderingTestComponent.cpp; sourceTree = SOURCE_ROOT; };
8429581E10BDF8AA0029323B /* RenderingTestComponent.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; name = RenderingTestComponent.h; path = ../../src/demos/RenderingTestComponent.h; sourceTree = SOURCE_ROOT; };
845057790EB52CE500029DFF /* QuickTime.framework */ = {isa = PBXFileReference; lastKnownFileType = wrapper.framework; name = QuickTime.framework; path = /System/Library/Frameworks/QuickTime.framework; sourceTree = "<absolute>"; };
847F4D8F0E8AC35C00F64426 /* QTKit.framework */ = {isa = PBXFileReference; lastKnownFileType = wrapper.framework; name = QTKit.framework; path = /System/Library/Frameworks/QTKit.framework; sourceTree = "<absolute>"; };
847F4E9B0E8BA9C300F64426 /* DragAndDropDemo.cpp */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.cpp.cpp; name = DragAndDropDemo.cpp; path = ../../src/demos/DragAndDropDemo.cpp; sourceTree = SOURCE_ROOT; };
847F4E9C0E8BA9C300F64426 /* FontsAndTextDemo.cpp */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.cpp.cpp; name = FontsAndTextDemo.cpp; path = ../../src/demos/FontsAndTextDemo.cpp; sourceTree = SOURCE_ROOT; };
847F4E9D0E8BA9C300F64426 /* InterprocessCommsDemo.cpp */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.cpp.cpp; name = InterprocessCommsDemo.cpp; path = ../../src/demos/InterprocessCommsDemo.cpp; sourceTree = SOURCE_ROOT; };
847F4E9E0E8BA9C300F64426 /* OpenGLDemo.cpp */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.cpp.cpp; name = OpenGLDemo.cpp; path = ../../src/demos/OpenGLDemo.cpp; sourceTree = SOURCE_ROOT; };
847F4E9F0E8BA9C300F64426 /* PathsAndTransformsDemo.cpp */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.cpp.cpp; lineEnding = 2; name = PathsAndTransformsDemo.cpp; path = ../../src/demos/PathsAndTransformsDemo.cpp; sourceTree = SOURCE_ROOT; };
847F4EA00E8BA9C300F64426 /* QuickTimeDemo.cpp */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.cpp.cpp; name = QuickTimeDemo.cpp; path = ../../src/demos/QuickTimeDemo.cpp; sourceTree = SOURCE_ROOT; };
847F4EA10E8BA9C300F64426 /* TableDemo.cpp */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.cpp.cpp; name = TableDemo.cpp; path = ../../src/demos/TableDemo.cpp; sourceTree = SOURCE_ROOT; };
847F4EA20E8BA9C300F64426 /* ThreadingDemo.cpp */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.cpp.cpp; name = ThreadingDemo.cpp; path = ../../src/demos/ThreadingDemo.cpp; sourceTree = SOURCE_ROOT; };
@@ -196,7 +197,8 @@
847F4E9C0E8BA9C300F64426 /* FontsAndTextDemo.cpp */,
847F4E9D0E8BA9C300F64426 /* InterprocessCommsDemo.cpp */,
847F4E9E0E8BA9C300F64426 /* OpenGLDemo.cpp */,
847F4E9F0E8BA9C300F64426 /* PathsAndTransformsDemo.cpp */,
8429581D10BDF8AA0029323B /* RenderingTestComponent.cpp */,
8429581E10BDF8AA0029323B /* RenderingTestComponent.h */,
847F4EA00E8BA9C300F64426 /* QuickTimeDemo.cpp */,
847F4EA10E8BA9C300F64426 /* TableDemo.cpp */,
847F4EA20E8BA9C300F64426 /* ThreadingDemo.cpp */,
@@ -264,7 +266,6 @@
847F4EA70E8BA9C300F64426 /* FontsAndTextDemo.cpp in Sources */,
847F4EA80E8BA9C300F64426 /* InterprocessCommsDemo.cpp in Sources */,
847F4EA90E8BA9C300F64426 /* OpenGLDemo.cpp in Sources */,
847F4EAA0E8BA9C300F64426 /* PathsAndTransformsDemo.cpp in Sources */,
847F4EAB0E8BA9C300F64426 /* QuickTimeDemo.cpp in Sources */,
847F4EAC0E8BA9C300F64426 /* TableDemo.cpp in Sources */,
847F4EAD0E8BA9C300F64426 /* ThreadingDemo.cpp in Sources */,
@@ -283,6 +284,7 @@
84913FE21063947900456AFC /* AudioDemoTabComponent.cpp in Sources */,
849144091064E54800456AFC /* AudioDemoRecordPage.cpp in Sources */,
84EDCA1F10A19E730079DB17 /* CodeEditorDemo.cpp in Sources */,
8429581F10BDF8AA0029323B /* RenderingTestComponent.cpp in Sources */,
);
runOnlyForDeploymentPostprocessing = 0;
};


+ 6
- 20
extras/juce demo/build/win32_vc8/jucedemo.vcproj View File

@@ -393,29 +393,15 @@
>
</File>
<File
RelativePath="..\..\src\demos\PathsAndTransformsDemo.cpp"
RelativePath="..\..\src\demos\QuickTimeDemo.cpp"
>
<FileConfiguration
Name="Release|Win32"
>
<Tool
Name="VCCLCompilerTool"
PreprocessorDefinitions=""
UsePrecompiledHeader="0"
/>
</FileConfiguration>
<FileConfiguration
Name="Debug|Win32"
>
<Tool
Name="VCCLCompilerTool"
PreprocessorDefinitions=""
UsePrecompiledHeader="0"
/>
</FileConfiguration>
</File>
<File
RelativePath="..\..\src\demos\QuickTimeDemo.cpp"
RelativePath="..\..\src\demos\RenderingTestComponent.cpp"
>
</File>
<File
RelativePath="..\..\src\demos\RenderingTestComponent.h"
>
</File>
<File


+ 25
- 12
extras/juce demo/src/MainDemoWindow.cpp View File

@@ -46,7 +46,7 @@ class ContentComp : public Component,
enum CommandIDs
{
showPathsAndTransforms = 0x2000,
showRendering = 0x2000,
showFontsAndText = 0x2001,
showWidgets = 0x2002,
showThreading = 0x2003,
@@ -75,7 +75,7 @@ public:
currentDemo (0),
currentDemoId (0)
{
invokeDirectly (showPathsAndTransforms, true);
invokeDirectly (showRendering, true);
}
~ContentComp()
@@ -121,7 +121,7 @@ public:
if (menuIndex == 0)
{
menu.addCommandItem (commandManager, showPathsAndTransforms);
menu.addCommandItem (commandManager, showRendering);
menu.addCommandItem (commandManager, showFontsAndText);
menu.addCommandItem (commandManager, showWidgets);
menu.addCommandItem (commandManager, showThreading);
@@ -153,6 +153,16 @@ public:
#if ! JUCE_LINUX
menu.addCommandItem (commandManager, goToKioskMode);
#endif
StringArray renderingEngines (getPeer()->getAvailableRenderingEngines());
if (renderingEngines.size() > 1)
{
menu.addSeparator();
for (int i = 0; i < renderingEngines.size(); ++i)
menu.addItem (5001 + i, "Use " + renderingEngines[i], true,
i == getPeer()->getCurrentRenderingEngine());
}
}
return menu;
@@ -161,8 +171,11 @@ public:
void menuItemSelected (int menuItemID,
int topLevelMenuIndex)
{
// all our menu items are invoked automatically as commands, so no need to do
// anything in this callback
// most of our menu items are invoked automatically as commands, but we can handle the
// other special cases here..
if (menuItemID >= 5001 && menuItemID < 5010)
getPeer()->setCurrentRenderingEngine (menuItemID - 5001);
}
//==============================================================================
@@ -180,7 +193,7 @@ public:
void getAllCommands (Array <CommandID>& commands)
{
// this returns the set of all commands that this target can perform..
const CommandID ids[] = { showPathsAndTransforms,
const CommandID ids[] = { showRendering,
showFontsAndText,
showWidgets,
showThreading,
@@ -218,9 +231,9 @@ public:
switch (commandID)
{
case showPathsAndTransforms:
result.setInfo (T("Paths and Transforms"), T("Shows the paths & transforms demo"), demosCategory, 0);
result.setTicked (currentDemoId == showPathsAndTransforms);
case showRendering:
result.setInfo (T("Graphics Rendering"), T("Shows the graphics demo"), demosCategory, 0);
result.setTicked (currentDemoId == showRendering);
result.addDefaultKeypress (T('1'), ModifierKeys::commandModifier);
break;
@@ -353,9 +366,9 @@ public:
{
switch (info.commandID)
{
case showPathsAndTransforms:
showDemo (createPathsAndTransformsDemo());
currentDemoId = showPathsAndTransforms;
case showRendering:
showDemo (createRenderingDemo());
currentDemoId = showRendering;
break;
case showFontsAndText:


+ 1
- 1
extras/juce demo/src/jucedemo_headers.h View File

@@ -42,7 +42,7 @@
// Pre-declare the functions that create each of the demo components..
Component* createFontsAndTextDemo();
Component* createPathsAndTransformsDemo();
Component* createRenderingDemo();
Component* createWidgetsDemo (ApplicationCommandManager* commandManager);
Component* createThreadingDemo();
Component* createTreeViewDemo();


+ 186
- 71
juce_amalgamated.cpp View File

@@ -14639,13 +14639,27 @@ bool XmlElement::writeToFile (const File& f,
<< dtd << "\r\n";

writeElementAsText (*out, 0, lineWrapLength);

delete out;

if (tempFile.moveFileTo (f))
return true;
if (! tempFile.exists())
return false;

tempFile.deleteFile();
int i;
for (i = 5; --i >= 0;)
{
if (tempFile.moveFileTo (f))
return true;

Thread::sleep (100);
}

for (i = 5; --i >= 0;)
{
if (tempFile.deleteFile())
break;

Thread::sleep (100);
}
}
}

@@ -75911,6 +75925,22 @@ void ComponentPeer::addMaskedRegion (int x, int y, int w, int h) throw()
maskedRegion.add (x, y, w, h);
}

const StringArray ComponentPeer::getAvailableRenderingEngines() throw()
{
StringArray s;
s.add ("Software Renderer");
return s;
}

int ComponentPeer::getCurrentRenderingEngine() throw()
{
return 0;
}

void ComponentPeer::setCurrentRenderingEngine (int /*index*/) throw()
{
}

END_JUCE_NAMESPACE
/********* End of inlined file: juce_ComponentPeer.cpp *********/

@@ -79228,6 +79258,7 @@ void FillType::setGradient (const ColourGradient& newGradient) throw()
{
image = 0;
gradient = new ColourGradient (newGradient);
colour = Colours::black;
}
}

@@ -79236,6 +79267,12 @@ void FillType::setTiledImage (const Image& image_, const AffineTransform& transf
deleteAndZero (gradient);
image = &image_;
transform = transform_;
colour = Colours::black;
}

void FillType::setOpacity (const float newOpacity) throw()
{
colour = colour.withAlpha (newOpacity);
}

END_JUCE_NAMESPACE
@@ -81459,6 +81496,7 @@ public:
jassert (! replaceContents); // that option is just for solid colours

ColourGradient g2 (*(fillType.gradient));
g2.multiplyOpacity (fillType.getOpacity());
AffineTransform transform (fillType.transform.translated ((float) xOffset, (float) yOffset));
const bool isIdentity = transform.isOnlyTranslation();

@@ -81863,9 +81901,9 @@ void LowLevelGraphicsSoftwareRenderer::setFill (const FillType& fillType)
currentState->fillType = fillType;
}

void LowLevelGraphicsSoftwareRenderer::setOpacity (float opacity)
void LowLevelGraphicsSoftwareRenderer::setOpacity (float newOpacity)
{
currentState->fillType.colour = currentState->fillType.colour.withAlpha (opacity);
currentState->fillType.setOpacity (newOpacity);
}

void LowLevelGraphicsSoftwareRenderer::setInterpolationQuality (Graphics::ResamplingQuality quality)
@@ -81910,15 +81948,21 @@ void LowLevelGraphicsSoftwareRenderer::drawLine (double x1, double y1, double x2

void LowLevelGraphicsSoftwareRenderer::drawVerticalLine (const int x, double top, double bottom)
{
EdgeTable et ((float) (x + currentState->xOffset), (float) (top + currentState->yOffset), 1.0f, (float) (bottom - top));
currentState->fillEdgeTable (image, et);
if (bottom > top)
{
EdgeTable et ((float) (x + currentState->xOffset), (float) (top + currentState->yOffset), 1.0f, (float) (bottom - top));
currentState->fillEdgeTable (image, et);
}
}

void LowLevelGraphicsSoftwareRenderer::drawHorizontalLine (const int y, double left, double right)
{
EdgeTable et ((float) (left + currentState->xOffset), (float) (y + currentState->yOffset),
(float) (right - left), 1.0f);
currentState->fillEdgeTable (image, et);
if (right > left)
{
EdgeTable et ((float) (left + currentState->xOffset), (float) (y + currentState->yOffset),
(float) (right - left), 1.0f);
currentState->fillEdgeTable (image, et);
}
}

class GlyphCache : private DeletedAtShutdown
@@ -82012,7 +82056,7 @@ public:
const AffineTransform transform (AffineTransform::scale (fontHeight * font.getHorizontalScale(), fontHeight));

float px, py, pw, ph;
glyphPath.getBoundsTransformed (transform, px, py, pw, ph);
glyphPath.getBoundsTransformed (transform.translated (0.0f, -0.5f), px, py, pw, ph);

Rectangle clip ((int) floorf (px), (int) floorf (py),
roundFloatToInt (pw) + 2, roundFloatToInt (ph) + 2);
@@ -82063,7 +82107,7 @@ void LowLevelGraphicsSoftwareRenderer::drawGlyph (int glyphNumber, const AffineT
{
GlyphCache::getInstance()->drawGlyph (*currentState, image, f, glyphNumber,
transform.getTranslationX() + (float) currentState->xOffset,
roundFloatToInt (transform.getTranslationY() + (float) currentState->yOffset));
transform.getTranslationY() + (float) currentState->yOffset);
}
else
{
@@ -261555,9 +261599,9 @@ public:
}
}

void setOpacity (float opacity)
void setOpacity (float newOpacity)
{
state->fillType.colour = state->fillType.colour.withAlpha (opacity);
state->fillType.setOpacity (newOpacity);
setFill (state->fillType);
}

@@ -261655,7 +261699,7 @@ public:
CGImageRelease (fullImage);

CGContextSaveGState (context);
CGContextSetAlpha (context, state->fillType.colour.getFloatAlpha());
CGContextSetAlpha (context, state->fillType.getOpacity());

flip();
applyTransform (AffineTransform::scale (1.0f, -1.0f).translated (0, sourceImage.getHeight()).followedBy (transform));
@@ -261840,26 +261884,27 @@ private:
outData[3] = colour.getAlpha() / 255.0f;
}

CGShadingRef createGradient (const AffineTransform& transform, const ColourGradient* const gradient) throw()
CGShadingRef createGradient (const AffineTransform& transform, ColourGradient gradient) throw()
{
// gradient.multiplyOpacity (state->fillType.getOpacity());
delete gradientLookupTable;
gradientLookupTable = gradient->createLookupTable (transform, numGradientLookupEntries);
gradientLookupTable = gradient.createLookupTable (transform, numGradientLookupEntries);
--numGradientLookupEntries;

CGShadingRef result = 0;
CGFunctionRef function = CGFunctionCreate ((void*) this, 1, 0, 4, 0, &gradientCallbacks);
CGPoint p1 (CGPointMake (gradient->x1, gradient->y1));
CGPoint p1 (CGPointMake (gradient.x1, gradient.y1));

if (gradient->isRadial)
if (gradient.isRadial)
{
result = CGShadingCreateRadial (rgbColourSpace, p1, 0,
p1, hypotf (gradient->x1 - gradient->x2, gradient->y1 - gradient->y2),
p1, hypotf (gradient.x1 - gradient.x2, gradient.y1 - gradient.y2),
function, true, true);
}
else
{
result = CGShadingCreateAxial (rgbColourSpace, p1,
CGPointMake (gradient->x2, gradient->y2),
CGPointMake (gradient.x2, gradient.y2),
function, true, true);
}

@@ -261872,10 +261917,9 @@ private:
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.transform, state->fillType.gradient);
CGShadingRef shading = createGradient (state->fillType.transform, *(state->fillType.gradient));
CGContextDrawShading (context, shading);
CGShadingRelease (shading);
}
@@ -262146,7 +262190,11 @@ static int getModifierForButtonNumber (const int num) throw()
: (num == 2 ? ModifierKeys::middleButtonModifier : 0));
}

static int64 getMouseTime (UIEvent* e) { return (int64) ([e timestamp] * 1000.0); }
static int64 getMouseTime (UIEvent* e) throw()
{
return (Time::currentTimeMillis() - Time::getMillisecondCounter())
+ (int64) ([e timestamp] * 1000.0);
}

int juce_lastMouseX = 0, juce_lastMouseY = 0;

@@ -266003,9 +266051,9 @@ public:
}
}

void setOpacity (float opacity)
void setOpacity (float newOpacity)
{
state->fillType.colour = state->fillType.colour.withAlpha (opacity);
state->fillType.setOpacity (newOpacity);
setFill (state->fillType);
}

@@ -266103,7 +266151,7 @@ public:
CGImageRelease (fullImage);

CGContextSaveGState (context);
CGContextSetAlpha (context, state->fillType.colour.getFloatAlpha());
CGContextSetAlpha (context, state->fillType.getOpacity());

flip();
applyTransform (AffineTransform::scale (1.0f, -1.0f).translated (0, sourceImage.getHeight()).followedBy (transform));
@@ -266288,26 +266336,27 @@ private:
outData[3] = colour.getAlpha() / 255.0f;
}

CGShadingRef createGradient (const AffineTransform& transform, const ColourGradient* const gradient) throw()
CGShadingRef createGradient (const AffineTransform& transform, ColourGradient gradient) throw()
{
// gradient.multiplyOpacity (state->fillType.getOpacity());
delete gradientLookupTable;
gradientLookupTable = gradient->createLookupTable (transform, numGradientLookupEntries);
gradientLookupTable = gradient.createLookupTable (transform, numGradientLookupEntries);
--numGradientLookupEntries;

CGShadingRef result = 0;
CGFunctionRef function = CGFunctionCreate ((void*) this, 1, 0, 4, 0, &gradientCallbacks);
CGPoint p1 (CGPointMake (gradient->x1, gradient->y1));
CGPoint p1 (CGPointMake (gradient.x1, gradient.y1));

if (gradient->isRadial)
if (gradient.isRadial)
{
result = CGShadingCreateRadial (rgbColourSpace, p1, 0,
p1, hypotf (gradient->x1 - gradient->x2, gradient->y1 - gradient->y2),
p1, hypotf (gradient.x1 - gradient.x2, gradient.y1 - gradient.y2),
function, true, true);
}
else
{
result = CGShadingCreateAxial (rgbColourSpace, p1,
CGPointMake (gradient->x2, gradient->y2),
CGPointMake (gradient.x2, gradient.y2),
function, true, true);
}

@@ -266320,10 +266369,9 @@ private:
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.transform, state->fillType.gradient);
CGShadingRef shading = createGradient (state->fillType.transform, *(state->fillType.gradient));
CGContextDrawShading (context, shading);
CGShadingRelease (shading);
}
@@ -266563,6 +266611,9 @@ public:
void toFront (bool makeActiveWindow);
void toBehind (ComponentPeer* other);
void setIcon (const Image& newIcon);
const StringArray getAvailableRenderingEngines() throw();
int getCurrentRenderingEngine() throw();
void setCurrentRenderingEngine (int index) throw();

/* When you use multiple DLLs which share similarly-named obj-c classes - like
for example having more than one juce plugin loaded into a host, then when a
@@ -266618,7 +266669,7 @@ public:

NSWindow* window;
JuceNSView* view;
bool isSharedWindow, fullScreen, insideDrawRect;
bool isSharedWindow, fullScreen, insideDrawRect, usingCoreGraphics;
};

END_JUCE_NAMESPACE
@@ -267036,7 +267087,11 @@ void ModifierKeys::updateCurrentModifiers() throw()
currentModifierFlags = currentModifiers;
}

static int64 getMouseTime (NSEvent* e) { return (int64) [e timestamp] * 1000.0; }
static int64 getMouseTime (NSEvent* e) throw()
{
return (Time::currentTimeMillis() - Time::getMillisecondCounter())
+ (int64) ([e timestamp] * 1000.0);
}

static void getMousePos (NSEvent* e, NSView* view, int& x, int& y)
{
@@ -267060,7 +267115,12 @@ NSViewComponentPeer::NSViewComponentPeer (Component* const component,
view (0),
isSharedWindow (viewToAttachTo != 0),
fullScreen (false),
insideDrawRect (false)
insideDrawRect (false),
#if USE_COREGRAPHICS_RENDERING
usingCoreGraphics (true)
#else
usingCoreGraphics (false)
#endif
{
NSRect r;
r.origin.x = 0;
@@ -267721,45 +267781,78 @@ void NSViewComponentPeer::drawRect (NSRect r)
CGContextClearRect (cg, CGContextGetClipBoundingBox (cg));

#if USE_COREGRAPHICS_RENDERING
CoreGraphicsContext context (cg, [view frame].size.height);
if (usingCoreGraphics)
{
CoreGraphicsContext context (cg, [view frame].size.height);

insideDrawRect = true;
handlePaint (context);
insideDrawRect = false;
#else
Image temp (getComponent()->isOpaque() ? Image::RGB : Image::ARGB,
(int) (r.size.width + 0.5f),
(int) (r.size.height + 0.5f),
! getComponent()->isOpaque());
insideDrawRect = true;
handlePaint (context);
insideDrawRect = false;
}
else
#endif
{
Image temp (getComponent()->isOpaque() ? Image::RGB : Image::ARGB,
(int) (r.size.width + 0.5f),
(int) (r.size.height + 0.5f),
! getComponent()->isOpaque());

LowLevelGraphicsSoftwareRenderer context (temp);
context.setOrigin (-roundFloatToInt (r.origin.x),
-roundFloatToInt ([view frame].size.height - (r.origin.y + r.size.height)));
LowLevelGraphicsSoftwareRenderer context (temp);
context.setOrigin (-roundFloatToInt (r.origin.x),
-roundFloatToInt ([view frame].size.height - (r.origin.y + r.size.height)));

const NSRect* rects = 0;
NSInteger numRects = 0;
[view getRectsBeingDrawn: &rects count: &numRects];
const NSRect* rects = 0;
NSInteger numRects = 0;
[view getRectsBeingDrawn: &rects count: &numRects];

RectangleList clip;
for (int i = 0; i < numRects; ++i)
{
clip.addWithoutMerging (Rectangle (roundFloatToInt (rects[i].origin.x),
roundFloatToInt ([view frame].size.height - (rects[i].origin.y + rects[i].size.height)),
roundFloatToInt (rects[i].size.width),
roundFloatToInt (rects[i].size.height)));
RectangleList clip;
for (int i = 0; i < numRects; ++i)
{
clip.addWithoutMerging (Rectangle (roundFloatToInt (rects[i].origin.x),
roundFloatToInt ([view frame].size.height - (rects[i].origin.y + rects[i].size.height)),
roundFloatToInt (rects[i].size.width),
roundFloatToInt (rects[i].size.height)));
}

if (context.clipToRectangleList (clip))
{
insideDrawRect = true;
handlePaint (context);
insideDrawRect = false;

CGColorSpaceRef colourSpace = CGColorSpaceCreateDeviceRGB();
CGImageRef image = CoreGraphicsImage::createImage (temp, false, colourSpace);
CGColorSpaceRelease (colourSpace);
CGContextDrawImage (cg, CGRectMake (r.origin.x, r.origin.y, temp.getWidth(), temp.getHeight()), image);
CGImageRelease (image);
}
}
}

if (context.clipToRectangleList (clip))
{
insideDrawRect = true;
handlePaint (context);
insideDrawRect = false;
const StringArray NSViewComponentPeer::getAvailableRenderingEngines() throw()
{
StringArray s;
s.add ("Software Renderer");

CGColorSpaceRef colourSpace = CGColorSpaceCreateDeviceRGB();
CGImageRef image = CoreGraphicsImage::createImage (temp, false, colourSpace);
CGColorSpaceRelease (colourSpace);
CGContextDrawImage (cg, CGRectMake (r.origin.x, r.origin.y, temp.getWidth(), temp.getHeight()), image);
CGImageRelease (image);
#if USE_COREGRAPHICS_RENDERING
s.add ("CoreGraphics Renderer");
#endif

return s;
}

int NSViewComponentPeer::getCurrentRenderingEngine() throw()
{
return usingCoreGraphics ? 1 : 0;
}

void NSViewComponentPeer::setCurrentRenderingEngine (int index) throw()
{
#if USE_COREGRAPHICS_RENDERING
if (usingCoreGraphics != (index > 0))
{
usingCoreGraphics = index > 0;
[view setNeedsDisplay: true];
}
#endif
}
@@ -269089,6 +269182,28 @@ END_JUCE_NAMESPACE

if ([[item representedObject] isKindOfClass: [NSArray class]])
{
// If the menu is being triggered by a keypress, the OS will have picked it up before we had a chance to offer it to
// our own components, which may have wanted to intercept it. So, rather than dispatching directly, we'll feed it back
// into the focused component and let it trigger the menu item indirectly.
NSEvent* e = [NSApp currentEvent];
if ([e type] == NSKeyDown || [e type] == NSKeyUp)
{
if (JUCE_NAMESPACE::Component::getCurrentlyFocusedComponent()->isValidComponent())
{
JUCE_NAMESPACE::NSViewComponentPeer* peer = dynamic_cast <JUCE_NAMESPACE::NSViewComponentPeer*> (JUCE_NAMESPACE::Component::getCurrentlyFocusedComponent()->getPeer());

if (peer != 0)
{
if ([e type] == NSKeyDown)
peer->redirectKeyDown (e);
else
peer->redirectKeyUp (e);

return;
}
}
}

NSArray* info = (NSArray*) [item representedObject];

owner->invoke ([item tag],


+ 25
- 3
juce_amalgamated.h View File

@@ -19894,17 +19894,36 @@ public:
*/
void setTiledImage (const Image& image, const AffineTransform& transform) throw();

/** Returns the solid colour being used. */
/** Changes the opacity that should be used.
If the fill is a solid colour, this just changes the opacity of that colour. For
gradients and image tiles, it changes the opacity that will be used for them.
*/
void setOpacity (const float newOpacity) throw();

/** Returns the current opacity to be applied to the colour, gradient, or image.
@see setOpacity
*/
float getOpacity() const throw() { return colour.getFloatAlpha(); }

/** The solid colour being used.

If the fill type is not a solid colour, the alpha channel of this colour indicates
the opacity that should be used for the fill, and the RGB channels are ignored.
*/
Colour colour;

/** Returns the gradient that should be used for filling.
This will be zero if the object is some other type of fill.
If a gradient is active, the overall opacity with which it should be applied
is indicated by the alpha channel of the colour variable.
*/
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.
If an image fill is active, the overall opacity with which it should be applied
is indicated by the alpha channel of the colour variable.
*/
const Image* image;

@@ -21503,6 +21522,10 @@ public:

static void bringModalComponentToFront();

virtual const StringArray getAvailableRenderingEngines() throw();
virtual int getCurrentRenderingEngine() throw();
virtual void setCurrentRenderingEngine (int index) throw();

juce_UseDebuggingNewOperator

protected:
@@ -39807,8 +39830,7 @@ public:
virtual void restoreState() = 0;

virtual void setFill (const FillType& fillType) = 0;

virtual void setOpacity (float opacity) = 0;
virtual void setOpacity (float newOpacity) = 0;
virtual void setInterpolationQuality (Graphics::ResamplingQuality quality) = 0;

virtual void fillRect (const Rectangle& r, const bool replaceExistingContents) = 0;


+ 16
- 0
src/gui/components/windows/juce_ComponentPeer.cpp View File

@@ -776,5 +776,21 @@ void ComponentPeer::addMaskedRegion (int x, int y, int w, int h) throw()
maskedRegion.add (x, y, w, h);
}
//==============================================================================
const StringArray ComponentPeer::getAvailableRenderingEngines() throw()
{
StringArray s;
s.add ("Software Renderer");
return s;
}
int ComponentPeer::getCurrentRenderingEngine() throw()
{
return 0;
}
void ComponentPeer::setCurrentRenderingEngine (int /*index*/) throw()
{
}
END_JUCE_NAMESPACE

+ 5
- 0
src/gui/components/windows/juce_ComponentPeer.h View File

@@ -353,6 +353,11 @@ public:
//==============================================================================
static void bringModalComponentToFront();
//==============================================================================
virtual const StringArray getAvailableRenderingEngines() throw();
virtual int getCurrentRenderingEngine() throw();
virtual void setCurrentRenderingEngine (int index) throw();
//==============================================================================
juce_UseDebuggingNewOperator


+ 7
- 0
src/gui/graphics/contexts/juce_FillType.cpp View File

@@ -28,6 +28,7 @@
BEGIN_JUCE_NAMESPACE
#include "juce_FillType.h"
#include "../colour/juce_Colours.h"
//==============================================================================
@@ -95,6 +96,7 @@ void FillType::setGradient (const ColourGradient& newGradient) throw()
{
image = 0;
gradient = new ColourGradient (newGradient);
colour = Colours::black;
}
}
@@ -103,7 +105,12 @@ void FillType::setTiledImage (const Image& image_, const AffineTransform& transf
deleteAndZero (gradient);
image = &image_;
transform = transform_;
colour = Colours::black;
}
void FillType::setOpacity (const float newOpacity) throw()
{
colour = colour.withAlpha (newOpacity);
}
END_JUCE_NAMESPACE

+ 20
- 1
src/gui/graphics/contexts/juce_FillType.h View File

@@ -91,17 +91,36 @@ public:
*/
void setTiledImage (const Image& image, const AffineTransform& transform) throw();
/** Returns the solid colour being used. */
/** Changes the opacity that should be used.
If the fill is a solid colour, this just changes the opacity of that colour. For
gradients and image tiles, it changes the opacity that will be used for them.
*/
void setOpacity (const float newOpacity) throw();
/** Returns the current opacity to be applied to the colour, gradient, or image.
@see setOpacity
*/
float getOpacity() const throw() { return colour.getFloatAlpha(); }
/** The solid colour being used.
If the fill type is not a solid colour, the alpha channel of this colour indicates
the opacity that should be used for the fill, and the RGB channels are ignored.
*/
Colour colour;
/** Returns the gradient that should be used for filling.
This will be zero if the object is some other type of fill.
If a gradient is active, the overall opacity with which it should be applied
is indicated by the alpha channel of the colour variable.
*/
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.
If an image fill is active, the overall opacity with which it should be applied
is indicated by the alpha channel of the colour variable.
*/
const Image* image;


+ 1
- 2
src/gui/graphics/contexts/juce_LowLevelGraphicsContext.h View File

@@ -81,8 +81,7 @@ public:
//==============================================================================
virtual void setFill (const FillType& fillType) = 0;
virtual void setOpacity (float opacity) = 0;
virtual void setOpacity (float newOpacity) = 0;
virtual void setInterpolationQuality (Graphics::ResamplingQuality quality) = 0;
//==============================================================================


+ 16
- 9
src/gui/graphics/contexts/juce_LowLevelGraphicsSoftwareRenderer.cpp View File

@@ -949,6 +949,7 @@ public:
jassert (! replaceContents); // that option is just for solid colours
ColourGradient g2 (*(fillType.gradient));
g2.multiplyOpacity (fillType.getOpacity());
AffineTransform transform (fillType.transform.translated ((float) xOffset, (float) yOffset));
const bool isIdentity = transform.isOnlyTranslation();
@@ -1365,9 +1366,9 @@ void LowLevelGraphicsSoftwareRenderer::setFill (const FillType& fillType)
currentState->fillType = fillType;
}
void LowLevelGraphicsSoftwareRenderer::setOpacity (float opacity)
void LowLevelGraphicsSoftwareRenderer::setOpacity (float newOpacity)
{
currentState->fillType.colour = currentState->fillType.colour.withAlpha (opacity);
currentState->fillType.setOpacity (newOpacity);
}
void LowLevelGraphicsSoftwareRenderer::setInterpolationQuality (Graphics::ResamplingQuality quality)
@@ -1414,15 +1415,21 @@ void LowLevelGraphicsSoftwareRenderer::drawLine (double x1, double y1, double x2
void LowLevelGraphicsSoftwareRenderer::drawVerticalLine (const int x, double top, double bottom)
{
EdgeTable et ((float) (x + currentState->xOffset), (float) (top + currentState->yOffset), 1.0f, (float) (bottom - top));
currentState->fillEdgeTable (image, et);
if (bottom > top)
{
EdgeTable et ((float) (x + currentState->xOffset), (float) (top + currentState->yOffset), 1.0f, (float) (bottom - top));
currentState->fillEdgeTable (image, et);
}
}
void LowLevelGraphicsSoftwareRenderer::drawHorizontalLine (const int y, double left, double right)
{
EdgeTable et ((float) (left + currentState->xOffset), (float) (y + currentState->yOffset),
(float) (right - left), 1.0f);
currentState->fillEdgeTable (image, et);
if (right > left)
{
EdgeTable et ((float) (left + currentState->xOffset), (float) (y + currentState->yOffset),
(float) (right - left), 1.0f);
currentState->fillEdgeTable (image, et);
}
}
//==============================================================================
@@ -1519,7 +1526,7 @@ public:
const AffineTransform transform (AffineTransform::scale (fontHeight * font.getHorizontalScale(), fontHeight));
float px, py, pw, ph;
glyphPath.getBoundsTransformed (transform, px, py, pw, ph);
glyphPath.getBoundsTransformed (transform.translated (0.0f, -0.5f), px, py, pw, ph);
Rectangle clip ((int) floorf (px), (int) floorf (py),
roundFloatToInt (pw) + 2, roundFloatToInt (ph) + 2);
@@ -1573,7 +1580,7 @@ void LowLevelGraphicsSoftwareRenderer::drawGlyph (int glyphNumber, const AffineT
{
GlyphCache::getInstance()->drawGlyph (*currentState, image, f, glyphNumber,
transform.getTranslationX() + (float) currentState->xOffset,
roundFloatToInt (transform.getTranslationY() + (float) currentState->yOffset));
transform.getTranslationY() + (float) currentState->yOffset);
}
else
{


+ 5
- 1
src/native/mac/juce_iphone_UIViewComponentPeer.mm View File

@@ -186,7 +186,11 @@ static int getModifierForButtonNumber (const int num) throw()
: (num == 2 ? ModifierKeys::middleButtonModifier : 0));
}
static int64 getMouseTime (UIEvent* e) { return (int64) ([e timestamp] * 1000.0); }
static int64 getMouseTime (UIEvent* e) throw()
{
return (Time::currentTimeMillis() - Time::getMillisecondCounter())
+ (int64) ([e timestamp] * 1000.0);
}
int juce_lastMouseX = 0, juce_lastMouseY = 0;


+ 11
- 11
src/native/mac/juce_mac_CoreGraphicsContext.mm View File

@@ -279,9 +279,9 @@ public:
}
}
void setOpacity (float opacity)
void setOpacity (float newOpacity)
{
state->fillType.colour = state->fillType.colour.withAlpha (opacity);
state->fillType.setOpacity (newOpacity);
setFill (state->fillType);
}
@@ -380,7 +380,7 @@ public:
CGImageRelease (fullImage);
CGContextSaveGState (context);
CGContextSetAlpha (context, state->fillType.colour.getFloatAlpha());
CGContextSetAlpha (context, state->fillType.getOpacity());
flip();
applyTransform (AffineTransform::scale (1.0f, -1.0f).translated (0, sourceImage.getHeight()).followedBy (transform));
@@ -566,26 +566,27 @@ private:
outData[3] = colour.getAlpha() / 255.0f;
}
CGShadingRef createGradient (const AffineTransform& transform, const ColourGradient* const gradient) throw()
CGShadingRef createGradient (const AffineTransform& transform, ColourGradient gradient) throw()
{
// gradient.multiplyOpacity (state->fillType.getOpacity());
delete gradientLookupTable;
gradientLookupTable = gradient->createLookupTable (transform, numGradientLookupEntries);
gradientLookupTable = gradient.createLookupTable (transform, numGradientLookupEntries);
--numGradientLookupEntries;
CGShadingRef result = 0;
CGFunctionRef function = CGFunctionCreate ((void*) this, 1, 0, 4, 0, &gradientCallbacks);
CGPoint p1 (CGPointMake (gradient->x1, gradient->y1));
CGPoint p1 (CGPointMake (gradient.x1, gradient.y1));
if (gradient->isRadial)
if (gradient.isRadial)
{
result = CGShadingCreateRadial (rgbColourSpace, p1, 0,
p1, hypotf (gradient->x1 - gradient->x2, gradient->y1 - gradient->y2),
p1, hypotf (gradient.x1 - gradient.x2, gradient.y1 - gradient.y2),
function, true, true);
}
else
{
result = CGShadingCreateAxial (rgbColourSpace, p1,
CGPointMake (gradient->x2, gradient->y2),
CGPointMake (gradient.x2, gradient.y2),
function, true, true);
}
@@ -598,10 +599,9 @@ private:
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.transform, state->fillType.gradient);
CGShadingRef shading = createGradient (state->fillType.transform, *(state->fillType.gradient));
CGContextDrawShading (context, shading);
CGShadingRelease (shading);
}


+ 22
- 0
src/native/mac/juce_mac_MainMenu.mm View File

@@ -361,6 +361,28 @@ END_JUCE_NAMESPACE
if ([[item representedObject] isKindOfClass: [NSArray class]])
{
// If the menu is being triggered by a keypress, the OS will have picked it up before we had a chance to offer it to
// our own components, which may have wanted to intercept it. So, rather than dispatching directly, we'll feed it back
// into the focused component and let it trigger the menu item indirectly.
NSEvent* e = [NSApp currentEvent];
if ([e type] == NSKeyDown || [e type] == NSKeyUp)
{
if (JUCE_NAMESPACE::Component::getCurrentlyFocusedComponent()->isValidComponent())
{
JUCE_NAMESPACE::NSViewComponentPeer* peer = dynamic_cast <JUCE_NAMESPACE::NSViewComponentPeer*> (JUCE_NAMESPACE::Component::getCurrentlyFocusedComponent()->getPeer());
if (peer != 0)
{
if ([e type] == NSKeyDown)
peer->redirectKeyDown (e);
else
peer->redirectKeyUp (e);
return;
}
}
}
NSArray* info = (NSArray*) [item representedObject];
owner->invoke ([item tag],


+ 80
- 35
src/native/mac/juce_mac_NSViewComponentPeer.mm View File

@@ -149,6 +149,9 @@ public:
void toFront (bool makeActiveWindow);
void toBehind (ComponentPeer* other);
void setIcon (const Image& newIcon);
const StringArray getAvailableRenderingEngines() throw();
int getCurrentRenderingEngine() throw();
void setCurrentRenderingEngine (int index) throw();
/* When you use multiple DLLs which share similarly-named obj-c classes - like
for example having more than one juce plugin loaded into a host, then when a
@@ -207,7 +210,7 @@ public:
NSWindow* window;
JuceNSView* view;
bool isSharedWindow, fullScreen, insideDrawRect;
bool isSharedWindow, fullScreen, insideDrawRect, usingCoreGraphics;
};
//==============================================================================
@@ -634,7 +637,11 @@ void ModifierKeys::updateCurrentModifiers() throw()
currentModifierFlags = currentModifiers;
}
static int64 getMouseTime (NSEvent* e) { return (int64) [e timestamp] * 1000.0; }
static int64 getMouseTime (NSEvent* e) throw()
{
return (Time::currentTimeMillis() - Time::getMillisecondCounter())
+ (int64) ([e timestamp] * 1000.0);
}
static void getMousePos (NSEvent* e, NSView* view, int& x, int& y)
{
@@ -659,7 +666,12 @@ NSViewComponentPeer::NSViewComponentPeer (Component* const component,
view (0),
isSharedWindow (viewToAttachTo != 0),
fullScreen (false),
insideDrawRect (false)
insideDrawRect (false),
#if USE_COREGRAPHICS_RENDERING
usingCoreGraphics (true)
#else
usingCoreGraphics (false)
#endif
{
NSRect r;
r.origin.x = 0;
@@ -1324,45 +1336,78 @@ void NSViewComponentPeer::drawRect (NSRect r)
CGContextClearRect (cg, CGContextGetClipBoundingBox (cg));
#if USE_COREGRAPHICS_RENDERING
CoreGraphicsContext context (cg, [view frame].size.height);
if (usingCoreGraphics)
{
CoreGraphicsContext context (cg, [view frame].size.height);
insideDrawRect = true;
handlePaint (context);
insideDrawRect = false;
#else
Image temp (getComponent()->isOpaque() ? Image::RGB : Image::ARGB,
(int) (r.size.width + 0.5f),
(int) (r.size.height + 0.5f),
! getComponent()->isOpaque());
insideDrawRect = true;
handlePaint (context);
insideDrawRect = false;
}
else
#endif
{
Image temp (getComponent()->isOpaque() ? Image::RGB : Image::ARGB,
(int) (r.size.width + 0.5f),
(int) (r.size.height + 0.5f),
! getComponent()->isOpaque());
LowLevelGraphicsSoftwareRenderer context (temp);
context.setOrigin (-roundFloatToInt (r.origin.x),
-roundFloatToInt ([view frame].size.height - (r.origin.y + r.size.height)));
LowLevelGraphicsSoftwareRenderer context (temp);
context.setOrigin (-roundFloatToInt (r.origin.x),
-roundFloatToInt ([view frame].size.height - (r.origin.y + r.size.height)));
const NSRect* rects = 0;
NSInteger numRects = 0;
[view getRectsBeingDrawn: &rects count: &numRects];
const NSRect* rects = 0;
NSInteger numRects = 0;
[view getRectsBeingDrawn: &rects count: &numRects];
RectangleList clip;
for (int i = 0; i < numRects; ++i)
{
clip.addWithoutMerging (Rectangle (roundFloatToInt (rects[i].origin.x),
roundFloatToInt ([view frame].size.height - (rects[i].origin.y + rects[i].size.height)),
roundFloatToInt (rects[i].size.width),
roundFloatToInt (rects[i].size.height)));
RectangleList clip;
for (int i = 0; i < numRects; ++i)
{
clip.addWithoutMerging (Rectangle (roundFloatToInt (rects[i].origin.x),
roundFloatToInt ([view frame].size.height - (rects[i].origin.y + rects[i].size.height)),
roundFloatToInt (rects[i].size.width),
roundFloatToInt (rects[i].size.height)));
}
if (context.clipToRectangleList (clip))
{
insideDrawRect = true;
handlePaint (context);
insideDrawRect = false;
CGColorSpaceRef colourSpace = CGColorSpaceCreateDeviceRGB();
CGImageRef image = CoreGraphicsImage::createImage (temp, false, colourSpace);
CGColorSpaceRelease (colourSpace);
CGContextDrawImage (cg, CGRectMake (r.origin.x, r.origin.y, temp.getWidth(), temp.getHeight()), image);
CGImageRelease (image);
}
}
}
if (context.clipToRectangleList (clip))
{
insideDrawRect = true;
handlePaint (context);
insideDrawRect = false;
const StringArray NSViewComponentPeer::getAvailableRenderingEngines() throw()
{
StringArray s;
s.add ("Software Renderer");
#if USE_COREGRAPHICS_RENDERING
s.add ("CoreGraphics Renderer");
#endif
return s;
}
CGColorSpaceRef colourSpace = CGColorSpaceCreateDeviceRGB();
CGImageRef image = CoreGraphicsImage::createImage (temp, false, colourSpace);
CGColorSpaceRelease (colourSpace);
CGContextDrawImage (cg, CGRectMake (r.origin.x, r.origin.y, temp.getWidth(), temp.getHeight()), image);
CGImageRelease (image);
int NSViewComponentPeer::getCurrentRenderingEngine() throw()
{
return usingCoreGraphics ? 1 : 0;
}
void NSViewComponentPeer::setCurrentRenderingEngine (int index) throw()
{
#if USE_COREGRAPHICS_RENDERING
if (usingCoreGraphics != (index > 0))
{
usingCoreGraphics = index > 0;
[view setNeedsDisplay: true];
}
#endif
}


+ 18
- 4
src/text/juce_XmlElement.cpp View File

@@ -430,13 +430,27 @@ bool XmlElement::writeToFile (const File& f,
<< dtd << "\r\n";
writeElementAsText (*out, 0, lineWrapLength);
delete out;
if (tempFile.moveFileTo (f))
return true;
if (! tempFile.exists())
return false;
tempFile.deleteFile();
int i;
for (i = 5; --i >= 0;)
{
if (tempFile.moveFileTo (f))
return true;
Thread::sleep (100);
}
for (i = 5; --i >= 0;)
{
if (tempFile.deleteFile())
break;
Thread::sleep (100);
}
}
}


Loading…
Cancel
Save