@@ -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 "$<" | |||
@@ -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; | |||
}; | |||
@@ -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 | |||
@@ -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: | |||
@@ -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(); | |||
@@ -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], | |||
@@ -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; | |||
@@ -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 |
@@ -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 | |||
@@ -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 |
@@ -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; | |||
@@ -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; | |||
//============================================================================== | |||
@@ -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 | |||
{ | |||
@@ -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; | |||
@@ -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); | |||
} | |||
@@ -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], | |||
@@ -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 | |||
} | |||
@@ -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); | |||
} | |||
} | |||
} | |||