diff --git a/build/macosx/Juce.xcodeproj/project.pbxproj b/build/macosx/Juce.xcodeproj/project.pbxproj
index 7458987b73..5a637c23e5 100644
--- a/build/macosx/Juce.xcodeproj/project.pbxproj
+++ b/build/macosx/Juce.xcodeproj/project.pbxproj
@@ -7,6 +7,13 @@
objects = {
/* Begin PBXBuildFile section */
+ 840F1DA110AD674C002A03A6 /* juce_CodeDocument.cpp in Sources */ = {isa = PBXBuildFile; fileRef = 84AB91F510A078190048FC39 /* juce_CodeDocument.cpp */; };
+ 840F1DA210AD674D002A03A6 /* juce_CodeDocument.h in Headers */ = {isa = PBXBuildFile; fileRef = 84AB91F610A078190048FC39 /* juce_CodeDocument.h */; };
+ 840F1DA310AD674D002A03A6 /* juce_CodeEditorComponent.cpp in Sources */ = {isa = PBXBuildFile; fileRef = 84AB91F710A078190048FC39 /* juce_CodeEditorComponent.cpp */; };
+ 840F1DA410AD674E002A03A6 /* juce_CodeEditorComponent.h in Headers */ = {isa = PBXBuildFile; fileRef = 84AB91F810A078190048FC39 /* juce_CodeEditorComponent.h */; };
+ 840F1DA510AD674F002A03A6 /* juce_CodeTokeniser.h in Headers */ = {isa = PBXBuildFile; fileRef = 84AB927110A082E30048FC39 /* juce_CodeTokeniser.h */; };
+ 840F1DA610AD674F002A03A6 /* juce_CPlusPlusCodeTokeniser.cpp in Sources */ = {isa = PBXBuildFile; fileRef = 84AB91F910A078190048FC39 /* juce_CPlusPlusCodeTokeniser.cpp */; };
+ 840F1DA710AD6750002A03A6 /* juce_CPlusPlusCodeTokeniser.h in Headers */ = {isa = PBXBuildFile; fileRef = 84AB91FA10A078190048FC39 /* juce_CPlusPlusCodeTokeniser.h */; };
840F80BC092B399D005E7B4E /* juce.h in Headers */ = {isa = PBXBuildFile; fileRef = 840F80BB092B399D005E7B4E /* juce.h */; };
84816E5710809D07008FEC33 /* juce_iphone_Audio.cpp in Sources */ = {isa = PBXBuildFile; fileRef = 84816E5110809D07008FEC33 /* juce_iphone_Audio.cpp */; };
84816E5910809D07008FEC33 /* juce_iphone_MessageManager.mm in Sources */ = {isa = PBXBuildFile; fileRef = 84816E5310809D07008FEC33 /* juce_iphone_MessageManager.mm */; };
@@ -3217,6 +3224,10 @@
84816F9510809DCB008FEC33 /* juce_XmlDocument.h in Headers */,
84816F9610809DCB008FEC33 /* juce_XmlElement.h in Headers */,
84816F9710809DCB008FEC33 /* juce_ZipFile.h in Headers */,
+ 840F1DA210AD674D002A03A6 /* juce_CodeDocument.h in Headers */,
+ 840F1DA410AD674E002A03A6 /* juce_CodeEditorComponent.h in Headers */,
+ 840F1DA510AD674F002A03A6 /* juce_CodeTokeniser.h in Headers */,
+ 840F1DA710AD6750002A03A6 /* juce_CPlusPlusCodeTokeniser.h in Headers */,
);
runOnlyForDeploymentPostprocessing = 0;
};
@@ -3888,6 +3899,9 @@
848170B010809E00008FEC33 /* juce_XmlDocument.cpp in Sources */,
848170B110809E00008FEC33 /* juce_XmlElement.cpp in Sources */,
848170B210809E00008FEC33 /* juce_ZipFile.cpp in Sources */,
+ 840F1DA110AD674C002A03A6 /* juce_CodeDocument.cpp in Sources */,
+ 840F1DA310AD674D002A03A6 /* juce_CodeEditorComponent.cpp in Sources */,
+ 840F1DA610AD674F002A03A6 /* juce_CPlusPlusCodeTokeniser.cpp in Sources */,
);
runOnlyForDeploymentPostprocessing = 0;
};
@@ -4219,7 +4233,7 @@
GCC_WARN_NON_VIRTUAL_DESTRUCTOR = YES;
GCC_WARN_TYPECHECK_CALLS_TO_PRINTF = YES;
MACOSX_DEPLOYMENT_TARGET = 10.4;
- MACOSX_DEPLOYMENT_TARGET_ppc = 10.3;
+ MACOSX_DEPLOYMENT_TARGET_ppc = 10.4;
};
name = Debug;
};
diff --git a/extras/juce demo/build/iphone/JuceDemo-Info.plist b/extras/juce demo/build/iphone/JuceDemo-Info.plist
new file mode 100644
index 0000000000..c6390a2a1b
--- /dev/null
+++ b/extras/juce demo/build/iphone/JuceDemo-Info.plist
@@ -0,0 +1,28 @@
+
+
+
+
+ CFBundleDevelopmentRegion
+ English
+ CFBundleDisplayName
+ ${PRODUCT_NAME}
+ CFBundleExecutable
+ ${EXECUTABLE_NAME}
+ CFBundleIconFile
+
+ CFBundleIdentifier
+ com.synchromation.rawmaterial
+ CFBundleInfoDictionaryVersion
+ 6.0
+ CFBundleName
+ ${PRODUCT_NAME}
+ CFBundlePackageType
+ APPL
+ CFBundleSignature
+ ????
+ CFBundleVersion
+ 1.0
+ LSRequiresIPhoneOS
+
+
+
diff --git a/extras/juce demo/build/iphone/JuceDemo.xcodeproj/project.pbxproj b/extras/juce demo/build/iphone/JuceDemo.xcodeproj/project.pbxproj
new file mode 100644
index 0000000000..4a50b0a51a
--- /dev/null
+++ b/extras/juce demo/build/iphone/JuceDemo.xcodeproj/project.pbxproj
@@ -0,0 +1,388 @@
+// !$*UTF8*$!
+{
+ archiveVersion = 1;
+ classes = {
+ };
+ objectVersion = 45;
+ objects = {
+
+/* Begin PBXBuildFile section */
+ 1D60589F0D05DD5A006BFB54 /* Foundation.framework in Frameworks */ = {isa = PBXBuildFile; fileRef = 1D30AB110D05D00D00671497 /* Foundation.framework */; };
+ 1DF5F4E00D08C38300B7A737 /* UIKit.framework in Frameworks */ = {isa = PBXBuildFile; fileRef = 1DF5F4DF0D08C38300B7A737 /* UIKit.framework */; };
+ 288765FD0DF74451002DB57D /* CoreGraphics.framework in Frameworks */ = {isa = PBXBuildFile; fileRef = 288765FC0DF74451002DB57D /* CoreGraphics.framework */; };
+ 840F1D8510AD66DE002A03A6 /* AudioToolbox.framework in Frameworks */ = {isa = PBXBuildFile; fileRef = 840F1D8410AD66DE002A03A6 /* AudioToolbox.framework */; };
+ 840F1D9C10AD6701002A03A6 /* CodeEditorDemo.cpp in Sources */ = {isa = PBXBuildFile; fileRef = 840F1D9B10AD6701002A03A6 /* CodeEditorDemo.cpp */; };
+ 848167F9107E4E5D008FEC33 /* ApplicationStartup.cpp in Sources */ = {isa = PBXBuildFile; fileRef = 848167F8107E4E5D008FEC33 /* ApplicationStartup.cpp */; };
+ 848168AB107E7DA6008FEC33 /* BinaryData.cpp in Sources */ = {isa = PBXBuildFile; fileRef = 8481688D107E7DA6008FEC33 /* BinaryData.cpp */; };
+ 848168AC107E7DA6008FEC33 /* CameraDemo.cpp in Sources */ = {isa = PBXBuildFile; fileRef = 84816890107E7DA6008FEC33 /* CameraDemo.cpp */; };
+ 848168AD107E7DA6008FEC33 /* DragAndDropDemo.cpp in Sources */ = {isa = PBXBuildFile; fileRef = 84816891107E7DA6008FEC33 /* DragAndDropDemo.cpp */; };
+ 848168AE107E7DA6008FEC33 /* InterprocessCommsDemo.cpp in Sources */ = {isa = PBXBuildFile; fileRef = 84816892107E7DA6008FEC33 /* InterprocessCommsDemo.cpp */; };
+ 848168AF107E7DA6008FEC33 /* OpenGLDemo.cpp in Sources */ = {isa = PBXBuildFile; fileRef = 84816893107E7DA6008FEC33 /* OpenGLDemo.cpp */; };
+ 848168B0107E7DA6008FEC33 /* PathsAndTransformsDemo.cpp in Sources */ = {isa = PBXBuildFile; fileRef = 84816894107E7DA6008FEC33 /* PathsAndTransformsDemo.cpp */; };
+ 848168B1107E7DA6008FEC33 /* QuickTimeDemo.cpp in Sources */ = {isa = PBXBuildFile; fileRef = 84816895107E7DA6008FEC33 /* QuickTimeDemo.cpp */; };
+ 848168B2107E7DA6008FEC33 /* TableDemo.cpp in Sources */ = {isa = PBXBuildFile; fileRef = 84816896107E7DA6008FEC33 /* TableDemo.cpp */; };
+ 848168B3107E7DA6008FEC33 /* ThreadingDemo.cpp in Sources */ = {isa = PBXBuildFile; fileRef = 84816897107E7DA6008FEC33 /* ThreadingDemo.cpp */; };
+ 848168B4107E7DA6008FEC33 /* AudioDemoTabComponent.cpp in Sources */ = {isa = PBXBuildFile; fileRef = 84816898107E7DA6008FEC33 /* AudioDemoTabComponent.cpp */; };
+ 848168B5107E7DA6008FEC33 /* WebBrowserDemo.cpp in Sources */ = {isa = PBXBuildFile; fileRef = 84816899107E7DA6008FEC33 /* WebBrowserDemo.cpp */; };
+ 848168B6107E7DA6008FEC33 /* WidgetsDemo.cpp in Sources */ = {isa = PBXBuildFile; fileRef = 8481689A107E7DA6008FEC33 /* WidgetsDemo.cpp */; };
+ 848168B7107E7DA6008FEC33 /* AudioDemoSetupPage.cpp in Sources */ = {isa = PBXBuildFile; fileRef = 8481689F107E7DA6008FEC33 /* AudioDemoSetupPage.cpp */; };
+ 848168B8107E7DA6008FEC33 /* AudioDemoPlaybackPage.cpp in Sources */ = {isa = PBXBuildFile; fileRef = 848168A0107E7DA6008FEC33 /* AudioDemoPlaybackPage.cpp */; };
+ 848168B9107E7DA6008FEC33 /* AudioDemoSynthPage.cpp in Sources */ = {isa = PBXBuildFile; fileRef = 848168A3107E7DA6008FEC33 /* AudioDemoSynthPage.cpp */; };
+ 848168BA107E7DA6008FEC33 /* AudioDemoRecordPage.cpp in Sources */ = {isa = PBXBuildFile; fileRef = 848168A4107E7DA6008FEC33 /* AudioDemoRecordPage.cpp */; };
+ 848168BB107E7DA6008FEC33 /* TreeViewDemo.cpp in Sources */ = {isa = PBXBuildFile; fileRef = 848168A5107E7DA6008FEC33 /* TreeViewDemo.cpp */; };
+ 848168BC107E7DA6008FEC33 /* FontsAndTextDemo.cpp in Sources */ = {isa = PBXBuildFile; fileRef = 848168A6107E7DA6008FEC33 /* FontsAndTextDemo.cpp */; };
+ 848168BD107E7DA6008FEC33 /* AudioDemoLatencyPage.cpp in Sources */ = {isa = PBXBuildFile; fileRef = 848168A7107E7DA6008FEC33 /* AudioDemoLatencyPage.cpp */; };
+ 848168BE107E7DA6008FEC33 /* MainDemoWindow.cpp in Sources */ = {isa = PBXBuildFile; fileRef = 848168A9107E7DA6008FEC33 /* MainDemoWindow.cpp */; };
+ 8481714D1080CCA5008FEC33 /* libjucedebug.a in Frameworks */ = {isa = PBXBuildFile; fileRef = 848171011080CB2A008FEC33 /* libjucedebug.a */; };
+/* End PBXBuildFile section */
+
+/* Begin PBXContainerItemProxy section */
+ 848171001080CB2A008FEC33 /* PBXContainerItemProxy */ = {
+ isa = PBXContainerItemProxy;
+ containerPortal = 848170FB1080CB2A008FEC33 /* Juce.xcodeproj */;
+ proxyType = 2;
+ remoteGlobalIDString = D2AAC046055464E500DB518D;
+ remoteInfo = Juce;
+ };
+ 848171021080CB2A008FEC33 /* PBXContainerItemProxy */ = {
+ isa = PBXContainerItemProxy;
+ containerPortal = 848170FB1080CB2A008FEC33 /* Juce.xcodeproj */;
+ proxyType = 2;
+ remoteGlobalIDString = 84816E3510809B4F008FEC33;
+ remoteInfo = "Juce (iPhone)";
+ };
+/* End PBXContainerItemProxy section */
+
+/* Begin PBXFileReference section */
+ 1D30AB110D05D00D00671497 /* Foundation.framework */ = {isa = PBXFileReference; lastKnownFileType = wrapper.framework; name = Foundation.framework; path = System/Library/Frameworks/Foundation.framework; sourceTree = SDKROOT; };
+ 1D6058910D05DD3D006BFB54 /* JuceDemo.app */ = {isa = PBXFileReference; explicitFileType = wrapper.application; includeInIndex = 0; path = JuceDemo.app; sourceTree = BUILT_PRODUCTS_DIR; };
+ 1DF5F4DF0D08C38300B7A737 /* UIKit.framework */ = {isa = PBXFileReference; lastKnownFileType = wrapper.framework; name = UIKit.framework; path = System/Library/Frameworks/UIKit.framework; sourceTree = SDKROOT; };
+ 288765FC0DF74451002DB57D /* CoreGraphics.framework */ = {isa = PBXFileReference; lastKnownFileType = wrapper.framework; name = CoreGraphics.framework; path = System/Library/Frameworks/CoreGraphics.framework; sourceTree = SDKROOT; };
+ 840F1D8410AD66DE002A03A6 /* AudioToolbox.framework */ = {isa = PBXFileReference; lastKnownFileType = wrapper.framework; name = AudioToolbox.framework; path = /System/Library/Frameworks/AudioToolbox.framework; sourceTree = ""; };
+ 840F1D9B10AD6701002A03A6 /* CodeEditorDemo.cpp */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.cpp.cpp; path = CodeEditorDemo.cpp; sourceTree = ""; };
+ 848167F8107E4E5D008FEC33 /* ApplicationStartup.cpp */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.cpp.cpp; name = ApplicationStartup.cpp; path = ../../src/ApplicationStartup.cpp; sourceTree = SOURCE_ROOT; };
+ 848167FA107E4E95008FEC33 /* juce_AppConfig.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; name = juce_AppConfig.h; path = ../../src/juce_AppConfig.h; sourceTree = SOURCE_ROOT; };
+ 8481688D107E7DA6008FEC33 /* BinaryData.cpp */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.cpp.cpp; name = BinaryData.cpp; path = ../../src/BinaryData.cpp; sourceTree = SOURCE_ROOT; };
+ 8481688E107E7DA6008FEC33 /* BinaryData.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; name = BinaryData.h; path = ../../src/BinaryData.h; sourceTree = SOURCE_ROOT; };
+ 84816890107E7DA6008FEC33 /* CameraDemo.cpp */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.cpp.cpp; path = CameraDemo.cpp; sourceTree = ""; };
+ 84816891107E7DA6008FEC33 /* DragAndDropDemo.cpp */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.cpp.cpp; path = DragAndDropDemo.cpp; sourceTree = ""; };
+ 84816892107E7DA6008FEC33 /* InterprocessCommsDemo.cpp */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.cpp.cpp; path = InterprocessCommsDemo.cpp; sourceTree = ""; };
+ 84816893107E7DA6008FEC33 /* OpenGLDemo.cpp */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.cpp.cpp; path = OpenGLDemo.cpp; sourceTree = ""; };
+ 84816894107E7DA6008FEC33 /* PathsAndTransformsDemo.cpp */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.cpp.cpp; path = PathsAndTransformsDemo.cpp; sourceTree = ""; };
+ 84816895107E7DA6008FEC33 /* QuickTimeDemo.cpp */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.cpp.cpp; path = QuickTimeDemo.cpp; sourceTree = ""; };
+ 84816896107E7DA6008FEC33 /* TableDemo.cpp */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.cpp.cpp; path = TableDemo.cpp; sourceTree = ""; };
+ 84816897107E7DA6008FEC33 /* ThreadingDemo.cpp */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.cpp.cpp; path = ThreadingDemo.cpp; sourceTree = ""; };
+ 84816898107E7DA6008FEC33 /* AudioDemoTabComponent.cpp */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.cpp.cpp; path = AudioDemoTabComponent.cpp; sourceTree = ""; };
+ 84816899107E7DA6008FEC33 /* WebBrowserDemo.cpp */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.cpp.cpp; path = WebBrowserDemo.cpp; sourceTree = ""; };
+ 8481689A107E7DA6008FEC33 /* WidgetsDemo.cpp */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.cpp.cpp; path = WidgetsDemo.cpp; sourceTree = ""; };
+ 8481689B107E7DA6008FEC33 /* AudioDemoSetupPage.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = AudioDemoSetupPage.h; sourceTree = ""; };
+ 8481689C107E7DA6008FEC33 /* AudioDemoLatencyPage.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = AudioDemoLatencyPage.h; sourceTree = ""; };
+ 8481689D107E7DA6008FEC33 /* AudioDemoRecordPage.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = AudioDemoRecordPage.h; sourceTree = ""; };
+ 8481689E107E7DA6008FEC33 /* AudioDemoPlaybackPage.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = AudioDemoPlaybackPage.h; sourceTree = ""; };
+ 8481689F107E7DA6008FEC33 /* AudioDemoSetupPage.cpp */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.cpp.cpp; path = AudioDemoSetupPage.cpp; sourceTree = ""; };
+ 848168A0107E7DA6008FEC33 /* AudioDemoPlaybackPage.cpp */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.cpp.cpp; path = AudioDemoPlaybackPage.cpp; sourceTree = ""; };
+ 848168A1107E7DA6008FEC33 /* AudioDemoSynthPage.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = AudioDemoSynthPage.h; sourceTree = ""; };
+ 848168A2107E7DA6008FEC33 /* AudioDemoTabComponent.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = AudioDemoTabComponent.h; sourceTree = ""; };
+ 848168A3107E7DA6008FEC33 /* AudioDemoSynthPage.cpp */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.cpp.cpp; path = AudioDemoSynthPage.cpp; sourceTree = ""; };
+ 848168A4107E7DA6008FEC33 /* AudioDemoRecordPage.cpp */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.cpp.cpp; path = AudioDemoRecordPage.cpp; sourceTree = ""; };
+ 848168A5107E7DA6008FEC33 /* TreeViewDemo.cpp */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.cpp.cpp; path = TreeViewDemo.cpp; sourceTree = ""; };
+ 848168A6107E7DA6008FEC33 /* FontsAndTextDemo.cpp */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.cpp.cpp; path = FontsAndTextDemo.cpp; sourceTree = ""; };
+ 848168A7107E7DA6008FEC33 /* AudioDemoLatencyPage.cpp */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.cpp.cpp; path = AudioDemoLatencyPage.cpp; sourceTree = ""; };
+ 848168A8107E7DA6008FEC33 /* jucedemo_headers.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; name = jucedemo_headers.h; path = ../../src/jucedemo_headers.h; sourceTree = SOURCE_ROOT; };
+ 848168A9107E7DA6008FEC33 /* MainDemoWindow.cpp */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.cpp.cpp; name = MainDemoWindow.cpp; path = ../../src/MainDemoWindow.cpp; sourceTree = SOURCE_ROOT; };
+ 848168AA107E7DA6008FEC33 /* MainDemoWindow.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; name = MainDemoWindow.h; path = ../../src/MainDemoWindow.h; sourceTree = SOURCE_ROOT; };
+ 848170FB1080CB2A008FEC33 /* Juce.xcodeproj */ = {isa = PBXFileReference; lastKnownFileType = "wrapper.pb-project"; name = Juce.xcodeproj; path = ../../../../build/macosx/Juce.xcodeproj; sourceTree = SOURCE_ROOT; };
+ 8D1107310486CEB800E47090 /* JuceDemo-Info.plist */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = text.plist.xml; path = "JuceDemo-Info.plist"; plistStructureDefinitionIdentifier = "com.apple.xcode.plist.structure-definition.iphone.info-plist"; sourceTree = ""; };
+/* End PBXFileReference section */
+
+/* Begin PBXFrameworksBuildPhase section */
+ 1D60588F0D05DD3D006BFB54 /* Frameworks */ = {
+ isa = PBXFrameworksBuildPhase;
+ buildActionMask = 2147483647;
+ files = (
+ 8481714D1080CCA5008FEC33 /* libjucedebug.a in Frameworks */,
+ 1D60589F0D05DD5A006BFB54 /* Foundation.framework in Frameworks */,
+ 1DF5F4E00D08C38300B7A737 /* UIKit.framework in Frameworks */,
+ 288765FD0DF74451002DB57D /* CoreGraphics.framework in Frameworks */,
+ 840F1D8510AD66DE002A03A6 /* AudioToolbox.framework in Frameworks */,
+ );
+ runOnlyForDeploymentPostprocessing = 0;
+ };
+/* End PBXFrameworksBuildPhase section */
+
+/* Begin PBXGroup section */
+ 19C28FACFE9D520D11CA2CBB /* Products */ = {
+ isa = PBXGroup;
+ children = (
+ 1D6058910D05DD3D006BFB54 /* JuceDemo.app */,
+ );
+ name = Products;
+ sourceTree = "";
+ };
+ 29B97314FDCFA39411CA2CEA /* CustomTemplate */ = {
+ isa = PBXGroup;
+ children = (
+ 29B97315FDCFA39411CA2CEA /* Other Sources */,
+ 29B97317FDCFA39411CA2CEA /* Resources */,
+ 29B97323FDCFA39411CA2CEA /* Frameworks */,
+ 19C28FACFE9D520D11CA2CBB /* Products */,
+ );
+ name = CustomTemplate;
+ sourceTree = "";
+ };
+ 29B97315FDCFA39411CA2CEA /* Other Sources */ = {
+ isa = PBXGroup;
+ children = (
+ 8481688F107E7DA6008FEC33 /* demos */,
+ 848167F8107E4E5D008FEC33 /* ApplicationStartup.cpp */,
+ 8481688D107E7DA6008FEC33 /* BinaryData.cpp */,
+ 8481688E107E7DA6008FEC33 /* BinaryData.h */,
+ 848168A8107E7DA6008FEC33 /* jucedemo_headers.h */,
+ 848168A9107E7DA6008FEC33 /* MainDemoWindow.cpp */,
+ 848168AA107E7DA6008FEC33 /* MainDemoWindow.h */,
+ 848167FA107E4E95008FEC33 /* juce_AppConfig.h */,
+ );
+ name = "Other Sources";
+ sourceTree = "";
+ };
+ 29B97317FDCFA39411CA2CEA /* Resources */ = {
+ isa = PBXGroup;
+ children = (
+ 8D1107310486CEB800E47090 /* JuceDemo-Info.plist */,
+ );
+ name = Resources;
+ sourceTree = "";
+ };
+ 29B97323FDCFA39411CA2CEA /* Frameworks */ = {
+ isa = PBXGroup;
+ children = (
+ 848170FB1080CB2A008FEC33 /* Juce.xcodeproj */,
+ 1DF5F4DF0D08C38300B7A737 /* UIKit.framework */,
+ 1D30AB110D05D00D00671497 /* Foundation.framework */,
+ 288765FC0DF74451002DB57D /* CoreGraphics.framework */,
+ 840F1D8410AD66DE002A03A6 /* AudioToolbox.framework */,
+ );
+ name = Frameworks;
+ sourceTree = "";
+ };
+ 8481688F107E7DA6008FEC33 /* demos */ = {
+ isa = PBXGroup;
+ children = (
+ 840F1D9B10AD6701002A03A6 /* CodeEditorDemo.cpp */,
+ 84816890107E7DA6008FEC33 /* CameraDemo.cpp */,
+ 84816891107E7DA6008FEC33 /* DragAndDropDemo.cpp */,
+ 84816892107E7DA6008FEC33 /* InterprocessCommsDemo.cpp */,
+ 84816893107E7DA6008FEC33 /* OpenGLDemo.cpp */,
+ 84816894107E7DA6008FEC33 /* PathsAndTransformsDemo.cpp */,
+ 84816895107E7DA6008FEC33 /* QuickTimeDemo.cpp */,
+ 84816896107E7DA6008FEC33 /* TableDemo.cpp */,
+ 84816897107E7DA6008FEC33 /* ThreadingDemo.cpp */,
+ 84816898107E7DA6008FEC33 /* AudioDemoTabComponent.cpp */,
+ 84816899107E7DA6008FEC33 /* WebBrowserDemo.cpp */,
+ 8481689A107E7DA6008FEC33 /* WidgetsDemo.cpp */,
+ 8481689B107E7DA6008FEC33 /* AudioDemoSetupPage.h */,
+ 8481689C107E7DA6008FEC33 /* AudioDemoLatencyPage.h */,
+ 8481689D107E7DA6008FEC33 /* AudioDemoRecordPage.h */,
+ 8481689E107E7DA6008FEC33 /* AudioDemoPlaybackPage.h */,
+ 8481689F107E7DA6008FEC33 /* AudioDemoSetupPage.cpp */,
+ 848168A0107E7DA6008FEC33 /* AudioDemoPlaybackPage.cpp */,
+ 848168A1107E7DA6008FEC33 /* AudioDemoSynthPage.h */,
+ 848168A2107E7DA6008FEC33 /* AudioDemoTabComponent.h */,
+ 848168A3107E7DA6008FEC33 /* AudioDemoSynthPage.cpp */,
+ 848168A4107E7DA6008FEC33 /* AudioDemoRecordPage.cpp */,
+ 848168A5107E7DA6008FEC33 /* TreeViewDemo.cpp */,
+ 848168A6107E7DA6008FEC33 /* FontsAndTextDemo.cpp */,
+ 848168A7107E7DA6008FEC33 /* AudioDemoLatencyPage.cpp */,
+ );
+ name = demos;
+ path = ../../src/demos;
+ sourceTree = SOURCE_ROOT;
+ };
+ 848170FC1080CB2A008FEC33 /* Products */ = {
+ isa = PBXGroup;
+ children = (
+ 848171011080CB2A008FEC33 /* libjucedebug.a */,
+ 848171031080CB2A008FEC33 /* libjucedebug.a */,
+ );
+ name = Products;
+ sourceTree = "";
+ };
+/* End PBXGroup section */
+
+/* Begin PBXNativeTarget section */
+ 1D6058900D05DD3D006BFB54 /* JuceDemo */ = {
+ isa = PBXNativeTarget;
+ buildConfigurationList = 1D6058960D05DD3E006BFB54 /* Build configuration list for PBXNativeTarget "JuceDemo" */;
+ buildPhases = (
+ 1D60588D0D05DD3D006BFB54 /* Resources */,
+ 1D60588E0D05DD3D006BFB54 /* Sources */,
+ 1D60588F0D05DD3D006BFB54 /* Frameworks */,
+ );
+ buildRules = (
+ );
+ dependencies = (
+ );
+ name = JuceDemo;
+ productName = JuceDemo;
+ productReference = 1D6058910D05DD3D006BFB54 /* JuceDemo.app */;
+ productType = "com.apple.product-type.application";
+ };
+/* End PBXNativeTarget section */
+
+/* Begin PBXProject section */
+ 29B97313FDCFA39411CA2CEA /* Project object */ = {
+ isa = PBXProject;
+ buildConfigurationList = C01FCF4E08A954540054247B /* Build configuration list for PBXProject "JuceDemo" */;
+ compatibilityVersion = "Xcode 3.1";
+ hasScannedForEncodings = 1;
+ mainGroup = 29B97314FDCFA39411CA2CEA /* CustomTemplate */;
+ projectDirPath = "";
+ projectReferences = (
+ {
+ ProductGroup = 848170FC1080CB2A008FEC33 /* Products */;
+ ProjectRef = 848170FB1080CB2A008FEC33 /* Juce.xcodeproj */;
+ },
+ );
+ projectRoot = "";
+ targets = (
+ 1D6058900D05DD3D006BFB54 /* JuceDemo */,
+ );
+ };
+/* End PBXProject section */
+
+/* Begin PBXReferenceProxy section */
+ 848171011080CB2A008FEC33 /* libjucedebug.a */ = {
+ isa = PBXReferenceProxy;
+ fileType = archive.ar;
+ path = libjucedebug.a;
+ remoteRef = 848171001080CB2A008FEC33 /* PBXContainerItemProxy */;
+ sourceTree = BUILT_PRODUCTS_DIR;
+ };
+ 848171031080CB2A008FEC33 /* libjucedebug.a */ = {
+ isa = PBXReferenceProxy;
+ fileType = archive.ar;
+ path = libjucedebug.a;
+ remoteRef = 848171021080CB2A008FEC33 /* PBXContainerItemProxy */;
+ sourceTree = BUILT_PRODUCTS_DIR;
+ };
+/* End PBXReferenceProxy section */
+
+/* Begin PBXResourcesBuildPhase section */
+ 1D60588D0D05DD3D006BFB54 /* Resources */ = {
+ isa = PBXResourcesBuildPhase;
+ buildActionMask = 2147483647;
+ files = (
+ );
+ runOnlyForDeploymentPostprocessing = 0;
+ };
+/* End PBXResourcesBuildPhase section */
+
+/* Begin PBXSourcesBuildPhase section */
+ 1D60588E0D05DD3D006BFB54 /* Sources */ = {
+ isa = PBXSourcesBuildPhase;
+ buildActionMask = 2147483647;
+ files = (
+ 848167F9107E4E5D008FEC33 /* ApplicationStartup.cpp in Sources */,
+ 848168AB107E7DA6008FEC33 /* BinaryData.cpp in Sources */,
+ 848168AC107E7DA6008FEC33 /* CameraDemo.cpp in Sources */,
+ 848168AD107E7DA6008FEC33 /* DragAndDropDemo.cpp in Sources */,
+ 848168AE107E7DA6008FEC33 /* InterprocessCommsDemo.cpp in Sources */,
+ 848168AF107E7DA6008FEC33 /* OpenGLDemo.cpp in Sources */,
+ 848168B0107E7DA6008FEC33 /* PathsAndTransformsDemo.cpp in Sources */,
+ 848168B1107E7DA6008FEC33 /* QuickTimeDemo.cpp in Sources */,
+ 848168B2107E7DA6008FEC33 /* TableDemo.cpp in Sources */,
+ 848168B3107E7DA6008FEC33 /* ThreadingDemo.cpp in Sources */,
+ 848168B4107E7DA6008FEC33 /* AudioDemoTabComponent.cpp in Sources */,
+ 848168B5107E7DA6008FEC33 /* WebBrowserDemo.cpp in Sources */,
+ 848168B6107E7DA6008FEC33 /* WidgetsDemo.cpp in Sources */,
+ 848168B7107E7DA6008FEC33 /* AudioDemoSetupPage.cpp in Sources */,
+ 848168B8107E7DA6008FEC33 /* AudioDemoPlaybackPage.cpp in Sources */,
+ 848168B9107E7DA6008FEC33 /* AudioDemoSynthPage.cpp in Sources */,
+ 848168BA107E7DA6008FEC33 /* AudioDemoRecordPage.cpp in Sources */,
+ 848168BB107E7DA6008FEC33 /* TreeViewDemo.cpp in Sources */,
+ 848168BC107E7DA6008FEC33 /* FontsAndTextDemo.cpp in Sources */,
+ 848168BD107E7DA6008FEC33 /* AudioDemoLatencyPage.cpp in Sources */,
+ 848168BE107E7DA6008FEC33 /* MainDemoWindow.cpp in Sources */,
+ 840F1D9C10AD6701002A03A6 /* CodeEditorDemo.cpp in Sources */,
+ );
+ runOnlyForDeploymentPostprocessing = 0;
+ };
+/* End PBXSourcesBuildPhase section */
+
+/* Begin XCBuildConfiguration section */
+ 1D6058940D05DD3E006BFB54 /* Debug */ = {
+ isa = XCBuildConfiguration;
+ buildSettings = {
+ ALWAYS_SEARCH_USER_PATHS = NO;
+ COPY_PHASE_STRIP = NO;
+ GCC_OPTIMIZATION_LEVEL = 0;
+ INFOPLIST_FILE = "JuceDemo-Info.plist";
+ PRODUCT_NAME = JuceDemo;
+ SDKROOT = iphoneos3.0;
+ };
+ name = Debug;
+ };
+ 1D6058950D05DD3E006BFB54 /* Release */ = {
+ isa = XCBuildConfiguration;
+ buildSettings = {
+ ALWAYS_SEARCH_USER_PATHS = NO;
+ COPY_PHASE_STRIP = YES;
+ INFOPLIST_FILE = "JuceDemo-Info.plist";
+ PRODUCT_NAME = JuceDemo;
+ SDKROOT = iphoneos3.0;
+ };
+ name = Release;
+ };
+ C01FCF4F08A954540054247B /* Debug */ = {
+ isa = XCBuildConfiguration;
+ buildSettings = {
+ ARCHS = "$(ARCHS_STANDARD_32_BIT)";
+ CODE_SIGN_IDENTITY = "iPhone Developer";
+ "CODE_SIGN_IDENTITY[sdk=iphoneos*]" = "iPhone Developer";
+ GCC_C_LANGUAGE_STANDARD = c99;
+ GCC_WARN_ABOUT_RETURN_TYPE = YES;
+ GCC_WARN_UNUSED_VARIABLE = YES;
+ PREBINDING = NO;
+ PROVISIONING_PROFILE = "";
+ SDKROOT = iphoneos3.1;
+ };
+ name = Debug;
+ };
+ C01FCF5008A954540054247B /* Release */ = {
+ isa = XCBuildConfiguration;
+ buildSettings = {
+ ARCHS = "$(ARCHS_STANDARD_32_BIT)";
+ "CODE_SIGN_IDENTITY[sdk=iphoneos*]" = "iPhone Developer";
+ GCC_C_LANGUAGE_STANDARD = c99;
+ GCC_WARN_ABOUT_RETURN_TYPE = YES;
+ GCC_WARN_UNUSED_VARIABLE = YES;
+ PREBINDING = NO;
+ SDKROOT = iphoneos3.1;
+ };
+ name = Release;
+ };
+/* End XCBuildConfiguration section */
+
+/* Begin XCConfigurationList section */
+ 1D6058960D05DD3E006BFB54 /* Build configuration list for PBXNativeTarget "JuceDemo" */ = {
+ isa = XCConfigurationList;
+ buildConfigurations = (
+ 1D6058940D05DD3E006BFB54 /* Debug */,
+ 1D6058950D05DD3E006BFB54 /* Release */,
+ );
+ defaultConfigurationIsVisible = 0;
+ defaultConfigurationName = Release;
+ };
+ C01FCF4E08A954540054247B /* Build configuration list for PBXProject "JuceDemo" */ = {
+ isa = XCConfigurationList;
+ buildConfigurations = (
+ C01FCF4F08A954540054247B /* Debug */,
+ C01FCF5008A954540054247B /* Release */,
+ );
+ defaultConfigurationIsVisible = 0;
+ defaultConfigurationName = Release;
+ };
+/* End XCConfigurationList section */
+ };
+ rootObject = 29B97313FDCFA39411CA2CEA /* Project object */;
+}
diff --git a/extras/juce demo/src/demos/AudioDemoRecordPage.cpp b/extras/juce demo/src/demos/AudioDemoRecordPage.cpp
index 522e0eefee..b34b1186e5 100644
--- a/extras/juce demo/src/demos/AudioDemoRecordPage.cpp
+++ b/extras/juce demo/src/demos/AudioDemoRecordPage.cpp
@@ -3,7 +3,7 @@
This is an automatically generated file created by the Jucer!
- Creation date: 19 Sep 2009 12:36:23 pm
+ Creation date: 13 Nov 2009 3:52:50 pm
Be careful when adding custom code to these files, as only the code within
the "//[xyz]" and "//[/xyz]" sections will be retained when the file is loaded
@@ -246,7 +246,7 @@ AudioDemoRecordPage::AudioDemoRecordPage (AudioDeviceManager& deviceManager_)
addAndMakeVisible (liveAudioDisplayComp = new LiveAudioInputDisplayComp());
addAndMakeVisible (explanationLabel = new Label (String::empty,
- T("This page demonstrates how to record a wave file from the live audio input..\n\nPressing record will start recording a file to your desktop.")));
+ T("This page demonstrates how to record a wave file from the live audio input..\n\nPressing record will start recording a file in your \"Documents\" folder.")));
explanationLabel->setFont (Font (15.0000f, Font::plain));
explanationLabel->setJustificationType (Justification::topLeft);
explanationLabel->setEditable (false, false, false);
@@ -304,7 +304,7 @@ void AudioDemoRecordPage::paint (Graphics& g)
void AudioDemoRecordPage::resized()
{
liveAudioDisplayComp->setBounds (8, 8, getWidth() - 16, 64);
- explanationLabel->setBounds (184, 88, getWidth() - 194, 120);
+ explanationLabel->setBounds (160, 88, getWidth() - 169, 216);
recordButton->setBounds (8, 88, 136, 40);
//[UserResized] Add your own custom resize handling here..
//[/UserResized]
@@ -324,7 +324,7 @@ void AudioDemoRecordPage::buttonClicked (Button* buttonThatWasClicked)
}
else
{
- File file (File::getSpecialLocation (File::userDesktopDirectory)
+ File file (File::getSpecialLocation (File::userDocumentsDirectory)
.getNonexistentChildFile ("Juce Demo Audio Recording", ".wav"));
recorder->startRecording (file);
@@ -377,8 +377,8 @@ BEGIN_JUCER_METADATA
virtualName="" explicitFocusOrder="0" pos="8 8 16M 64" class="LiveAudioInputDisplayComp"
params=""/>
& AudioDeviceManager::getAvailableDeviceType
}
AudioIODeviceType* juce_createAudioIODeviceType_CoreAudio();
+AudioIODeviceType* juce_createAudioIODeviceType_iPhoneAudio();
AudioIODeviceType* juce_createAudioIODeviceType_WASAPI();
AudioIODeviceType* juce_createAudioIODeviceType_DirectSound();
AudioIODeviceType* juce_createAudioIODeviceType_ASIO();
@@ -23348,6 +23347,10 @@ void AudioDeviceManager::createAudioDeviceTypes (OwnedArray &
list.add (juce_createAudioIODeviceType_CoreAudio());
#endif
+ #if JUCE_IPHONE
+ list.add (juce_createAudioIODeviceType_iPhoneAudio());
+ #endif
+
#if JUCE_LINUX && JUCE_ALSA
list.add (juce_createAudioIODeviceType_ALSA());
#endif
@@ -29264,10 +29267,6 @@ BEGIN_JUCE_NAMESPACE
#if JUCE_MAC
-#if MACOS_10_3_OR_EARLIER
- #define kAudioUnitType_Generator 'augn'
-#endif
-
// Change this to disable logging of various activities
#ifndef AU_LOGGING
#define AU_LOGGING 1
@@ -39443,9 +39442,9 @@ void Component::paintEntireComponent (Graphics& originalContext)
if (effect_ != 0)
{
- effectImage = new Image (flags.opaqueFlag ? Image::RGB : Image::ARGB,
- getWidth(), getHeight(),
- ! flags.opaqueFlag);
+ effectImage = Image::createNativeImage (flags.opaqueFlag ? Image::RGB : Image::ARGB,
+ getWidth(), getHeight(),
+ ! flags.opaqueFlag);
g = new Graphics (*effectImage);
}
@@ -39466,8 +39465,8 @@ void Component::paintEntireComponent (Graphics& originalContext)
{
if (bufferedImage_ == 0)
{
- bufferedImage_ = new Image (flags.opaqueFlag ? Image::RGB : Image::ARGB,
- getWidth(), getHeight(), ! flags.opaqueFlag);
+ bufferedImage_ = Image::createNativeImage (flags.opaqueFlag ? Image::RGB : Image::ARGB,
+ getWidth(), getHeight(), ! flags.opaqueFlag);
Graphics imG (*bufferedImage_);
paint (imG);
@@ -39547,10 +39546,10 @@ Image* Component::createComponentSnapshot (const Rectangle& areaToGrab,
if (clipImageToComponentBounds)
r = r.getIntersection (Rectangle (0, 0, getWidth(), getHeight()));
- Image* const componentImage = new Image (flags.opaqueFlag ? Image::RGB : Image::ARGB,
- jmax (1, r.getWidth()),
- jmax (1, r.getHeight()),
- true);
+ Image* const componentImage = Image::createNativeImage (flags.opaqueFlag ? Image::RGB : Image::ARGB,
+ jmax (1, r.getWidth()),
+ jmax (1, r.getHeight()),
+ true);
Graphics imageContext (*componentImage);
imageContext.setOrigin (-r.getX(),
@@ -47732,7 +47731,7 @@ void ListBox::repaintRow (const int rowNumber) throw()
Image* ListBox::createSnapshotOfSelectedRows()
{
- Image* snapshot = new Image (Image::ARGB, getWidth(), getHeight(), true);
+ Image* snapshot = Image::createNativeImage (Image::ARGB, getWidth(), getHeight(), true);
Graphics g (*snapshot);
const int firstRow = getRowContainingPosition (0, 0);
@@ -52502,7 +52501,7 @@ void TextEditor::mouseUp (const MouseEvent& e)
if (wasFocused || ! selectAllTextWhenFocused)
{
- if (! (popupMenuEnabled && e.mods.isPopupMenu()))
+ if (e.mouseWasClicked() && ! (popupMenuEnabled && e.mods.isPopupMenu()))
{
moveCaret (getTextIndexAt (e.x, e.y));
}
@@ -64490,14 +64489,15 @@ void LookAndFeel::drawRotarySlider (Graphics& g,
}
if (slider.isEnabled())
- {
g.setColour (slider.findColour (Slider::rotarySliderOutlineColourId));
- Path outlineArc;
- outlineArc.addPieSegment (rx, ry, rw, rw, rotaryStartAngle, rotaryEndAngle, thickness);
- outlineArc.closeSubPath();
+ else
+ g.setColour (Colour (0x80808080));
- g.strokePath (outlineArc, PathStrokeType (slider.isEnabled() ? (isMouseOver ? 2.0f : 1.2f) : 0.3f));
- }
+ Path outlineArc;
+ outlineArc.addPieSegment (rx, ry, rw, rw, rotaryStartAngle, rotaryEndAngle, thickness);
+ outlineArc.closeSubPath();
+
+ g.strokePath (outlineArc, PathStrokeType (slider.isEnabled() ? (isMouseOver ? 2.0f : 1.2f) : 0.3f));
}
else
{
@@ -67880,8 +67880,8 @@ private:
y = jmax (mon.getY(), maxY - heightToUse);
}
- x = jlimit (mon.getX() + 1, mon.getRight() - (widthToUse + 6), x);
- y = jlimit (mon.getY() + 1, mon.getBottom() - (heightToUse + 6), y);
+ x = jmax (mon.getX() + 1, jmin (mon.getRight() - (widthToUse + 6), x));
+ y = jmax (mon.getY() + 1, jmin (mon.getBottom() - (heightToUse + 6), y));
windowPos.setBounds (x, y, widthToUse, heightToUse);
@@ -69239,7 +69239,7 @@ void DragAndDropContainer::startDragging (const String& sourceDescription,
if (im->getFormat() != Image::ARGB)
{
- Image* newIm = new Image (Image::ARGB, im->getWidth(), im->getHeight(), true);
+ Image* newIm = Image::createNativeImage (Image::ARGB, im->getWidth(), im->getHeight(), true);
Graphics g2 (*newIm);
g2.drawImageAt (im, 0, 0);
@@ -72738,7 +72738,7 @@ void DropShadower::updateShadows()
if (bigIm == 0)
{
- bigIm = new Image (Image::ARGB, shadowEdge * 5, shadowEdge * 5, true);
+ bigIm = Image::createNativeImage (Image::ARGB, shadowEdge * 5, shadowEdge * 5, true);
Graphics bigG (*bigIm);
bigG.setColour (Colours::black.withAlpha (alpha));
@@ -78109,6 +78109,16 @@ const Colour Colour::overlaidWith (const Colour& src) const throw()
}
}
+const Colour Colour::interpolatedWith (const Colour& other, float proportionOfOther) const throw()
+{
+ const int amount = jlimit (0, 256, (int) (proportionOfOther * 256.0f));
+
+ return Colour ((uint8) (getRed() + (((other.getRed() - getRed()) * amount) >> 8)),
+ (uint8) (getGreen() + (((other.getGreen() - getGreen()) * amount) >> 8)),
+ (uint8) (getBlue() + (((other.getBlue() - getBlue()) * amount) >> 8)),
+ (uint8) (getAlpha() + (((other.getAlpha() - getAlpha()) * amount) >> 8)));
+}
+
float Colour::getFloatRed() const throw()
{
return getRed() * oneOver255;
@@ -78426,17 +78436,12 @@ const Colour ColourGradient::getColourAtPosition (const float position) const th
return Colour (colours.getUnchecked(i));
const int pos1 = colours.getUnchecked (i);
- PixelARGB pix1 (colours.getUnchecked (i + 1));
- pix1.premultiply();
+ const Colour col1 (colours.getUnchecked (i + 1));
const int pos2 = colours.getUnchecked (i + 2);
- PixelARGB pix2 (colours.getUnchecked (i + 3));
- pix2.premultiply();
+ const Colour col2 (colours.getUnchecked (i + 3));
- pix1.tween (pix2, ((integerPos - pos1) << 8) / (pos2 - pos1));
- pix1.unpremultiply();
-
- return Colour (pix1.getARGB());
+ return col1.interpolatedWith (col2, (integerPos - pos1) / (float) (pos2 - pos1));
}
PixelARGB* ColourGradient::createLookupTable (int& numEntries) const throw()
@@ -78825,23 +78830,25 @@ BEGIN_JUCE_NAMESPACE
const int juce_edgeTableDefaultEdgesPerLine = 32;
-EdgeTable::EdgeTable (const int top_, const int height_,
+EdgeTable::EdgeTable (const Rectangle& bounds_,
const Path& path, const AffineTransform& transform) throw()
- : top (top_),
- height (height_),
+ : bounds (bounds_),
maxEdgesPerLine (juce_edgeTableDefaultEdgesPerLine),
lineStrideElements ((juce_edgeTableDefaultEdgesPerLine << 1) + 1)
{
- table = (int*) juce_malloc (height_ * lineStrideElements * sizeof (int));
+ table = (int*) juce_malloc ((bounds.getHeight() + 1) * lineStrideElements * sizeof (int));
int* t = table;
- for (int i = height_; --i >= 0;)
+ for (int i = bounds.getHeight(); --i >= 0;)
{
*t = 0;
t += lineStrideElements;
}
- const int topLimit = top << 8;
- const int bottomLimit = height << 8;
+ const int topLimit = bounds.getY() << 8;
+ const int heightLimit = bounds.getHeight() << 8;
+ const int leftLimit = bounds.getX() << 8;
+ const int rightLimit = bounds.getRight() << 8;
+
PathFlatteningIterator iter (path, transform);
while (iter.next())
@@ -78854,33 +78861,41 @@ EdgeTable::EdgeTable (const int top_, const int height_,
y1 -= topLimit;
y2 -= topLimit;
- const double startX = 256.0f * iter.x1;
const int startY = y1;
- const double multiplier = (iter.x2 - iter.x1) / (iter.y2 - iter.y1);
- int winding = -1;
+ int direction = -1;
if (y1 > y2)
{
swapVariables (y1, y2);
- winding = 1;
+ direction = 1;
}
if (y1 < 0)
y1 = 0;
- if (y2 > bottomLimit)
- y2 = bottomLimit;
+ if (y2 > heightLimit)
+ y2 = heightLimit;
- const int stepSize = jlimit (1, 256, 256 / (1 + (int) fabs (multiplier)));
-
- while (y1 < y2)
+ if (y1 < y2)
{
- const int step = jmin (stepSize, y2 - y1, 256 - (y1 & 255));
+ const double startX = 256.0f * iter.x1;
+ const double multiplier = (iter.x2 - iter.x1) / (iter.y2 - iter.y1);
+ const int stepSize = jlimit (1, 256, 256 / (1 + (int) fabs (multiplier)));
- addEdgePoint (roundDoubleToInt (startX + multiplier * (y1 - startY)),
- y1 >> 8, winding * step);
+ do
+ {
+ const int step = jmin (stepSize, y2 - y1, 256 - (y1 & 255));
+ int x = roundDoubleToInt (startX + multiplier * (y1 - startY));
- y1 += step;
+ if (x < leftLimit)
+ x = leftLimit;
+ else if (x >= rightLimit)
+ x = rightLimit - 1;
+
+ addEdgePoint (x, y1 >> 8, direction * step);
+ y1 += step;
+ }
+ while (y1 < y2);
}
}
}
@@ -78889,7 +78904,7 @@ EdgeTable::EdgeTable (const int top_, const int height_,
{
int* lineStart = table;
- for (int i = height; --i >= 0;)
+ for (int i = bounds.getHeight(); --i >= 0;)
{
int* line = lineStart;
lineStart += lineStrideElements;
@@ -78917,14 +78932,11 @@ EdgeTable::EdgeTable (const int top_, const int height_,
}
EdgeTable::EdgeTable (const Rectangle& rectangleToAdd) throw()
- : top (rectangleToAdd.getY()),
- height (jmax (1, rectangleToAdd.getHeight())),
+ : bounds (rectangleToAdd),
maxEdgesPerLine (juce_edgeTableDefaultEdgesPerLine),
lineStrideElements ((juce_edgeTableDefaultEdgesPerLine << 1) + 1)
{
- jassert (! rectangleToAdd.isEmpty());
-
- table = (int*) juce_malloc (height * lineStrideElements * sizeof (int));
+ table = (int*) juce_malloc (jmax (1, bounds.getHeight()) * lineStrideElements * sizeof (int));
*table = 0;
const int x1 = rectangleToAdd.getX();
@@ -78952,12 +78964,11 @@ const EdgeTable& EdgeTable::operator= (const EdgeTable& other) throw()
{
juce_free (table);
- top = other.top;
- height = other.height;
+ bounds = other.bounds;
maxEdgesPerLine = other.maxEdgesPerLine;
lineStrideElements = other.lineStrideElements;
- const int tableSize = height * lineStrideElements * sizeof (int);
+ const int tableSize = jmax (1, bounds.getHeight()) * lineStrideElements * sizeof (int);
table = (int*) juce_malloc (tableSize);
memcpy (table, other.table, tableSize);
@@ -78975,10 +78986,11 @@ void EdgeTable::remapTableForNumEdges (const int newNumEdgesPerLine) throw()
{
maxEdgesPerLine = newNumEdgesPerLine;
+ jassert (bounds.getHeight() > 0);
const int newLineStrideElements = maxEdgesPerLine * 2 + 1;
- int* const newTable = (int*) juce_malloc (height * newLineStrideElements * sizeof (int));
+ int* const newTable = (int*) juce_malloc (bounds.getHeight() * newLineStrideElements * sizeof (int));
- for (int i = 0; i < height; ++i)
+ for (int i = 0; i < bounds.getHeight(); ++i)
{
const int* srcLine = table + lineStrideElements * i;
int* dstLine = newTable + newLineStrideElements * i;
@@ -79001,90 +79013,230 @@ void EdgeTable::optimiseTable() throw()
{
int maxLineElements = 0;
- for (int i = height; --i >= 0;)
- maxLineElements = jmax (maxLineElements,
- table [i * lineStrideElements]);
+ for (int i = bounds.getHeight(); --i >= 0;)
+ maxLineElements = jmax (maxLineElements, table [i * lineStrideElements]);
remapTableForNumEdges (maxLineElements);
}
void EdgeTable::addEdgePoint (const int x, const int y, const int winding) throw()
{
- jassert (y >= 0 && y < height)
+ jassert (y >= 0 && y < bounds.getHeight());
- int* lineStart = table + lineStrideElements * y;
- int n = lineStart[0];
+ int* line = table + lineStrideElements * y;
+ const int numPoints = line[0];
+ int n = line[0] << 1;
- if (n >= maxEdgesPerLine)
+ if (n > 0)
{
- remapTableForNumEdges (maxEdgesPerLine + juce_edgeTableDefaultEdgesPerLine);
- jassert (n < maxEdgesPerLine);
- lineStart = table + lineStrideElements * y;
+ while (n > 0)
+ {
+ const int cx = line [n - 1];
+
+ if (cx <= x)
+ {
+ if (cx == x)
+ {
+ line [n] += winding;
+ return;
+ }
+
+ break;
+ }
+
+ n -= 2;
+ }
+
+ if (numPoints >= maxEdgesPerLine)
+ {
+ remapTableForNumEdges (maxEdgesPerLine + juce_edgeTableDefaultEdgesPerLine);
+ jassert (numPoints < maxEdgesPerLine);
+ line = table + lineStrideElements * y;
+ }
+
+ memmove (line + (n + 3), line + (n + 1), sizeof (int) * ((numPoints << 1) - n));
}
- n <<= 1;
-
- int* const line = lineStart + 1;
-
- while (n > 0)
- {
- const int cx = line [n - 2];
-
- if (cx <= x)
- break;
-
- line [n] = cx;
- line [n + 1] = line [n - 1];
- n -= 2;
- }
-
- line [n] = x;
- line [n + 1] = winding;
-
- lineStart[0]++;
+ line [n + 1] = x;
+ line [n + 2] = winding;
+ line[0]++;
}
void EdgeTable::clearLineSection (const int y, int minX, int maxX) throw()
{
-// int* line = table + lineStrideElements * y;
+ jassert (y >= 0 && y < bounds.getHeight());
+ jassert (maxX > minX);
+ int* lineStart = table + lineStrideElements * y;
+ const int totalPoints = *lineStart;
+ int* line = lineStart;
+ int level = 0;
+ int num = totalPoints;
+
+ while (--num >= 0)
+ {
+ int x = *++line;
+
+ if (x < minX)
+ {
+ level += *++line;
+ continue;
+ }
+
+ if (x > maxX)
+ {
+ if (level != 0)
+ {
+ addEdgePoint (minX, y, -level);
+ addEdgePoint (maxX, y, level);
+ }
+
+ return;
+ }
+
+ if (level != 0)
+ {
+ const int oldLevel = level;
+ level += line[1];
+ line[0] = minX;
+ line[1] = -oldLevel;
+ line += 2;
+ }
+ else
+ {
+ ++num;
+ }
+
+ int* cutPoint = line;
+ int numToDelete = 0;
+
+ while (--num >= 0)
+ {
+ x = *line++;
+
+ if (x <= maxX)
+ {
+ level += *line++;
+ ++numToDelete;
+ continue;
+ }
+
+ break;
+ }
+
+ if (num < 0)
+ {
+ lineStart[0] -= numToDelete;
+ }
+ else
+ {
+ if (--numToDelete > 0)
+ {
+ char* startOfSrcSection = (char*) (cutPoint + numToDelete * 2);
+ memmove (cutPoint, startOfSrcSection,
+ ((char*) (lineStart + (1 + 2 * totalPoints))) - startOfSrcSection);
+
+ lineStart[0] -= numToDelete;
+ }
+
+ if (numToDelete < 0)
+ {
+ addEdgePoint (maxX, y, level);
+ }
+ else
+ {
+ cutPoint[0] = maxX;
+ cutPoint[1] = level;
+ }
+ }
+
+ break;
+ }
}
-void EdgeTable::clipToRectangle (const Rectangle& r) throw()
+void EdgeTable::intersectWithEdgeTableLine (const int y, const int* otherLine) throw()
{
- const int rectTop = jmax (0, r.getY() - top);
- const int rectBottom = jmin (height, r.getBottom() - top);
+// int otherNum = otherLine[0];
+}
- for (int i = rectTop - 1; --i >= 0;)
- table [lineStrideElements * i] = 0;
+/*void EdgeTable::clipToRectangle (const Rectangle& r) throw()
+{
+ const Rectangle clipped (r.getIntersection (bounds));
- for (int i = rectBottom; i < height; ++i)
- table [lineStrideElements * i] = 0;
-
- for (int i = rectTop; i < rectBottom; ++i)
+ if (clipped.isEmpty())
{
- clearLineSection (i, -INT_MAX, r.getX());
- clearLineSection (i, r.getRight(), INT_MAX);
+ bounds.setHeight (0);
+ }
+ else
+ {
+ const int top = clipped.getY() - bounds.getY();
+ const int bottom = clipped.getBottom() - bounds.getY();
+
+ if (bottom < bounds.getHeight())
+ bounds.setHeight (bottom);
+
+ if (clipped.getRight() < bounds.getRight())
+ bounds.setRight (clipped.getRight());
+
+ for (int i = top; --i >= 0;)
+ table [lineStrideElements * i] = 0;
+
+ if (clipped.getX() > bounds.getX())
+ for (int i = top; i < bottom; ++i)
+ clearLineSection (i, bounds.getX(), clipped.getX());
}
}
void EdgeTable::excludeRectangle (const Rectangle& r) throw()
{
- const int rectTop = jmax (0, r.getY() - top);
- const int rectBottom = jmin (height, r.getBottom() - top);
+ const Rectangle clipped (r.getIntersection (bounds));
- for (int i = rectTop; i < rectBottom; ++i)
- clearLineSection (i, r.getX(), r.getRight());
+ if (! clipped.isEmpty())
+ {
+ const int top = clipped.getY() - bounds.getY();
+ const int bottom = clipped.getBottom() - bounds.getY();
+
+ for (int i = top; i < bottom; ++i)
+ clearLineSection (i, clipped.getX(), clipped.getRight());
+ }
}
void EdgeTable::clipToEdgeTable (const EdgeTable& other)
{
+ const Rectangle clipped (other.bounds.getIntersection (bounds));
+
+ if (clipped.isEmpty())
+ {
+ bounds.setHeight (0);
+ }
+ else
+ {
+ const int top = clipped.getY() - bounds.getY();
+ const int bottom = clipped.getBottom() - bounds.getY();
+
+ if (bottom < bounds.getHeight())
+ bounds.setHeight (bottom);
+
+ if (clipped.getRight() < bounds.getRight())
+ bounds.setRight (clipped.getRight());
+
+ for (int i = top; --i >= 0;)
+ table [lineStrideElements * i] = 0;
+
+ const int* otherLine = other.table + other.lineStrideElements * (top + (bounds.getY() - other.bounds.getY()));
+
+ for (int i = top; i < bottom; ++i)
+ {
+ intersectWithEdgeTableLine (i, otherLine);
+ otherLine += other.lineStrideElements;
+ }
+ }
}
void EdgeTable::clipToImageAlpha (Image& image, int x, int y) throw()
{
}
-
+*/
END_JUCE_NAMESPACE
/********* End of inlined file: juce_EdgeTable.cpp *********/
@@ -81878,6 +82030,14 @@ void LowLevelGraphicsSoftwareRenderer::excludeClipRegion (int x, int y, int w, i
clip->subtract (Rectangle (x + xOffset, y + yOffset, w, h));
}
+void LowLevelGraphicsSoftwareRenderer::clipToPath (const Path& path, const AffineTransform& transform)
+{
+}
+
+void LowLevelGraphicsSoftwareRenderer::clipToImage (Image& image, int imageX, int imageY)
+{
+}
+
bool LowLevelGraphicsSoftwareRenderer::clipRegionIntersects (int x, int y, int w, int h)
{
return clip->intersectsRectangle (Rectangle (x + xOffset, y + yOffset, w, h));
@@ -82056,7 +82216,7 @@ void LowLevelGraphicsSoftwareRenderer::clippedFillPath (int clipX, int clipY, in
if (getPathBounds (clipX, clipY, clipW, clipH, path, transform, cx, cy, cw, ch))
{
- EdgeTable edgeTable (0, ch, path, transform.translated ((float) -cx, (float) -cy));
+ EdgeTable edgeTable (Rectangle (0, 0, cw, ch), path, transform.translated ((float) -cx, (float) -cy));
int stride, pixelStride;
uint8* const pixels = (uint8*) image.lockPixelDataReadWrite (cx, cy, cw, ch, stride, pixelStride);
@@ -82092,18 +82252,18 @@ void LowLevelGraphicsSoftwareRenderer::clippedFillPath (int clipX, int clipY, in
if (isIdentity)
{
GradientEdgeTableRenderer renderer (pixels, stride, g2, lookupTable, numLookupEntries);
- edgeTable.iterate (renderer, 0, 0, cw, ch, 0);
+ edgeTable.iterate (renderer);
}
else
{
GradientEdgeTableRenderer renderer (pixels, stride, g2, lookupTable, numLookupEntries);
- edgeTable.iterate (renderer, 0, 0, cw, ch, 0);
+ edgeTable.iterate (renderer);
}
}
else
{
GradientEdgeTableRenderer renderer (pixels, stride, g2, lookupTable, numLookupEntries);
- edgeTable.iterate (renderer, 0, 0, cw, ch, 0);
+ edgeTable.iterate (renderer);
}
}
else if (image.getFormat() == Image::ARGB)
@@ -82115,18 +82275,18 @@ void LowLevelGraphicsSoftwareRenderer::clippedFillPath (int clipX, int clipY, in
if (isIdentity)
{
GradientEdgeTableRenderer renderer (pixels, stride, g2, lookupTable, numLookupEntries);
- edgeTable.iterate (renderer, 0, 0, cw, ch, 0);
+ edgeTable.iterate (renderer);
}
else
{
GradientEdgeTableRenderer renderer (pixels, stride, g2, lookupTable, numLookupEntries);
- edgeTable.iterate (renderer, 0, 0, cw, ch, 0);
+ edgeTable.iterate (renderer);
}
}
else
{
GradientEdgeTableRenderer renderer (pixels, stride, g2, lookupTable, numLookupEntries);
- edgeTable.iterate (renderer, 0, 0, cw, ch, 0);
+ edgeTable.iterate (renderer);
}
}
else if (image.getFormat() == Image::SingleChannel)
@@ -82142,19 +82302,19 @@ void LowLevelGraphicsSoftwareRenderer::clippedFillPath (int clipX, int clipY, in
{
jassert (pixelStride == 3);
SolidColourEdgeTableRenderer renderer (pixels, stride, colour);
- edgeTable.iterate (renderer, 0, 0, cw, ch, 0);
+ edgeTable.iterate (renderer);
}
else if (image.getFormat() == Image::ARGB)
{
jassert (pixelStride == 4);
SolidColourEdgeTableRenderer renderer (pixels, stride, colour);
- edgeTable.iterate (renderer, 0, 0, cw, ch, 0);
+ edgeTable.iterate (renderer);
}
else if (image.getFormat() == Image::SingleChannel)
{
jassert (pixelStride == 1);
AlphaBitmapRenderer renderer (pixels, stride);
- edgeTable.iterate (renderer, 0, 0, cw, ch, 0);
+ edgeTable.iterate (renderer);
}
}
@@ -82183,7 +82343,8 @@ void LowLevelGraphicsSoftwareRenderer::clippedFillPathWithImage (int x, int y, i
{
if (Rectangle::intersectRectangles (x, y, w, h, imageX, imageY, sourceImage.getWidth(), sourceImage.getHeight()))
{
- EdgeTable edgeTable (0, h, path, transform.translated ((float) (xOffset - x), (float) (yOffset - y)));
+ EdgeTable edgeTable (Rectangle (0, 0, w, h), path,
+ transform.translated ((float) (xOffset - x), (float) (yOffset - y)));
int stride, pixelStride;
uint8* const pixels = (uint8*) image.lockPixelDataReadWrite (x, y, w, h, stride, pixelStride);
@@ -82200,14 +82361,14 @@ void LowLevelGraphicsSoftwareRenderer::clippedFillPathWithImage (int x, int y, i
ImageFillEdgeTableRenderer renderer (pixels, stride,
srcPix, srcStride,
alpha, (PixelRGB*) 0);
- edgeTable.iterate (renderer, 0, 0, w, h, 0);
+ edgeTable.iterate (renderer);
}
else if (sourceImage.getFormat() == Image::ARGB)
{
ImageFillEdgeTableRenderer renderer (pixels, stride,
srcPix, srcStride,
alpha, (PixelARGB*) 0);
- edgeTable.iterate (renderer, 0, 0, w, h, 0);
+ edgeTable.iterate (renderer);
}
else
{
@@ -82221,14 +82382,14 @@ void LowLevelGraphicsSoftwareRenderer::clippedFillPathWithImage (int x, int y, i
ImageFillEdgeTableRenderer renderer (pixels, stride,
srcPix, srcStride,
alpha, (PixelRGB*) 0);
- edgeTable.iterate (renderer, 0, 0, w, h, 0);
+ edgeTable.iterate (renderer);
}
else if (sourceImage.getFormat() == Image::ARGB)
{
ImageFillEdgeTableRenderer renderer (pixels, stride,
srcPix, srcStride,
alpha, (PixelARGB*) 0);
- edgeTable.iterate (renderer, 0, 0, w, h, 0);
+ edgeTable.iterate (renderer);
}
else
{
@@ -87897,8 +88058,8 @@ const AffineTransform AffineTransform::followedBy (const float omat00,
const AffineTransform AffineTransform::translated (const float dx,
const float dy) const throw()
{
- return followedBy (1.0f, 0, dx,
- 0, 1.0f, dy);
+ return AffineTransform (mat00, mat01, mat02 + dx,
+ mat10, mat11, mat12 + dy);
}
const AffineTransform AffineTransform::translation (const float dx,
@@ -87993,6 +88154,14 @@ bool AffineTransform::isSingularity() const throw()
return (mat00 * mat11 - mat10 * mat01) == 0.0;
}
+bool AffineTransform::isOnlyTranslation() const throw()
+{
+ return (mat01 == 0)
+ && (mat10 == 0)
+ && (mat00 == 1.0f)
+ && (mat11 == 1.0f);
+}
+
void AffineTransform::transformPoint (float& x,
float& y) const throw()
{
@@ -90044,17 +90213,17 @@ Image* Path::createMaskBitmap (const AffineTransform& transform,
if (imagePosition.isEmpty())
return 0;
- Image* im = new Image (Image::SingleChannel, imagePosition.getWidth(), imagePosition.getHeight(), true);
+ Image* im = Image::createNativeImage (Image::SingleChannel, imagePosition.getWidth(), imagePosition.getHeight(), true);
- EdgeTable edgeTable (0, imagePosition.getHeight(), *this,
- transform.translated (-imagePosition.getX(), -imagePosition.getY()));
+ EdgeTable edgeTable (Rectangle (0, 0, imagePosition.getWidth(), imagePosition.getHeight()),
+ *this, transform.translated (-imagePosition.getX(), -imagePosition.getY()));
int stride, pixelStride;
uint8* const pixels = (uint8*) im->lockPixelDataReadWrite (0, 0, imagePosition.getWidth(), imagePosition.getHeight(), stride, pixelStride);
jassert (pixelStride == 1);
MaskBitmapRenderer renderer (pixels, stride);
- edgeTable.iterate (renderer, 0, 0, imagePosition.getWidth(), imagePosition.getHeight(), 0);
+ edgeTable.iterate (renderer);
im->releasePixelDataReadWrite (pixels);
return im;
@@ -91420,6 +91589,16 @@ void Rectangle::setSize (const int w_,
h = h_;
}
+void Rectangle::setWidth (const int newWidth) throw()
+{
+ w = newWidth;
+}
+
+void Rectangle::setHeight (const int newHeight) throw()
+{
+ h = newHeight;
+}
+
void Rectangle::setLeft (const int newLeft) throw()
{
w = jmax (0, x + w - newLeft);
@@ -92364,7 +92543,7 @@ Image* Image::createCopy (int newWidth, int newHeight,
if (newHeight < 0)
newHeight = imageHeight;
- Image* const newImage = new Image (format, newWidth, newHeight, true);
+ Image* const newImage = Image::createNativeImage (format, newWidth, newHeight, true);
Graphics g (*newImage);
g.setImageResamplingQuality (quality);
@@ -92381,7 +92560,7 @@ Image* Image::createCopyOfAlphaChannel() const
{
jassert (format != SingleChannel);
- Image* const newImage = new Image (SingleChannel, imageWidth, imageHeight, false);
+ Image* const newImage = Image::createNativeImage (SingleChannel, imageWidth, imageHeight, false);
if (! hasAlphaChannel())
{
@@ -93461,8 +93640,8 @@ GIFLoader::GIFLoader (InputStream& in)
if (! readPalette (numColours))
break;
- image = new Image ((transparent >= 0) ? Image::ARGB : Image::RGB,
- imageWidth, imageHeight, (transparent >= 0));
+ image = Image::createNativeImage ((transparent >= 0) ? Image::ARGB : Image::RGB,
+ imageWidth, imageHeight, (transparent >= 0));
readImage (imageWidth, imageHeight,
(buf[8] & 0x40) != 0,
@@ -208740,7 +208919,7 @@ Image* juce_loadJPEGImageFromStream (InputStream& in) throw()
if (jpeg_start_decompress (&jpegDecompStruct))
{
- image = new Image (Image::RGB, width, height, false);
+ image = Image::createNativeImage (Image::RGB, width, height, false);
for (int y = 0; y < height; ++y)
{
@@ -234414,8 +234593,8 @@ Image* juce_loadPNGImageFromStream (InputStream& in) throw()
png_destroy_read_struct (&pngReadStruct, &pngInfoStruct, 0);
// now convert the data to a juce image format..
- image = new Image (hasAlphaChan ? Image::ARGB : Image::RGB,
- width, height, hasAlphaChan);
+ image = Image::createNativeImage (hasAlphaChan ? Image::ARGB : Image::RGB,
+ width, height, hasAlphaChan);
int stride, pixelStride;
uint8* const pixels = image->lockPixelDataReadWrite (0, 0, width, height, stride, pixelStride);
@@ -235861,6 +236040,7 @@ const File JUCE_CALLTYPE File::getSpecialLocation (const SpecialLocationType typ
return File (String (dest));
}
+ case invokedExecutableFile:
case currentExecutableFile:
case currentApplicationFile:
{
@@ -239409,6 +239589,11 @@ void Desktop::setMousePosition (int x, int y) throw()
SetCursorPos (x, y);
}
+Image* Image::createNativeImage (const PixelFormat format, const int imageWidth, const int imageHeight, const bool clearImage)
+{
+ return new Image (format, imageWidth, imageHeight, clearImage);
+}
+
class ScreenSaverDefeater : public Timer,
public DeletedAtShutdown
{
@@ -241872,6 +242057,12 @@ bool QuickTimeMovieComponent::loadMovie (const File& movieFile_,
return ok;
}
+bool QuickTimeMovieComponent::loadMovie (const URL& movieURL,
+ const bool isControllerVisible)
+{
+ return loadMovie ((InputStream*) movieURL_.createInputStream (false), isControllerVisible);
+}
+
void QuickTimeMovieComponent::goToStart()
{
setPosition (0.0);
@@ -251718,6 +251909,8 @@ bool File::isHidden() const throw()
return getFileName().startsWithChar (T('.'));
}
+const char* juce_Argv0 = 0; // referenced from juce_Application.cpp
+
const File File::getSpecialLocation (const SpecialLocationType type)
{
switch (type)
@@ -251766,6 +251959,11 @@ const File File::getSpecialLocation (const SpecialLocationType type)
return tmp;
}
+ case invokedExecutableFile:
+ if (juce_Argv0 != 0)
+ return File (String::fromUTF8 ((const uint8*) juce_Argv0));
+ // deliberate fall-through...
+
case currentExecutableFile:
case currentApplicationFile:
return juce_getExecutableFile();
@@ -256862,6 +257060,11 @@ Image* juce_createIconForFile (const File& file)
return 0;
}
+Image* Image::createNativeImage (const PixelFormat format, const int imageWidth, const int imageHeight, const bool clearImage)
+{
+ return new Image (format, imageWidth, imageHeight, clearImage);
+}
+
#if JUCE_OPENGL
class WindowedGLContext : public OpenGLContext
@@ -259823,7 +260026,7 @@ int SystemStats::getCpuSpeedInMegaherz() throw()
int SystemStats::getNumCpus() throw()
{
-#if MACOS_10_4_OR_EARLIER
+#if MAC_OS_X_VERSION_MIN_REQUIRED < MAC_OS_X_VERSION_10_5
return MPProcessors();
#else
return [[NSProcessInfo processInfo] activeProcessorCount];
@@ -261191,6 +261394,8 @@ bool File::isHidden() const throw()
return juce_isHiddenFile (getFullPathName());
}
+const char* juce_Argv0 = 0; // referenced from juce_Application.cpp
+
const File File::getSpecialLocation (const SpecialLocationType type)
{
const ScopedAutoReleasePool pool;
@@ -261239,6 +261444,11 @@ const File File::getSpecialLocation (const SpecialLocationType type)
return tmp.getFullPathName();
}
+ case invokedExecutableFile:
+ if (juce_Argv0 != 0)
+ return File (String::fromUTF8 ((const uint8*) juce_Argv0));
+ // deliberate fall-through...
+
case currentExecutableFile:
return juce_getExecutableFile();
@@ -261680,21 +261890,6 @@ bool DragAndDropContainer::performExternalDragDropOfText (const String& text)
return false;
}
-bool Desktop::canUseSemiTransparentWindows() throw()
-{
- return true;
-}
-
-void Desktop::getMousePosition (int& x, int& y) throw()
-{
- x = 0;
- y = 0;
-}
-
-void Desktop::setMousePosition (int x, int y) throw()
-{
-}
-
void Desktop::setScreenSaverEnabled (const bool isEnabled) throw()
{
[[UIApplication sharedApplication] setIdleTimerDisabled: ! isEnabled];
@@ -261845,17 +262040,11 @@ void Desktop::setMousePosition (int x, int y) throw()
// this rubbish needs to be done around the warp call, to avoid causing a
// bizarre glitch..
CGAssociateMouseAndMouseCursorPosition (false);
-#if (! defined (MAC_OS_X_VERSION_10_6)) || MAC_OS_X_VERSION_MAX_ALLOWED < MAC_OS_X_VERSION_10_6
- CGSetLocalEventsSuppressionInterval (0);
-#endif
-
- CGPoint pos = { x, y };
- CGWarpMouseCursorPosition (pos);
-
+ CGWarpMouseCursorPosition (CGPointMake (x, y));
CGAssociateMouseAndMouseCursorPosition (true);
}
-#if MACOS_10_4_OR_EARLIER
+#if MAC_OS_X_VERSION_MIN_REQUIRED < MAC_OS_X_VERSION_10_5
class ScreenSaverDefeater : public Timer,
public DeletedAtShutdown
{
@@ -262016,6 +262205,10 @@ bool JUCE_CALLTYPE Process::isRunningUnderDebugger() throw()
#define SUPPORT_10_4_FONTS 1
#define NEW_CGFONT_FUNCTIONS_UNAVAILABLE (CGFontCreateWithFontName == 0)
+ #if MAC_OS_X_VERSION_MAX_ALLOWED < MAC_OS_X_VERSION_10_5
+ #define SUPPORT_ONLY_10_4_FONTS 1
+ #endif
+
END_JUCE_NAMESPACE
@interface NSFont (PrivateHack)
- (NSGlyph) _defaultGlyphForChar: (unichar) theChar;
@@ -262028,8 +262221,10 @@ class MacTypeface : public Typeface
public:
MacTypeface (const Font& font)
- : Typeface (font.getTypefaceName()),
- charToGlyphMapper (0)
+ : Typeface (font.getTypefaceName())
+#if ! SUPPORT_ONLY_10_4_FONTS
+ , charToGlyphMapper (0)
+#endif
{
const ScopedAutoReleasePool pool;
renderingTransform = CGAffineTransformIdentity;
@@ -262074,9 +262269,11 @@ public:
fontRef = CGFontCreateWithFontName ((CFStringRef) fontName);
- const int totalHeight = abs (CGFontGetAscent (fontRef)) + abs (CGFontGetDescent (fontRef));
+ const int ascender = abs (CGFontGetAscent (fontRef));
+ const float totalHeight = ascender + abs (CGFontGetDescent (fontRef));
+ ascent = ascender / totalHeight;
unitsToHeightScaleFactor = 1.0f / totalHeight;
- fontHeightToCGSizeFactor = CGFontGetUnitsPerEm (fontRef) / (float) totalHeight;
+ fontHeightToCGSizeFactor = CGFontGetUnitsPerEm (fontRef) / totalHeight;
#else
nsFont = [NSFont fontWithName: juceStringToNS (font.getTypefaceName()) size: 1024];
@@ -262108,7 +262305,19 @@ public:
renderingTransform.c = 0.15f;
}
-#if SUPPORT_10_4_FONTS
+#if SUPPORT_ONLY_10_4_FONTS
+ ATSFontRef atsFont = ATSFontFindFromName ((CFStringRef) [nsFont fontName], kATSOptionFlagsDefault);
+
+ if (atsFont == 0)
+ atsFont = ATSFontFindFromPostScriptName ((CFStringRef) [nsFont fontName], kATSOptionFlagsDefault);
+
+ fontRef = CGFontCreateWithPlatformFont ((void*) &atsFont);
+
+ const float totalHeight = fabsf ([nsFont ascender]) + fabsf([nsFont descender]);
+ unitsToHeightScaleFactor = 1.0f / totalHeight;
+ fontHeightToCGSizeFactor = 1024.0f / totalHeight;
+#else
+ #if SUPPORT_10_4_FONTS
if (NEW_CGFONT_FUNCTIONS_UNAVAILABLE)
{
ATSFontRef atsFont = ATSFontFindFromName ((CFStringRef) [nsFont fontName], kATSOptionFlagsDefault);
@@ -262123,7 +262332,7 @@ public:
fontHeightToCGSizeFactor = 1024.0f / totalHeight;
}
else
-#endif
+ #endif
{
fontRef = CGFontCreateWithFontName ((CFStringRef) [nsFont fontName]);
@@ -262131,18 +262340,22 @@ public:
unitsToHeightScaleFactor = 1.0f / totalHeight;
fontHeightToCGSizeFactor = CGFontGetUnitsPerEm (fontRef) / (float) totalHeight;
}
+#endif
#endif
}
~MacTypeface()
{
+#if ! JUCE_IPHONE
[nsFont release];
-
+#endif
if (fontRef != 0)
CGFontRelease (fontRef);
+#if ! SUPPORT_ONLY_10_4_FONTS
delete charToGlyphMapper;
+#endif
}
float getAscent() const
@@ -262165,7 +262378,16 @@ public:
int x = 0;
-#if SUPPORT_10_4_FONTS
+#if SUPPORT_ONLY_10_4_FONTS
+ NSSize* const advances = (NSSize*) juce_malloc (length * sizeof (NSSize));
+ [nsFont getAdvancements: advances forGlyphs: (NSGlyph*) glyphs count: length];
+
+ for (int i = 0; i < length; ++i)
+ x += advances[i].width;
+
+ juce_free (advances);
+#else
+ #if SUPPORT_10_4_FONTS
if (NEW_CGFONT_FUNCTIONS_UNAVAILABLE)
{
NSSize* const advances = (NSSize*) juce_malloc (length * sizeof (NSSize));
@@ -262177,7 +262399,7 @@ public:
juce_free (advances);
}
else
-#endif
+ #endif
{
int* const advances = (int*) juce_malloc (length * sizeof (int));
@@ -262187,6 +262409,7 @@ public:
juce_free (advances);
}
+#endif
juce_free (glyphs);
@@ -262203,7 +262426,21 @@ public:
const int length = text.length();
CGGlyph* const glyphs = createGlyphsForString (text, length);
-#if SUPPORT_10_4_FONTS
+#if SUPPORT_ONLY_10_4_FONTS
+ NSSize* const advances = (NSSize*) juce_malloc (length * sizeof (NSSize));
+ [nsFont getAdvancements: advances forGlyphs: (NSGlyph*) glyphs count: length];
+
+ int x = 0;
+ for (int i = 0; i < length; ++i)
+ {
+ x += advances[i].width;
+ xOffsets.add (x * unitsToHeightScaleFactor);
+ resultGlyphs.add (((NSGlyph*) glyphs)[i]);
+ }
+
+ juce_free (advances);
+#else
+ #if SUPPORT_10_4_FONTS
if (NEW_CGFONT_FUNCTIONS_UNAVAILABLE)
{
NSSize* const advances = (NSSize*) juce_malloc (length * sizeof (NSSize));
@@ -262220,7 +262457,7 @@ public:
juce_free (advances);
}
else
-#endif
+ #endif
{
int* const advances = (int*) juce_malloc (length * sizeof (int));
@@ -262237,6 +262474,7 @@ public:
juce_free (advances);
}
+#endif
juce_free (glyphs);
}
@@ -262306,7 +262544,9 @@ private:
CGGlyph* createGlyphsForString (const juce_wchar* const text, const int length) throw()
{
#if SUPPORT_10_4_FONTS
+ #if ! SUPPORT_ONLY_10_4_FONTS
if (NEW_CGFONT_FUNCTIONS_UNAVAILABLE)
+ #endif
{
NSGlyph* const g = (NSGlyph*) juce_malloc (sizeof (NSGlyph) * length);
@@ -262316,6 +262556,8 @@ private:
return (CGGlyph*) g;
}
#endif
+
+#if ! SUPPORT_ONLY_10_4_FONTS
if (charToGlyphMapper == 0)
charToGlyphMapper = new CharToGlyphMapper (fontRef);
@@ -262325,8 +262567,10 @@ private:
g[i] = (CGGlyph) charToGlyphMapper->getGlyphForCharacter (text[i]);
return g;
+#endif
}
+#if ! SUPPORT_ONLY_10_4_FONTS
// Reads a CGFontRef's character map table to convert unicode into glyph numbers
class CharToGlyphMapper
{
@@ -262425,6 +262669,7 @@ private:
};
CharToGlyphMapper* charToGlyphMapper;
+#endif
};
const Typeface::Ptr Typeface::createSystemTypefaceFor (const Font& font)
@@ -262453,14 +262698,659 @@ const StringArray Font::findAllTypefaceNames() throw()
void Font::getPlatformDefaultFontNames (String& defaultSans, String& defaultSerif, String& defaultFixed) throw()
{
+#if JUCE_IPHONE
+ defaultSans = "Helvetica";
+ defaultSerif = "Times New Roman";
+ defaultFixed = "Courier New";
+#else
defaultSans = "Lucida Grande";
defaultSerif = "Times New Roman";
defaultFixed = "Monaco";
+#endif
}
#endif
/********* End of inlined file: juce_mac_Fonts.mm *********/
+/********* Start of inlined file: juce_mac_CoreGraphicsContext.mm *********/
+// (This file gets included by juce_mac_NativeCode.mm, rather than being
+// compiled on its own).
+#if JUCE_INCLUDED_FILE
+
+class CoreGraphicsImage : public Image
+{
+public:
+ CoreGraphicsImage (const PixelFormat format,
+ const int imageWidth,
+ const int imageHeight,
+ const bool clearImage)
+ : Image (format, imageWidth, imageHeight, clearImage)
+ {
+ CGColorSpaceRef colourSpace = format == Image::SingleChannel ? CGColorSpaceCreateDeviceGray()
+ : CGColorSpaceCreateDeviceRGB();
+
+ context = CGBitmapContextCreate (imageData, imageWidth, imageHeight, 8, lineStride,
+ colourSpace,
+ format == Image::ARGB ? (kCGImageAlphaPremultipliedFirst | kCGBitmapByteOrder32Little)
+ : kCGBitmapByteOrderDefault);
+
+ CGColorSpaceRelease (colourSpace);
+ }
+
+ ~CoreGraphicsImage()
+ {
+ CGContextRelease (context);
+ }
+
+ LowLevelGraphicsContext* createLowLevelContext();
+
+ CGContextRef context;
+};
+
+Image* Image::createNativeImage (const PixelFormat format, const int imageWidth, const int imageHeight, const bool clearImage)
+{
+ return new CoreGraphicsImage (format == RGB ? ARGB : format, imageWidth, imageHeight, clearImage);
+}
+
+class CoreGraphicsContext : public LowLevelGraphicsContext
+{
+public:
+ CoreGraphicsContext (CGContextRef context_, const float flipHeight_)
+ : context (context_),
+ flipHeight (flipHeight_)
+ {
+ CGContextRetain (context);
+ CGContextSetShouldSmoothFonts (context, true);
+ CGContextSetBlendMode (context, kCGBlendModeNormal);
+ rgbColourSpace = CGColorSpaceCreateDeviceRGB();
+ greyColourSpace = CGColorSpaceCreateDeviceGray();
+ gradientCallbacks.version = 0;
+ gradientCallbacks.evaluate = gradientCallback;
+ gradientCallbacks.releaseInfo = 0;
+ state = new SavedState();
+ }
+
+ ~CoreGraphicsContext()
+ {
+ CGContextRelease (context);
+ CGColorSpaceRelease (rgbColourSpace);
+ CGColorSpaceRelease (greyColourSpace);
+ delete state;
+ }
+
+ bool isVectorDevice() const { return false; }
+
+ void setOrigin (int x, int y)
+ {
+ CGContextTranslateCTM (context, x, -y);
+ }
+
+ bool reduceClipRegion (int x, int y, int w, int h)
+ {
+ CGContextClipToRect (context, CGRectMake (x, flipHeight - (y + h), w, h));
+ return ! isClipEmpty();
+ }
+
+ bool reduceClipRegion (const RectangleList& clipRegion)
+ {
+ const int numRects = clipRegion.getNumRectangles();
+ CGRect* const rects = new CGRect [numRects];
+ for (int i = 0; i < numRects; ++i)
+ {
+ const Rectangle& r = clipRegion.getRectangle(i);
+ rects[i] = CGRectMake (r.getX(), flipHeight - r.getBottom(), r.getWidth(), r.getHeight());
+ }
+
+ CGContextClipToRects (context, rects, numRects);
+ delete[] rects;
+
+ return ! isClipEmpty();
+ }
+
+ void excludeClipRegion (int x, int y, int w, int h)
+ {
+ RectangleList r (getClipBounds());
+ r.subtract (Rectangle (x, y, w, h));
+ reduceClipRegion (r);
+ }
+
+ void saveState()
+ {
+ CGContextSaveGState (context);
+ stateStack.add (new SavedState (*state));
+ }
+
+ void restoreState()
+ {
+ CGContextRestoreGState (context);
+
+ SavedState* const top = stateStack.getLast();
+
+ if (top != 0)
+ {
+ delete state;
+ state = top;
+ stateStack.removeLast (1, false);
+ }
+ else
+ {
+ jassertfalse // trying to pop with an empty stack!
+ }
+ }
+
+ bool clipRegionIntersects (int x, int y, int w, int h)
+ {
+ return getClipBounds().intersects (Rectangle (x, y, w, h));
+ }
+
+ const Rectangle getClipBounds() const
+ {
+ CGRect bounds = CGRectIntegral (CGContextGetClipBoundingBox (context));
+
+ return Rectangle (roundFloatToInt (bounds.origin.x),
+ roundFloatToInt (flipHeight - (bounds.origin.y + bounds.size.height)),
+ roundFloatToInt (bounds.size.width),
+ roundFloatToInt (bounds.size.height));
+ }
+
+ bool isClipEmpty() const
+ {
+ return CGRectIsEmpty (CGContextGetClipBoundingBox (context));
+ }
+
+ void setColour (const Colour& colour)
+ {
+ state->colour = colour;
+ deleteAndZero (state->gradient);
+
+ CGContextSetRGBFillColor (context,
+ colour.getFloatRed(), colour.getFloatGreen(),
+ colour.getFloatBlue(), colour.getFloatAlpha());
+ CGContextSetAlpha (context, 1.0f);
+ }
+
+ void setGradient (const ColourGradient& gradient)
+ {
+ if (state->gradient == 0)
+ state->gradient = new ColourGradient (gradient);
+ else
+ *state->gradient = gradient;
+ }
+
+ void setOpacity (float opacity)
+ {
+ setColour (state->colour.withAlpha (opacity));
+ }
+
+ void setInterpolationQuality (Graphics::ResamplingQuality quality)
+ {
+ CGContextSetInterpolationQuality (context, quality == Graphics::lowResamplingQuality
+ ? kCGInterpolationLow
+ : kCGInterpolationHigh);
+ }
+
+ void fillRect (int x, int y, int w, int h, const bool replaceExistingContents)
+ {
+ if (replaceExistingContents)
+ {
+#if MAC_OS_X_VERSION_MAX_ALLOWED < MAC_OS_X_VERSION_10_5
+ CGContextClearRect (context, CGRectMake (x, y, w, h));
+#else
+ #if MAC_OS_X_VERSION_MIN_REQUIRED < MAC_OS_X_VERSION_10_5
+ if (CGContextDrawLinearGradient == 0) // (just a way of checking whether we're running in 10.5 or later)
+ CGContextClearRect (context, CGRectMake (x, y, w, h));
+ else
+ #endif
+ CGContextSetBlendMode (context, kCGBlendModeCopy);
+#endif
+
+ fillRect (x, y, w, h, false);
+ CGContextSetBlendMode (context, kCGBlendModeNormal);
+ }
+ else
+ {
+ if (state->gradient == 0)
+ {
+ CGContextFillRect (context, CGRectMake (x, flipHeight - (y + h), w, h));
+ }
+ else
+ {
+ CGContextSaveGState (context);
+ CGContextClipToRect (context, CGRectMake (x, flipHeight - (y + h), w, h));
+ flip();
+ drawGradient();
+ CGContextRestoreGState (context);
+ }
+ }
+ }
+
+ void fillPath (const Path& path, const AffineTransform& transform)
+ {
+ CGContextSaveGState (context);
+
+ if (state->gradient == 0)
+ {
+ flip();
+ applyTransform (transform);
+ createPath (path);
+
+ if (path.isUsingNonZeroWinding())
+ CGContextFillPath (context);
+ else
+ CGContextEOFillPath (context);
+ }
+ else
+ {
+ createPath (path, transform);
+ CGContextClip (context);
+ flip();
+ applyTransform (state->gradient->transform);
+ drawGradient();
+ }
+
+ CGContextRestoreGState (context);
+ }
+
+ void fillPathWithImage (const Path& path, const AffineTransform& transform,
+ const Image& image, int imageX, int imageY)
+ {
+ CGContextSaveGState (context);
+ createPath (path, transform);
+ CGContextClip (context);
+ blendImage (image, imageX, imageY, image.getWidth(), image.getHeight(), 0, 0);
+ CGContextRestoreGState (context);
+ }
+
+ void fillAlphaChannel (const Image& alphaImage, int alphaImageX, int alphaImageY)
+ {
+ Image* singleChannelImage = createAlphaChannelImage (alphaImage);
+ CGImageRef image = createImage (*singleChannelImage, true);
+
+ CGContextSaveGState (context);
+ CGContextSetAlpha (context, 1.0f);
+
+ CGRect r = CGRectMake (alphaImageX, flipHeight - (alphaImageY + alphaImage.getHeight()),
+ alphaImage.getWidth(), alphaImage.getHeight());
+ CGContextClipToMask (context, r, image);
+
+ fillRect (alphaImageX, alphaImageY, alphaImage.getWidth(), alphaImage.getHeight(), false);
+
+ CGContextRestoreGState (context);
+ CGImageRelease (image);
+ deleteAlphaChannelImage (alphaImage, singleChannelImage);
+ }
+
+ void fillAlphaChannelWithImage (const Image& alphaImage, int alphaImageX, int alphaImageY,
+ const Image& fillerImage, int fillerImageX, int fillerImageY)
+ {
+ Image* singleChannelImage = createAlphaChannelImage (alphaImage);
+ CGImageRef image = createImage (*singleChannelImage, true);
+
+ CGContextSaveGState (context);
+ CGRect r = CGRectMake (alphaImageX, flipHeight - (alphaImageY + alphaImage.getHeight()),
+ alphaImage.getWidth(), alphaImage.getHeight());
+ CGContextClipToMask (context, r, image);
+
+ blendImage (fillerImage, fillerImageX, fillerImageY,
+ fillerImage.getWidth(), fillerImage.getHeight(),
+ 0, 0);
+
+ CGContextRestoreGState (context);
+
+ CGImageRelease (image);
+ deleteAlphaChannelImage (alphaImage, singleChannelImage);
+ }
+
+ void blendImage (const Image& sourceImage,
+ int destX, int destY, int destW, int destH, int sourceX, int sourceY)
+ {
+ CGImageRef image = createImage (sourceImage, false);
+
+ CGContextSaveGState (context);
+ CGContextClipToRect (context, CGRectMake (destX, flipHeight - (destY + destH), destW, destH));
+ CGContextSetAlpha (context, state->colour.getFloatAlpha());
+ CGContextDrawImage (context, CGRectMake (destX - sourceX,
+ flipHeight - ((destY - sourceY) + sourceImage.getHeight()),
+ sourceImage.getWidth(),
+ sourceImage.getHeight()), image);
+
+ CGContextRestoreGState (context);
+ CGImageRelease (image);
+ }
+
+ void blendImageWarping (const Image& sourceImage,
+ int srcClipX, int srcClipY, int srcClipW, int srcClipH,
+ const AffineTransform& transform)
+ {
+ CGImageRef fullImage = createImage (sourceImage, false);
+ CGImageRef image = CGImageCreateWithImageInRect (fullImage, CGRectMake (srcClipX, sourceImage.getHeight() - (srcClipY + srcClipH),
+ srcClipW, srcClipH));
+ CGImageRelease (fullImage);
+
+ CGContextSaveGState (context);
+ flip();
+ applyTransform (AffineTransform::scale (1.0f, -1.0f).translated (0, sourceImage.getHeight()).followedBy (transform));
+
+ CGContextSetAlpha (context, state->colour.getFloatAlpha());
+ CGContextDrawImage (context, CGRectMake (0, 0, sourceImage.getWidth(),
+ sourceImage.getHeight()), image);
+
+ CGImageRelease (image);
+ CGContextRestoreGState (context);
+ }
+
+ void drawLine (double x1, double y1, double x2, double y2)
+ {
+ CGContextSetLineCap (context, kCGLineCapSquare);
+ CGContextSetLineWidth (context, 1.0f);
+ CGContextSetRGBStrokeColor (context,
+ state->colour.getFloatRed(), state->colour.getFloatGreen(),
+ state->colour.getFloatBlue(), state->colour.getFloatAlpha());
+
+ CGPoint line[] = { { x1 + 0.5f, flipHeight - (y1 + 0.5f) },
+ { x2 + 0.5f, flipHeight - (y2 + 0.5f) } };
+
+ CGContextStrokeLineSegments (context, line, 1);
+ }
+
+ void drawVerticalLine (const int x, double top, double bottom)
+ {
+ CGContextFillRect (context, CGRectMake (x, flipHeight - bottom, 1.0f, bottom - top));
+ }
+
+ void drawHorizontalLine (const int y, double left, double right)
+ {
+ CGContextFillRect (context, CGRectMake (left, y, right - left, 1.0f));
+ }
+
+ void setFont (const Font& newFont)
+ {
+ if (state->font != newFont)
+ {
+ state->fontRef = 0;
+ state->font = newFont;
+
+ MacTypeface* mf = dynamic_cast ((Typeface*) state->font.getTypeface());
+
+ if (mf != 0)
+ {
+ state->fontRef = mf->fontRef;
+ CGContextSetFont (context, state->fontRef);
+ CGContextSetFontSize (context, state->font.getHeight() * mf->fontHeightToCGSizeFactor);
+
+ state->fontTransform = mf->renderingTransform;
+ state->fontTransform.a *= state->font.getHorizontalScale();
+ CGContextSetTextMatrix (context, state->fontTransform);
+ }
+ }
+ }
+
+ void drawGlyph (int glyphNumber, float x, float y)
+ {
+ if (state->fontRef != 0 && state->gradient == 0)
+ {
+ CGGlyph g = glyphNumber;
+ CGContextShowGlyphsAtPoint (context, x, flipHeight - roundFloatToInt (y), &g, 1);
+ }
+ else
+ {
+ state->font.renderGlyphIndirectly (*this, glyphNumber, x, y);
+ }
+ }
+
+ void drawGlyph (int glyphNumber, const AffineTransform& transform)
+ {
+ if (state->fontRef != 0)
+ {
+ CGContextSaveGState (context);
+ flip();
+ applyTransform (transform);
+
+ CGAffineTransform t = state->fontTransform;
+ t.d = -t.d;
+ CGContextSetTextMatrix (context, t);
+
+ CGGlyph g = glyphNumber;
+ CGContextShowGlyphsAtPoint (context, 0, 0, &g, 1);
+
+ CGContextSetTextMatrix (context, state->fontTransform);
+ CGContextRestoreGState (context);
+ }
+ else
+ {
+ state->font.renderGlyphIndirectly (*this, glyphNumber, transform);
+ }
+ }
+
+private:
+ CGContextRef context;
+ const float flipHeight;
+ CGColorSpaceRef rgbColourSpace, greyColourSpace;
+ CGFunctionCallbacks gradientCallbacks;
+
+ struct SavedState
+ {
+ SavedState() throw()
+ : gradient (0), font (1.0f), fontRef (0),
+ fontTransform (CGAffineTransformIdentity)
+ {
+ }
+
+ SavedState (const SavedState& other) throw()
+ : colour (other.colour),
+ gradient (other.gradient != 0 ? new ColourGradient (*other.gradient) : 0),
+ font (other.font), fontRef (other.fontRef),
+ fontTransform (other.fontTransform)
+ {
+ }
+
+ ~SavedState() throw()
+ {
+ delete gradient;
+ }
+
+ Colour colour;
+ ColourGradient* gradient;
+ Font font;
+ CGFontRef fontRef;
+ CGAffineTransform fontTransform;
+ };
+
+ SavedState* state;
+ OwnedArray stateStack;
+
+#if ! CGFLOAT_DEFINED
+ #define CGFloat float
+#endif
+
+ static void gradientCallback (void* info, const CGFloat* inData, CGFloat* outData)
+ {
+ const ColourGradient* const g = (const ColourGradient*) info;
+ const Colour c (g->getColourAtPosition (inData[0]));
+ outData[0] = c.getFloatRed();
+ outData[1] = c.getFloatGreen();
+ outData[2] = c.getFloatBlue();
+ outData[3] = c.getFloatAlpha();
+ }
+
+ CGShadingRef createGradient (const ColourGradient* const gradient) const throw()
+ {
+ CGShadingRef result = 0;
+ CGFunctionRef function = CGFunctionCreate ((void*) gradient, 1, 0, 4, 0, &gradientCallbacks);
+ CGPoint p1 (CGPointMake (gradient->x1, gradient->y1));
+
+ if (gradient->isRadial)
+ {
+ result = CGShadingCreateRadial (rgbColourSpace, p1, 0,
+ p1, hypotf (gradient->x1 - gradient->x2, gradient->y1 - gradient->y2),
+ function, true, true);
+ }
+ else
+ {
+ result = CGShadingCreateAxial (rgbColourSpace, p1,
+ CGPointMake (gradient->x2, gradient->y2),
+ function, true, true);
+ }
+
+ CGFunctionRelease (function);
+ return result;
+ }
+
+ void drawGradient() const throw()
+ {
+ CGContextSetAlpha (context, 1.0f);
+ CGShadingRef shading = createGradient (state->gradient);
+ CGContextDrawShading (context, shading);
+ CGShadingRelease (shading);
+ }
+
+ void createPath (const Path& path) const throw()
+ {
+ CGContextBeginPath (context);
+ Path::Iterator i (path);
+
+ while (i.next())
+ {
+ switch (i.elementType)
+ {
+ case Path::Iterator::startNewSubPath:
+ CGContextMoveToPoint (context, i.x1, i.y1);
+ break;
+ case Path::Iterator::lineTo:
+ CGContextAddLineToPoint (context, i.x1, i.y1);
+ break;
+ case Path::Iterator::quadraticTo:
+ CGContextAddQuadCurveToPoint (context, i.x1, i.y1, i.x2, i.y2);
+ break;
+ case Path::Iterator::cubicTo:
+ CGContextAddCurveToPoint (context, i.x1, i.y1, i.x2, i.y2, i.x3, i.y3);
+ break;
+ case Path::Iterator::closePath:
+ CGContextClosePath (context); break;
+ default:
+ jassertfalse
+ break;
+ }
+ }
+ }
+
+ void createPath (const Path& path, const AffineTransform& transform) const throw()
+ {
+ CGContextBeginPath (context);
+ Path::Iterator i (path);
+
+ while (i.next())
+ {
+ switch (i.elementType)
+ {
+ case Path::Iterator::startNewSubPath:
+ transform.transformPoint (i.x1, i.y1);
+ CGContextMoveToPoint (context, i.x1, flipHeight - i.y1);
+ break;
+ case Path::Iterator::lineTo:
+ transform.transformPoint (i.x1, i.y1);
+ CGContextAddLineToPoint (context, i.x1, flipHeight - i.y1);
+ break;
+ case Path::Iterator::quadraticTo:
+ transform.transformPoint (i.x1, i.y1);
+ transform.transformPoint (i.x2, i.y2);
+ CGContextAddQuadCurveToPoint (context, i.x1, flipHeight - i.y1, i.x2, flipHeight - i.y2);
+ break;
+ case Path::Iterator::cubicTo:
+ transform.transformPoint (i.x1, i.y1);
+ transform.transformPoint (i.x2, i.y2);
+ transform.transformPoint (i.x3, i.y3);
+ CGContextAddCurveToPoint (context, i.x1, flipHeight - i.y1, i.x2, flipHeight - i.y2, i.x3, flipHeight - i.y3);
+ break;
+ case Path::Iterator::closePath:
+ CGContextClosePath (context); break;
+ default:
+ jassertfalse
+ break;
+ }
+ }
+ }
+
+ CGImageRef createImage (const Image& juceImage, const bool forAlpha) const throw()
+ {
+ const CoreGraphicsImage* nativeImage = dynamic_cast (&juceImage);
+
+ if (nativeImage != 0 && (juceImage.getFormat() == Image::SingleChannel || ! forAlpha))
+ {
+ return CGBitmapContextCreateImage (nativeImage->context);
+ }
+ else
+ {
+ int lineStride = 0;
+ int pixelStride = 0;
+ const uint8* imageData = juceImage.lockPixelDataReadOnly (0, 0, juceImage.getWidth(), juceImage.getHeight(),
+ lineStride, pixelStride);
+
+ CGDataProviderRef provider = CGDataProviderCreateWithData (0, imageData, lineStride * pixelStride, 0);
+
+ CGColorSpaceRef colourSpace = forAlpha ? greyColourSpace : rgbColourSpace;
+
+ CGImageRef imageRef = CGImageCreate (juceImage.getWidth(), juceImage.getHeight(),
+ 8, pixelStride * 8, lineStride,
+ colourSpace,
+ (juceImage.hasAlphaChannel() && ! forAlpha)
+ ? (kCGImageAlphaPremultipliedFirst | kCGBitmapByteOrder32Little)
+ : kCGBitmapByteOrderDefault,
+ provider,
+ 0, true, kCGRenderingIntentDefault);
+
+ CGDataProviderRelease (provider);
+
+ juceImage.releasePixelDataReadOnly (imageData);
+ return imageRef;
+ }
+ }
+
+ static Image* createAlphaChannelImage (const Image& im) throw()
+ {
+ if (im.getFormat() == Image::SingleChannel)
+ return const_cast (&im);
+
+ return im.createCopyOfAlphaChannel();
+ }
+
+ static void deleteAlphaChannelImage (const Image& im, Image* const alphaIm) throw()
+ {
+ if (im.getFormat() != Image::SingleChannel)
+ delete alphaIm;
+ }
+
+ void flip() const throw()
+ {
+ CGContextConcatCTM (context, CGAffineTransformMake (1, 0, 0, -1, 0, flipHeight));
+ }
+
+ void applyTransform (const AffineTransform& transform) const throw()
+ {
+ CGAffineTransform t;
+ t.a = transform.mat00;
+ t.b = transform.mat10;
+ t.c = transform.mat01;
+ t.d = transform.mat11;
+ t.tx = transform.mat02;
+ t.ty = transform.mat12;
+ CGContextConcatCTM (context, t);
+ }
+
+ float flipY (float y) const throw()
+ {
+ return flipHeight - y;
+ }
+};
+
+LowLevelGraphicsContext* CoreGraphicsImage::createLowLevelContext()
+{
+ return new CoreGraphicsContext (context, imageHeight);
+}
+
+#endif
+/********* End of inlined file: juce_mac_CoreGraphicsContext.mm *********/
+
/********* Start of inlined file: juce_iphone_UIViewComponentPeer.mm *********/
// (This file gets included by juce_mac_NativeCode.mm, rather than being
// compiled on its own).
@@ -262492,6 +263382,8 @@ END_JUCE_NAMESPACE
- (BOOL) resignFirstResponder;
- (BOOL) canBecomeFirstResponder;
+- (void) asyncRepaint: (id) rect;
+
@end
#define JuceUIWindow MakeObjCClassName(JuceUIWindow)
@@ -262615,8 +263507,13 @@ static int getModifierForButtonNumber (const int num) throw()
static int64 getMouseTime (UIEvent* e) { return (int64) [e timestamp] * 1000.0; }
+int juce_lastMouseX = 0, juce_lastMouseY = 0;
+
- (void) touchesBegan: (NSSet*) touches withEvent: (UIEvent*) event
{
+ if (owner == 0)
+ return;
+
NSArray* const t = [[event touchesForView: self] allObjects];
switch ([t count])
@@ -262626,7 +263523,15 @@ static int64 getMouseTime (UIEvent* e) { return (int64) [e timestamp] * 1000.0;
CGPoint p = [[t objectAtIndex: 0] locationInView: self];
currentModifiers |= getModifierForButtonNumber (0);
- owner->handleMouseDown (p.x, p.y, getMouseTime (event));
+ int x, y, w, h;
+ owner->getBounds (x, y, w, h, true);
+ juce_lastMouseX = p.x + x;
+ juce_lastMouseY = p.y + y;
+
+ owner->handleMouseMove (p.x, p.y, getMouseTime (event));
+
+ if (owner != 0)
+ owner->handleMouseDown (p.x, p.y, getMouseTime (event));
}
default:
@@ -262637,6 +263542,9 @@ static int64 getMouseTime (UIEvent* e) { return (int64) [e timestamp] * 1000.0;
- (void) touchesMoved: (NSSet*) touches withEvent: (UIEvent*) event
{
+ if (owner == 0)
+ return;
+
NSArray* const t = [[event touchesForView: self] allObjects];
switch ([t count])
@@ -262644,6 +263552,12 @@ static int64 getMouseTime (UIEvent* e) { return (int64) [e timestamp] * 1000.0;
case 1: // One finger..
{
CGPoint p = [[t objectAtIndex: 0] locationInView: self];
+
+ int x, y, w, h;
+ owner->getBounds (x, y, w, h, true);
+ juce_lastMouseX = p.x + x;
+ juce_lastMouseY = p.y + y;
+
owner->handleMouseDrag (p.x, p.y, getMouseTime (event));
}
@@ -262655,6 +263569,9 @@ static int64 getMouseTime (UIEvent* e) { return (int64) [e timestamp] * 1000.0;
- (void) touchesEnded: (NSSet*) touches withEvent: (UIEvent*) event
{
+ if (owner == 0)
+ return;
+
NSArray* const t = [[event touchesForView: self] allObjects];
switch ([t count])
@@ -262662,6 +263579,12 @@ static int64 getMouseTime (UIEvent* e) { return (int64) [e timestamp] * 1000.0;
case 1: // One finger..
{
CGPoint p = [[t objectAtIndex: 0] locationInView: self];
+
+ int x, y, w, h;
+ owner->getBounds (x, y, w, h, true);
+ juce_lastMouseX = p.x + x;
+ juce_lastMouseY = p.y + y;
+
const int oldMods = currentModifiers;
currentModifiers &= ~getModifierForButtonNumber (0);
owner->handleMouseUp (oldMods, p.x, p.y, getMouseTime (event));
@@ -262699,6 +263622,12 @@ static int64 getMouseTime (UIEvent* e) { return (int64) [e timestamp] * 1000.0;
return owner != 0 && owner->canBecomeKeyWindow();
}
+- (void) asyncRepaint: (id) rect
+{
+ CGRect* r = (CGRect*) [((NSData*) rect) bytes];
+ [self setNeedsDisplayInRect: *r];
+}
+
@end
@implementation JuceUIWindow
@@ -262721,118 +263650,6 @@ static int64 getMouseTime (UIEvent* e) { return (int64) [e timestamp] * 1000.0;
BEGIN_JUCE_NAMESPACE
-class JuceUIImage
-{
-public:
- JuceUIImage (const int width, const int height, const bool hasAlpha)
- : juceImage (hasAlpha ? Image::ARGB : Image::RGB,
- width, height, hasAlpha)
- {
- lineStride = 0;
- pixelStride = 0;
- imageData = juceImage.lockPixelDataReadWrite (0, 0, width, height,
- lineStride, pixelStride);
-
- CGDataProviderRef provider = CGDataProviderCreateWithData (0, imageData, lineStride * pixelStride, 0);
- CGColorSpaceRef colourSpace = CGColorSpaceCreateDeviceRGB();
-
- CGImageRef imageRef = CGImageCreate (width, height,
- 8, pixelStride * 8, lineStride,
- colourSpace,
- hasAlpha ? (kCGImageAlphaFirst | kCGBitmapByteOrder32Little) : kCGBitmapByteOrderDefault,
- provider,
- 0,
- true, kCGRenderingIntentDefault);
-
- CGColorSpaceRelease (colourSpace);
- CGDataProviderRelease (provider);
-
- juceImage.releasePixelDataReadWrite (imageData);
-
- uiImage = [[UIImage imageWithCGImage: imageRef] retain];
- }
-
- ~JuceUIImage()
- {
- [uiImage release];
- CGImageRelease (imageRef);
- }
-
- Image& getJuceImage() throw() { return juceImage; }
-
- void draw (const float x, const float y) const
- {
- [uiImage drawAtPoint: CGPointMake (x, y)
- blendMode: kCGBlendModeCopy
- alpha: 1.0f];
- }
-
- void drawUIImage (UIImage* imageToDraw)
- {
- const ScopedAutoReleasePool pool;
-
- jassertfalse
- /*[NSGraphicsContext saveGraphicsState];
- [NSGraphicsContext setCurrentContext:
- [NSGraphicsContext graphicsContextWithBitmapImageRep: imageRep]];
-
- [imageToDraw drawAtPoint: NSZeroPoint
- fromRect: NSMakeRect (0, 0, [imageToDraw size].width, [imageToDraw size].height)
- operation: NSCompositeSourceOver
- fraction: 1.0f];
-
- [[NSGraphicsContext currentContext] flushGraphics];
- [NSGraphicsContext restoreGraphicsState];
-
- if (juceImage.hasAlphaChannel())
- swapRGBOrder (0, 0, juceImage.getWidth(), juceImage.getHeight());*/
-
- }
-
-private:
- Image juceImage;
- CGImageRef imageRef;
- CGDataProviderRef provider;
- UIImage* uiImage;
- uint8* imageData;
- int pixelStride, lineStride;
-
-/* void swapRGBOrder (const int x, const int y, const int w, int h) const
- {
-#if JUCE_BIG_ENDIAN
- jassert (pixelStride == 4);
-#endif
- jassert (Rectangle (0, 0, juceImage.getWidth(), juceImage.getHeight())
- .contains (Rectangle (x, y, w, h)));
-
- uint8* start = imageData + x * pixelStride + y * lineStride;
-
- while (--h >= 0)
- {
- uint8* p = start;
- start += lineStride;
-
- for (int i = w; --i >= 0;)
- {
-#if JUCE_BIG_ENDIAN
- const uint8 oldp3 = p[3];
- const uint8 oldp1 = p[1];
- p[3] = p[0];
- p[0] = oldp1;
- p[1] = p[2];
- p[2] = oldp3;
-#else
- const uint8 oldp0 = p[0];
- p[0] = p[2];
- p[2] = oldp0;
-#endif
-
- p += pixelStride;
- }
- }
- }*/
-};
-
UIViewComponentPeer::UIViewComponentPeer (Component* const component,
const int windowStyleFlags,
UIView* viewToAttachTo)
@@ -262865,6 +263682,12 @@ UIViewComponentPeer::UIViewComponentPeer (Component* const component,
window = [[JuceUIWindow alloc] init];
window.frame = r;
+
+ window.opaque = component->isOpaque();
+ view.opaque = component->isOpaque();
+ window.backgroundColor = [[UIColor blackColor] colorWithAlphaComponent: 0];
+ view.backgroundColor = [[UIColor blackColor] colorWithAlphaComponent: 0];
+
[((JuceUIWindow*) window) setOwner: this];
if (component->isAlwaysOnTop())
@@ -262872,6 +263695,9 @@ UIViewComponentPeer::UIViewComponentPeer (Component* const component,
[window addSubview: view];
view.frame = CGRectMake (0, 0, r.size.width, r.size.height);
+
+ view.hidden = ! component->isVisible();
+ window.hidden = ! component->isVisible();
}
setTitle (component->getName());
@@ -262898,6 +263724,9 @@ void* UIViewComponentPeer::getNativeHandle() const
void UIViewComponentPeer::setVisible (bool shouldBeVisible)
{
view.hidden = ! shouldBeVisible;
+
+ if (! isSharedWindow)
+ window.hidden = ! shouldBeVisible;
}
void UIViewComponentPeer::setTitle (const String& title)
@@ -262939,8 +263768,6 @@ void UIViewComponentPeer::setBounds (int x, int y, int w, int h, const bool isNo
}
else
{
- //r.origin.y = [[UIScreen mainScreen] bounds].size.height - (r.origin.y + r.size.height);
-
window.frame = r;
view.frame = CGRectMake (0, 0, r.size.width, r.size.height);
}
@@ -262956,15 +263783,10 @@ void UIViewComponentPeer::getBounds (int& x, int& y, int& w, int& h, const bool
CGRect wr = [[view window] frame];
r.origin.x += wr.origin.x;
r.origin.y += wr.origin.y;
-
- y = (int) ([[UIScreen mainScreen] bounds].size.height - r.origin.y - r.size.height);
- }
- else
- {
- y = (int) ([[view superview] frame].size.height - r.origin.y - r.size.height);
}
x = (int) r.origin.x;
+ y = (int) r.origin.y;
w = (int) r.size.width;
h = (int) r.size.height;
}
@@ -263213,23 +264035,14 @@ void UIViewComponentPeer::drawRect (CGRect r)
if (r.size.width < 1.0f || r.size.height < 1.0f)
return;
- DBG (Rectangle (r.origin.x, r.origin.y, r.size.width, r.size.height).toString());
+ CGContextRef cg = UIGraphicsGetCurrentContext();
- const float y = r.origin.y;//[view frame].size.height - (r.origin.y + r.size.height);
+ if (! component->isOpaque())
+ CGContextClearRect (cg, CGContextGetClipBoundingBox (cg));
- JuceUIImage temp ((int) (r.size.width + 0.5f),
- (int) (r.size.height + 0.5f),
- true);//! getComponent()->isOpaque());
-
- LowLevelGraphicsSoftwareRenderer context (temp.getJuceImage());
- const int originX = -roundFloatToInt (r.origin.x);
- const int originY = -roundFloatToInt (y);
- context.setOrigin (originX, originY);
-
- handlePaint (context);
-
- //CGContextClipToRect (UIGraphicsGetCurrentContext(), r);
- temp.draw (r.origin.x, r.origin.y);
+ CGContextConcatCTM (cg, CGAffineTransformMake (1, 0, 0, -1, 0, view.bounds.size.height));
+ CoreGraphicsContext g (cg, view.bounds.size.height);
+ handlePaint (g);
}
bool UIViewComponentPeer::canBecomeKeyWindow()
@@ -263257,9 +264070,18 @@ void juce_setKioskComponent (Component* kioskModeComponent, bool enableOrDisable
void UIViewComponentPeer::repaint (int x, int y, int w, int h)
{
- [view setNeedsDisplayInRect:
- CGRectMake ((float) x, (float) y,//([view frame].size.height - (y + h)),
- (float) w, (float) h)];
+ CGRect r = CGRectMake ((float) x, (float) y, (float) w, (float) h);
+
+ if (! MessageManager::getInstance()->isThisTheMessageThread())
+ {
+ [view performSelectorOnMainThread: @selector (asyncRepaint:)
+ withObject: [NSData dataWithBytes: &r length: sizeof (r)]
+ waitUntilDone: NO];
+ }
+ else
+ {
+ [view setNeedsDisplayInRect: r];
+ }
}
void UIViewComponentPeer::performAnyPendingRepaintsNow()
@@ -263271,21 +264093,26 @@ ComponentPeer* Component::createNewPeer (int styleFlags, void* windowToAttachTo)
return new UIViewComponentPeer (this, styleFlags, (UIView*) windowToAttachTo);
}
-static Image* UIImageToJuceImage (UIImage* image)
-{
- JuceUIImage juceIm ((int) [image size].width,
- (int) [image size].height,
- true);
-
- juceIm.drawUIImage (image);
- return juceIm.getJuceImage().createCopy();
-}
-
Image* juce_createIconForFile (const File& file)
{
return 0;
}
+bool Desktop::canUseSemiTransparentWindows() throw()
+{
+ return true;
+}
+
+void Desktop::getMousePosition (int& x, int& y) throw()
+{
+ x = juce_lastMouseX;
+ y = juce_lastMouseY;
+}
+
+void Desktop::setMousePosition (int x, int y) throw()
+{
+}
+
const int KeyPress::spaceKey = ' ';
const int KeyPress::returnKey = 0x0d;
const int KeyPress::escapeKey = 0x1b;
@@ -263538,11 +264365,7 @@ static const int quitMessageId = 0xfffff321;
void MessageManager::stopDispatchLoop()
{
- Message* const m = new Message (quitMessageId, 0, 0, 0);
- m->messageRecipient = 0;
- postMessageToQueue (m);
-
- quitMessagePosted = true;
+ exit (0); // iPhone apps get no mercy..
}
bool MessageManager::runDispatchLoopUntil (int millisecondsToRunFor)
@@ -264867,8 +265690,8 @@ private:
}
else
{
- zeromem (inputChannels[0], sizeof (float) * inNumberFrames);
- zeromem (inputChannels[1], sizeof (float) * inNumberFrames);
+ for (int i = numInputChannels; --i >= 0;)
+ zeromem (inputChannels[i], sizeof (float) * inNumberFrames);
}
callback->audioDeviceIOCallback ((const float**) inputChannels, numInputChannels,
@@ -265097,7 +265920,7 @@ public:
const StringArray getDeviceNames (const bool wantInputNames) const
{
StringArray s;
- s.add (wantInputNames ? "Microphone" : "Speaker");
+ s.add ("iPhone Audio");
return s;
}
@@ -265347,8 +266170,23 @@ static bool makeSureClientExists()
return hasGlobalClientBeenCreated;
}
-struct MidiPortAndEndpoint
+class MidiPortAndEndpoint
{
+public:
+ MidiPortAndEndpoint (MIDIPortRef port, MIDIEndpointRef endpoint) throw()
+ : port (port), endPoint (endpoint)
+ {
+ }
+
+ ~MidiPortAndEndpoint() throw()
+ {
+ if (port != 0)
+ MIDIPortDispose (port);
+
+ if (endPoint != 0)
+ MIDIEndpointDispose (endPoint);
+ }
+
MIDIPortRef port;
MIDIEndpointRef endPoint;
};
@@ -265372,12 +266210,8 @@ MidiOutput* MidiOutput::openDevice (int index)
if (OK (MIDIOutputPortCreate (globalMidiClient, pname, &port)))
{
- MidiPortAndEndpoint* mpe = new MidiPortAndEndpoint();
- mpe->port = port;
- mpe->endPoint = endPoint;
-
mo = new MidiOutput();
- mo->internal = (void*)mpe;
+ mo->internal = (void*) new MidiPortAndEndpoint (port, endPoint);
}
}
@@ -265388,10 +266222,30 @@ MidiOutput* MidiOutput::openDevice (int index)
return mo;
}
+MidiOutput* MidiOutput::createNewDevice (const String& deviceName)
+{
+ MidiOutput* mo = 0;
+
+ if (makeSureClientExists())
+ {
+ MIDIEndpointRef endPoint;
+ CFStringRef name = PlatformUtilities::juceStringToCFString (deviceName);
+
+ if (OK (MIDISourceCreate (globalMidiClient, name, &endPoint)))
+ {
+ mo = new MidiOutput();
+ mo->internal = (void*) new MidiPortAndEndpoint (0, endPoint);
+ }
+
+ CFRelease (name);
+ }
+
+ return mo;
+}
+
MidiOutput::~MidiOutput()
{
- MidiPortAndEndpoint* const mpe = (MidiPortAndEndpoint*)internal;
- MIDIPortDispose (mpe->port);
+ MidiPortAndEndpoint* const mpe = (MidiPortAndEndpoint*) internal;
delete mpe;
}
@@ -265410,7 +266264,7 @@ void MidiOutput::setVolume (float leftVol, float rightVol)
void MidiOutput::sendMessageNow (const MidiMessage& message)
{
- MidiPortAndEndpoint* const mpe = (MidiPortAndEndpoint*)internal;
+ MidiPortAndEndpoint* const mpe = (MidiPortAndEndpoint*) internal;
if (message.isSysEx())
{
@@ -265432,7 +266286,11 @@ void MidiOutput::sendMessageNow (const MidiMessage& message)
p = MIDIPacketNext (p);
}
- MIDISend (mpe->port, mpe->endPoint, packets);
+ if (mpe->port != 0)
+ MIDISend (mpe->port, mpe->endPoint, packets);
+ else
+ MIDIReceived (mpe->endPoint, packets);
+
juce_free (packets);
}
else
@@ -265443,7 +266301,10 @@ void MidiOutput::sendMessageNow (const MidiMessage& message)
packets.packet[0].length = message.getRawDataSize();
*(int*) (packets.packet[0].data) = *(const int*) message.getRawData();
- MIDISend (mpe->port, mpe->endPoint, &packets);
+ if (mpe->port != 0)
+ MIDISend (mpe->port, mpe->endPoint, &packets);
+ else
+ MIDIReceived (mpe->endPoint, &packets);
}
}
@@ -265482,8 +266343,7 @@ int MidiInput::getDefaultDeviceIndex()
struct MidiPortAndCallback
{
MidiInput* input;
- MIDIPortRef port;
- MIDIEndpointRef endPoint;
+ MidiPortAndEndpoint* portAndEndpoint;
MidiInputCallback* callback;
MemoryBlock pendingData;
int pendingBytes;
@@ -265494,26 +266354,26 @@ struct MidiPortAndCallback
static CriticalSection callbackLock;
static VoidArray activeCallbacks;
-static void processSysex (MidiPortAndCallback* const mpe, const uint8*& d, int& size, const double time)
+static void processSysex (MidiPortAndCallback* const mpc, const uint8*& d, int& size, const double time)
{
if (*d == 0xf0)
{
- mpe->pendingBytes = 0;
- mpe->pendingDataTime = time;
+ mpc->pendingBytes = 0;
+ mpc->pendingDataTime = time;
}
- mpe->pendingData.ensureSize (mpe->pendingBytes + size, false);
- uint8* totalMessage = (uint8*) mpe->pendingData.getData();
+ mpc->pendingData.ensureSize (mpc->pendingBytes + size, false);
+ uint8* totalMessage = (uint8*) mpc->pendingData.getData();
- uint8* dest = totalMessage + mpe->pendingBytes;
+ uint8* dest = totalMessage + mpc->pendingBytes;
while (size > 0)
{
- if (mpe->pendingBytes > 0 && *d >= 0x80)
+ if (mpc->pendingBytes > 0 && *d >= 0x80)
{
if (*d >= 0xfa || *d == 0xf8)
{
- mpe->callback->handleIncomingMidiMessage (mpe->input, MidiMessage (*d, time));
+ mpc->callback->handleIncomingMidiMessage (mpc->input, MidiMessage (*d, time));
++d;
--size;
}
@@ -265522,7 +266382,7 @@ static void processSysex (MidiPortAndCallback* const mpe, const uint8*& d, int&
if (*d == 0xf7)
{
*dest++ = *d++;
- mpe->pendingBytes++;
+ mpc->pendingBytes++;
--size;
}
@@ -265532,24 +266392,24 @@ static void processSysex (MidiPortAndCallback* const mpe, const uint8*& d, int&
else
{
*dest++ = *d++;
- mpe->pendingBytes++;
+ mpc->pendingBytes++;
--size;
}
}
- if (totalMessage [mpe->pendingBytes - 1] == 0xf7)
+ if (totalMessage [mpc->pendingBytes - 1] == 0xf7)
{
- mpe->callback->handleIncomingMidiMessage (mpe->input, MidiMessage (totalMessage,
- mpe->pendingBytes,
- mpe->pendingDataTime));
- mpe->pendingBytes = 0;
+ mpc->callback->handleIncomingMidiMessage (mpc->input, MidiMessage (totalMessage,
+ mpc->pendingBytes,
+ mpc->pendingDataTime));
+ mpc->pendingBytes = 0;
}
else
{
- mpe->callback->handlePartialSysexMessage (mpe->input,
+ mpc->callback->handlePartialSysexMessage (mpc->input,
totalMessage,
- mpe->pendingBytes,
- mpe->pendingDataTime);
+ mpc->pendingBytes,
+ mpc->pendingDataTime);
}
}
@@ -265560,10 +266420,10 @@ static void midiInputProc (const MIDIPacketList* pktlist,
double time = Time::getMillisecondCounterHiRes() * 0.001;
const double originalTime = time;
- MidiPortAndCallback* const mpe = (MidiPortAndCallback*) readProcRefCon;
+ MidiPortAndCallback* const mpc = (MidiPortAndCallback*) readProcRefCon;
const ScopedLock sl (callbackLock);
- if (activeCallbacks.contains (mpe) && mpe->active)
+ if (activeCallbacks.contains (mpc) && mpc->active)
{
const MIDIPacket* packet = &pktlist->packet[0];
@@ -265576,9 +266436,9 @@ static void midiInputProc (const MIDIPacketList* pktlist,
{
time = originalTime;
- if (mpe->pendingBytes > 0 || d[0] == 0xf0)
+ if (mpc->pendingBytes > 0 || d[0] == 0xf0)
{
- processSysex (mpe, d, size, time);
+ processSysex (mpc, d, size, time);
}
else
{
@@ -265592,7 +266452,7 @@ static void midiInputProc (const MIDIPacketList* pktlist,
}
else
{
- mpe->callback->handleIncomingMidiMessage (mpe->input, m);
+ mpc->callback->handleIncomingMidiMessage (mpc->input, m);
}
size -= used;
@@ -265625,35 +266485,34 @@ MidiInput* MidiInput::openDevice (int index, MidiInputCallback* callback)
{
MIDIPortRef port;
- MidiPortAndCallback* const mpe = new MidiPortAndCallback();
- mpe->active = false;
+ MidiPortAndCallback* const mpc = new MidiPortAndCallback();
+ mpc->active = false;
- if (OK (MIDIInputPortCreate (globalMidiClient, pname, midiInputProc, mpe, &port)))
+ if (OK (MIDIInputPortCreate (globalMidiClient, pname, midiInputProc, mpc, &port)))
{
if (OK (MIDIPortConnectSource (port, endPoint, 0)))
{
- mpe->port = port;
- mpe->endPoint = endPoint;
- mpe->callback = callback;
- mpe->pendingBytes = 0;
- mpe->pendingData.ensureSize (128);
+ mpc->portAndEndpoint = new MidiPortAndEndpoint (port, endPoint);
+ mpc->callback = callback;
+ mpc->pendingBytes = 0;
+ mpc->pendingData.ensureSize (128);
mi = new MidiInput (getDevices() [index]);
- mpe->input = mi;
- mi->internal = (void*) mpe;
+ mpc->input = mi;
+ mi->internal = (void*) mpc;
const ScopedLock sl (callbackLock);
- activeCallbacks.add (mpe);
+ activeCallbacks.add (mpc);
}
else
{
OK (MIDIPortDispose (port));
- delete mpe;
+ delete mpc;
}
}
else
{
- delete mpe;
+ delete mpc;
}
}
}
@@ -265665,6 +266524,42 @@ MidiInput* MidiInput::openDevice (int index, MidiInputCallback* callback)
return mi;
}
+MidiInput* MidiInput::createNewDevice (const String& deviceName, MidiInputCallback* callback)
+{
+ MidiInput* mi = 0;
+
+ if (makeSureClientExists())
+ {
+ MidiPortAndCallback* const mpc = new MidiPortAndCallback();
+ mpc->active = false;
+
+ MIDIEndpointRef endPoint;
+ CFStringRef name = PlatformUtilities::juceStringToCFString(deviceName);
+ if (OK (MIDIDestinationCreate (globalMidiClient, name, midiInputProc, mpc, &endPoint)))
+ {
+ mpc->portAndEndpoint = new MidiPortAndEndpoint (0, endPoint);
+ mpc->callback = callback;
+ mpc->pendingBytes = 0;
+ mpc->pendingData.ensureSize (128);
+
+ mi = new MidiInput (deviceName);
+ mpc->input = mi;
+ mi->internal = (void*) mpc;
+
+ const ScopedLock sl (callbackLock);
+ activeCallbacks.add (mpc);
+ }
+ else
+ {
+ delete mpc;
+ }
+
+ CFRelease (name);
+ }
+
+ return mi;
+}
+
MidiInput::MidiInput (const String& name_)
: name (name_)
{
@@ -265672,30 +266567,32 @@ MidiInput::MidiInput (const String& name_)
MidiInput::~MidiInput()
{
- MidiPortAndCallback* const mpe = (MidiPortAndCallback*) internal;
- mpe->active = false;
+ MidiPortAndCallback* const mpc = (MidiPortAndCallback*) internal;
+ mpc->active = false;
callbackLock.enter();
- activeCallbacks.removeValue (mpe);
+ activeCallbacks.removeValue (mpc);
callbackLock.exit();
- OK (MIDIPortDisconnectSource (mpe->port, mpe->endPoint));
- OK (MIDIPortDispose (mpe->port));
- delete mpe;
+ if (mpc->portAndEndpoint->port != 0)
+ OK (MIDIPortDisconnectSource (mpc->portAndEndpoint->port, mpc->portAndEndpoint->endPoint));
+
+ delete mpc->portAndEndpoint;
+ delete mpc;
}
void MidiInput::start()
{
- MidiPortAndCallback* const mpe = (MidiPortAndCallback*) internal;
+ MidiPortAndCallback* const mpc = (MidiPortAndCallback*) internal;
const ScopedLock sl (callbackLock);
- mpe->active = true;
+ mpc->active = true;
}
void MidiInput::stop()
{
- MidiPortAndCallback* const mpe = (MidiPortAndCallback*) internal;
+ MidiPortAndCallback* const mpc = (MidiPortAndCallback*) internal;
const ScopedLock sl (callbackLock);
- mpe->active = false;
+ mpc->active = false;
}
#undef log
@@ -265759,6 +266656,10 @@ MidiInput* MidiInput::openDevice (int index, MidiInputCallback* callback)
#define SUPPORT_10_4_FONTS 1
#define NEW_CGFONT_FUNCTIONS_UNAVAILABLE (CGFontCreateWithFontName == 0)
+ #if MAC_OS_X_VERSION_MAX_ALLOWED < MAC_OS_X_VERSION_10_5
+ #define SUPPORT_ONLY_10_4_FONTS 1
+ #endif
+
END_JUCE_NAMESPACE
@interface NSFont (PrivateHack)
- (NSGlyph) _defaultGlyphForChar: (unichar) theChar;
@@ -265771,8 +266672,10 @@ class MacTypeface : public Typeface
public:
MacTypeface (const Font& font)
- : Typeface (font.getTypefaceName()),
- charToGlyphMapper (0)
+ : Typeface (font.getTypefaceName())
+#if ! SUPPORT_ONLY_10_4_FONTS
+ , charToGlyphMapper (0)
+#endif
{
const ScopedAutoReleasePool pool;
renderingTransform = CGAffineTransformIdentity;
@@ -265817,9 +266720,11 @@ public:
fontRef = CGFontCreateWithFontName ((CFStringRef) fontName);
- const int totalHeight = abs (CGFontGetAscent (fontRef)) + abs (CGFontGetDescent (fontRef));
+ const int ascender = abs (CGFontGetAscent (fontRef));
+ const float totalHeight = ascender + abs (CGFontGetDescent (fontRef));
+ ascent = ascender / totalHeight;
unitsToHeightScaleFactor = 1.0f / totalHeight;
- fontHeightToCGSizeFactor = CGFontGetUnitsPerEm (fontRef) / (float) totalHeight;
+ fontHeightToCGSizeFactor = CGFontGetUnitsPerEm (fontRef) / totalHeight;
#else
nsFont = [NSFont fontWithName: juceStringToNS (font.getTypefaceName()) size: 1024];
@@ -265851,7 +266756,19 @@ public:
renderingTransform.c = 0.15f;
}
-#if SUPPORT_10_4_FONTS
+#if SUPPORT_ONLY_10_4_FONTS
+ ATSFontRef atsFont = ATSFontFindFromName ((CFStringRef) [nsFont fontName], kATSOptionFlagsDefault);
+
+ if (atsFont == 0)
+ atsFont = ATSFontFindFromPostScriptName ((CFStringRef) [nsFont fontName], kATSOptionFlagsDefault);
+
+ fontRef = CGFontCreateWithPlatformFont ((void*) &atsFont);
+
+ const float totalHeight = fabsf ([nsFont ascender]) + fabsf([nsFont descender]);
+ unitsToHeightScaleFactor = 1.0f / totalHeight;
+ fontHeightToCGSizeFactor = 1024.0f / totalHeight;
+#else
+ #if SUPPORT_10_4_FONTS
if (NEW_CGFONT_FUNCTIONS_UNAVAILABLE)
{
ATSFontRef atsFont = ATSFontFindFromName ((CFStringRef) [nsFont fontName], kATSOptionFlagsDefault);
@@ -265866,7 +266783,7 @@ public:
fontHeightToCGSizeFactor = 1024.0f / totalHeight;
}
else
-#endif
+ #endif
{
fontRef = CGFontCreateWithFontName ((CFStringRef) [nsFont fontName]);
@@ -265874,18 +266791,22 @@ public:
unitsToHeightScaleFactor = 1.0f / totalHeight;
fontHeightToCGSizeFactor = CGFontGetUnitsPerEm (fontRef) / (float) totalHeight;
}
+#endif
#endif
}
~MacTypeface()
{
+#if ! JUCE_IPHONE
[nsFont release];
-
+#endif
if (fontRef != 0)
CGFontRelease (fontRef);
+#if ! SUPPORT_ONLY_10_4_FONTS
delete charToGlyphMapper;
+#endif
}
float getAscent() const
@@ -265908,7 +266829,16 @@ public:
int x = 0;
-#if SUPPORT_10_4_FONTS
+#if SUPPORT_ONLY_10_4_FONTS
+ NSSize* const advances = (NSSize*) juce_malloc (length * sizeof (NSSize));
+ [nsFont getAdvancements: advances forGlyphs: (NSGlyph*) glyphs count: length];
+
+ for (int i = 0; i < length; ++i)
+ x += advances[i].width;
+
+ juce_free (advances);
+#else
+ #if SUPPORT_10_4_FONTS
if (NEW_CGFONT_FUNCTIONS_UNAVAILABLE)
{
NSSize* const advances = (NSSize*) juce_malloc (length * sizeof (NSSize));
@@ -265920,7 +266850,7 @@ public:
juce_free (advances);
}
else
-#endif
+ #endif
{
int* const advances = (int*) juce_malloc (length * sizeof (int));
@@ -265930,6 +266860,7 @@ public:
juce_free (advances);
}
+#endif
juce_free (glyphs);
@@ -265946,7 +266877,21 @@ public:
const int length = text.length();
CGGlyph* const glyphs = createGlyphsForString (text, length);
-#if SUPPORT_10_4_FONTS
+#if SUPPORT_ONLY_10_4_FONTS
+ NSSize* const advances = (NSSize*) juce_malloc (length * sizeof (NSSize));
+ [nsFont getAdvancements: advances forGlyphs: (NSGlyph*) glyphs count: length];
+
+ int x = 0;
+ for (int i = 0; i < length; ++i)
+ {
+ x += advances[i].width;
+ xOffsets.add (x * unitsToHeightScaleFactor);
+ resultGlyphs.add (((NSGlyph*) glyphs)[i]);
+ }
+
+ juce_free (advances);
+#else
+ #if SUPPORT_10_4_FONTS
if (NEW_CGFONT_FUNCTIONS_UNAVAILABLE)
{
NSSize* const advances = (NSSize*) juce_malloc (length * sizeof (NSSize));
@@ -265963,7 +266908,7 @@ public:
juce_free (advances);
}
else
-#endif
+ #endif
{
int* const advances = (int*) juce_malloc (length * sizeof (int));
@@ -265980,6 +266925,7 @@ public:
juce_free (advances);
}
+#endif
juce_free (glyphs);
}
@@ -266049,7 +266995,9 @@ private:
CGGlyph* createGlyphsForString (const juce_wchar* const text, const int length) throw()
{
#if SUPPORT_10_4_FONTS
+ #if ! SUPPORT_ONLY_10_4_FONTS
if (NEW_CGFONT_FUNCTIONS_UNAVAILABLE)
+ #endif
{
NSGlyph* const g = (NSGlyph*) juce_malloc (sizeof (NSGlyph) * length);
@@ -266059,6 +267007,8 @@ private:
return (CGGlyph*) g;
}
#endif
+
+#if ! SUPPORT_ONLY_10_4_FONTS
if (charToGlyphMapper == 0)
charToGlyphMapper = new CharToGlyphMapper (fontRef);
@@ -266068,8 +267018,10 @@ private:
g[i] = (CGGlyph) charToGlyphMapper->getGlyphForCharacter (text[i]);
return g;
+#endif
}
+#if ! SUPPORT_ONLY_10_4_FONTS
// Reads a CGFontRef's character map table to convert unicode into glyph numbers
class CharToGlyphMapper
{
@@ -266168,6 +267120,7 @@ private:
};
CharToGlyphMapper* charToGlyphMapper;
+#endif
};
const Typeface::Ptr Typeface::createSystemTypefaceFor (const Font& font)
@@ -266196,9 +267149,15 @@ const StringArray Font::findAllTypefaceNames() throw()
void Font::getPlatformDefaultFontNames (String& defaultSans, String& defaultSerif, String& defaultFixed) throw()
{
+#if JUCE_IPHONE
+ defaultSans = "Helvetica";
+ defaultSerif = "Times New Roman";
+ defaultFixed = "Courier New";
+#else
defaultSans = "Lucida Grande";
defaultSerif = "Times New Roman";
defaultFixed = "Monaco";
+#endif
}
#endif
@@ -266211,6 +267170,41 @@ void Font::getPlatformDefaultFontNames (String& defaultSans, String& defaultSeri
// compiled on its own).
#if JUCE_INCLUDED_FILE
+class CoreGraphicsImage : public Image
+{
+public:
+ CoreGraphicsImage (const PixelFormat format,
+ const int imageWidth,
+ const int imageHeight,
+ const bool clearImage)
+ : Image (format, imageWidth, imageHeight, clearImage)
+ {
+ CGColorSpaceRef colourSpace = format == Image::SingleChannel ? CGColorSpaceCreateDeviceGray()
+ : CGColorSpaceCreateDeviceRGB();
+
+ context = CGBitmapContextCreate (imageData, imageWidth, imageHeight, 8, lineStride,
+ colourSpace,
+ format == Image::ARGB ? (kCGImageAlphaPremultipliedFirst | kCGBitmapByteOrder32Little)
+ : kCGBitmapByteOrderDefault);
+
+ CGColorSpaceRelease (colourSpace);
+ }
+
+ ~CoreGraphicsImage()
+ {
+ CGContextRelease (context);
+ }
+
+ LowLevelGraphicsContext* createLowLevelContext();
+
+ CGContextRef context;
+};
+
+Image* Image::createNativeImage (const PixelFormat format, const int imageWidth, const int imageHeight, const bool clearImage)
+{
+ return new CoreGraphicsImage (format == RGB ? ARGB : format, imageWidth, imageHeight, clearImage);
+}
+
class CoreGraphicsContext : public LowLevelGraphicsContext
{
public:
@@ -266221,12 +267215,19 @@ public:
CGContextRetain (context);
CGContextSetShouldSmoothFonts (context, true);
CGContextSetBlendMode (context, kCGBlendModeNormal);
+ rgbColourSpace = CGColorSpaceCreateDeviceRGB();
+ greyColourSpace = CGColorSpaceCreateDeviceGray();
+ gradientCallbacks.version = 0;
+ gradientCallbacks.evaluate = gradientCallback;
+ gradientCallbacks.releaseInfo = 0;
state = new SavedState();
}
~CoreGraphicsContext()
{
CGContextRelease (context);
+ CGColorSpaceRelease (rgbColourSpace);
+ CGColorSpaceRelease (greyColourSpace);
delete state;
}
@@ -266345,7 +267346,17 @@ public:
{
if (replaceExistingContents)
{
- CGContextSetBlendMode (context, kCGBlendModeCopy);
+#if MAC_OS_X_VERSION_MAX_ALLOWED < MAC_OS_X_VERSION_10_5
+ CGContextClearRect (context, CGRectMake (x, y, w, h));
+#else
+ #if MAC_OS_X_VERSION_MIN_REQUIRED < MAC_OS_X_VERSION_10_5
+ if (CGContextDrawLinearGradient == 0) // (just a way of checking whether we're running in 10.5 or later)
+ CGContextClearRect (context, CGRectMake (x, y, w, h));
+ else
+ #endif
+ CGContextSetBlendMode (context, kCGBlendModeCopy);
+#endif
+
fillRect (x, y, w, h, false);
CGContextSetBlendMode (context, kCGBlendModeNormal);
}
@@ -266529,7 +267540,7 @@ public:
void drawGlyph (int glyphNumber, float x, float y)
{
- if (state->fontRef != 0)
+ if (state->fontRef != 0 && state->gradient == 0)
{
CGGlyph g = glyphNumber;
CGContextShowGlyphsAtPoint (context, x, flipHeight - roundFloatToInt (y), &g, 1);
@@ -266567,6 +267578,8 @@ public:
private:
CGContextRef context;
const float flipHeight;
+ CGColorSpaceRef rgbColourSpace, greyColourSpace;
+ CGFunctionCallbacks gradientCallbacks;
struct SavedState
{
@@ -266599,6 +267612,10 @@ private:
SavedState* state;
OwnedArray stateStack;
+#if ! CGFLOAT_DEFINED
+ #define CGFloat float
+#endif
+
static void gradientCallback (void* info, const CGFloat* inData, CGFloat* outData)
{
const ColourGradient* const g = (const ColourGradient*) info;
@@ -266609,30 +267626,25 @@ private:
outData[3] = c.getFloatAlpha();
}
- static CGShadingRef createGradient (const ColourGradient* const gradient) throw()
+ CGShadingRef createGradient (const ColourGradient* const gradient) const throw()
{
CGShadingRef result = 0;
- CGColorSpaceRef colourSpace = CGColorSpaceCreateDeviceRGB();
-
- CGFunctionCallbacks callbacks = { 0, gradientCallback, 0 };
- CGFunctionRef function = CGFunctionCreate ((void*) gradient, 1, 0, 4, 0, &callbacks);
- CGPoint p1 = CGPointMake (gradient->x1, gradient->y1);
+ CGFunctionRef function = CGFunctionCreate ((void*) gradient, 1, 0, 4, 0, &gradientCallbacks);
+ CGPoint p1 (CGPointMake (gradient->x1, gradient->y1));
if (gradient->isRadial)
{
- result = CGShadingCreateRadial (colourSpace,
- p1, 0,
+ result = CGShadingCreateRadial (rgbColourSpace, p1, 0,
p1, hypotf (gradient->x1 - gradient->x2, gradient->y1 - gradient->y2),
function, true, true);
}
else
{
- result = CGShadingCreateAxial (colourSpace, p1,
+ result = CGShadingCreateAxial (rgbColourSpace, p1,
CGPointMake (gradient->x2, gradient->y2),
function, true, true);
}
- CGColorSpaceRelease (colourSpace);
CGFunctionRelease (function);
return result;
}
@@ -266714,30 +267726,37 @@ private:
CGImageRef createImage (const Image& juceImage, const bool forAlpha) const throw()
{
- int lineStride = 0;
- int pixelStride = 0;
- const uint8* imageData = juceImage.lockPixelDataReadOnly (0, 0, juceImage.getWidth(), juceImage.getHeight(),
- lineStride, pixelStride);
+ const CoreGraphicsImage* nativeImage = dynamic_cast (&juceImage);
- CGDataProviderRef provider = CGDataProviderCreateWithData (0, imageData, lineStride * pixelStride, 0);
+ if (nativeImage != 0 && (juceImage.getFormat() == Image::SingleChannel || ! forAlpha))
+ {
+ return CGBitmapContextCreateImage (nativeImage->context);
+ }
+ else
+ {
+ int lineStride = 0;
+ int pixelStride = 0;
+ const uint8* imageData = juceImage.lockPixelDataReadOnly (0, 0, juceImage.getWidth(), juceImage.getHeight(),
+ lineStride, pixelStride);
- CGColorSpaceRef colourSpace = forAlpha ? CGColorSpaceCreateDeviceGray()
- : CGColorSpaceCreateDeviceRGB();
+ CGDataProviderRef provider = CGDataProviderCreateWithData (0, imageData, lineStride * pixelStride, 0);
- CGImageRef imageRef = CGImageCreate (juceImage.getWidth(), juceImage.getHeight(),
- 8, pixelStride * 8, lineStride,
- colourSpace,
- (juceImage.hasAlphaChannel() && ! forAlpha)
- ? (kCGImageAlphaPremultipliedFirst | kCGBitmapByteOrder32Little)
- : kCGBitmapByteOrderDefault,
- provider,
- 0, true, kCGRenderingIntentDefault);
+ CGColorSpaceRef colourSpace = forAlpha ? greyColourSpace : rgbColourSpace;
- CGColorSpaceRelease (colourSpace);
- CGDataProviderRelease (provider);
+ CGImageRef imageRef = CGImageCreate (juceImage.getWidth(), juceImage.getHeight(),
+ 8, pixelStride * 8, lineStride,
+ colourSpace,
+ (juceImage.hasAlphaChannel() && ! forAlpha)
+ ? (kCGImageAlphaPremultipliedFirst | kCGBitmapByteOrder32Little)
+ : kCGBitmapByteOrderDefault,
+ provider,
+ 0, true, kCGRenderingIntentDefault);
- juceImage.releasePixelDataReadOnly (imageData);
- return imageRef;
+ CGDataProviderRelease (provider);
+
+ juceImage.releasePixelDataReadOnly (imageData);
+ return imageRef;
+ }
}
static Image* createAlphaChannelImage (const Image& im) throw()
@@ -266770,8 +267789,18 @@ private:
t.ty = transform.mat12;
CGContextConcatCTM (context, t);
}
+
+ float flipY (float y) const throw()
+ {
+ return flipHeight - y;
+ }
};
+LowLevelGraphicsContext* CoreGraphicsImage::createLowLevelContext()
+{
+ return new CoreGraphicsContext (context, imageHeight);
+}
+
#endif
/********* End of inlined file: juce_mac_CoreGraphicsContext.mm *********/
@@ -269919,6 +270948,12 @@ static QTMovie* openMovieFromStream (InputStream* movieStream, File& movieFile)
return movie;
}
+bool QuickTimeMovieComponent::loadMovie (const File& movieFile_,
+ const bool isControllerVisible)
+{
+ return loadMovie ((InputStream*) movieFile_.createInputStream(), isControllerVisible);
+}
+
bool QuickTimeMovieComponent::loadMovie (InputStream* movieStream,
const bool controllerVisible)
{
@@ -269943,6 +270978,36 @@ bool QuickTimeMovieComponent::loadMovie (InputStream* movieStream,
return movie != nil;
}
+bool QuickTimeMovieComponent::loadMovie (const URL& movieURL,
+ const bool isControllerVisible)
+{
+ // unfortunately, QTMovie objects can only be created on the main thread..
+ jassert (MessageManager::getInstance()->isThisTheMessageThread());
+
+ closeMovie();
+
+ if (getPeer() == 0)
+ {
+ // To open a movie, this component must be visible inside a functioning window, so that
+ // the QT control can be assigned to the window.
+ jassertfalse
+ return false;
+ }
+
+ NSURL* url = [NSURL URLWithString: juceStringToNS (movieURL.toString (true))];
+ NSError* err;
+ if ([QTMovie canInitWithURL: url])
+ movie = [QTMovie movieWithURL: url error: &err];
+
+ [theMovie retain];
+ QTMovieView* view = (QTMovieView*) getView();
+ [view setMovie: theMovie];
+ [view setControllerVisible: controllerVisible];
+ setLooping (looping);
+
+ return movie != nil;
+}
+
void QuickTimeMovieComponent::closeMovie()
{
stop();
@@ -270061,14 +271126,6 @@ bool QuickTimeMovieComponent::isControllerVisible() const
return controllerVisible;
}
-bool QuickTimeMovieComponent::loadMovie (const File& movieFile_,
- const bool isControllerVisible)
-{
- const bool ok = loadMovie ((InputStream*) movieFile_.createInputStream(), isControllerVisible);
- movieFile = movieFile_;
- return ok;
-}
-
void QuickTimeMovieComponent::goToStart()
{
setPosition (0.0);
@@ -271315,7 +272372,7 @@ public:
: inputLatency (0),
outputLatency (0),
callback (0),
-#if ! MACOS_10_4_OR_EARLIER
+#if MAC_OS_X_VERSION_MIN_REQUIRED >= MAC_OS_X_VERSION_10_5
audioProcID (0),
#endif
inputDevice (0),
@@ -271780,7 +272837,7 @@ public:
if (deviceID != 0)
{
-#if MACOS_10_4_OR_EARLIER
+#if MAC_OS_X_VERSION_MIN_REQUIRED < MAC_OS_X_VERSION_10_5
if (OK (AudioDeviceAddIOProc (deviceID, audioIOProc, (void*) this)))
#else
if (OK (AudioDeviceCreateIOProcID (deviceID, audioIOProc, (void*) this, &audioProcID)))
@@ -271792,7 +272849,7 @@ public:
}
else
{
-#if MACOS_10_4_OR_EARLIER
+#if MAC_OS_X_VERSION_MIN_REQUIRED < MAC_OS_X_VERSION_10_5
OK (AudioDeviceRemoveIOProc (deviceID, audioIOProc));
#else
OK (AudioDeviceDestroyIOProcID (deviceID, audioProcID));
@@ -271827,7 +272884,7 @@ public:
{
OK (AudioDeviceStop (deviceID, audioIOProc));
-#if MACOS_10_4_OR_EARLIER
+#if MAC_OS_X_VERSION_MIN_REQUIRED < MAC_OS_X_VERSION_10_5
OK (AudioDeviceRemoveIOProc (deviceID, audioIOProc));
#else
OK (AudioDeviceDestroyIOProcID (deviceID, audioProcID));
@@ -272046,7 +273103,7 @@ public:
Array sampleRates;
Array bufferSizes;
AudioIODeviceCallback* callback;
-#if ! MACOS_10_4_OR_EARLIER
+#if MAC_OS_X_VERSION_MIN_REQUIRED >= MAC_OS_X_VERSION_10_5
AudioDeviceIOProcID audioProcID;
#endif
@@ -272817,8 +273874,23 @@ static bool makeSureClientExists()
return hasGlobalClientBeenCreated;
}
-struct MidiPortAndEndpoint
+class MidiPortAndEndpoint
{
+public:
+ MidiPortAndEndpoint (MIDIPortRef port, MIDIEndpointRef endpoint) throw()
+ : port (port), endPoint (endpoint)
+ {
+ }
+
+ ~MidiPortAndEndpoint() throw()
+ {
+ if (port != 0)
+ MIDIPortDispose (port);
+
+ if (endPoint != 0)
+ MIDIEndpointDispose (endPoint);
+ }
+
MIDIPortRef port;
MIDIEndpointRef endPoint;
};
@@ -272842,12 +273914,8 @@ MidiOutput* MidiOutput::openDevice (int index)
if (OK (MIDIOutputPortCreate (globalMidiClient, pname, &port)))
{
- MidiPortAndEndpoint* mpe = new MidiPortAndEndpoint();
- mpe->port = port;
- mpe->endPoint = endPoint;
-
mo = new MidiOutput();
- mo->internal = (void*)mpe;
+ mo->internal = (void*) new MidiPortAndEndpoint (port, endPoint);
}
}
@@ -272858,10 +273926,30 @@ MidiOutput* MidiOutput::openDevice (int index)
return mo;
}
+MidiOutput* MidiOutput::createNewDevice (const String& deviceName)
+{
+ MidiOutput* mo = 0;
+
+ if (makeSureClientExists())
+ {
+ MIDIEndpointRef endPoint;
+ CFStringRef name = PlatformUtilities::juceStringToCFString (deviceName);
+
+ if (OK (MIDISourceCreate (globalMidiClient, name, &endPoint)))
+ {
+ mo = new MidiOutput();
+ mo->internal = (void*) new MidiPortAndEndpoint (0, endPoint);
+ }
+
+ CFRelease (name);
+ }
+
+ return mo;
+}
+
MidiOutput::~MidiOutput()
{
- MidiPortAndEndpoint* const mpe = (MidiPortAndEndpoint*)internal;
- MIDIPortDispose (mpe->port);
+ MidiPortAndEndpoint* const mpe = (MidiPortAndEndpoint*) internal;
delete mpe;
}
@@ -272880,7 +273968,7 @@ void MidiOutput::setVolume (float leftVol, float rightVol)
void MidiOutput::sendMessageNow (const MidiMessage& message)
{
- MidiPortAndEndpoint* const mpe = (MidiPortAndEndpoint*)internal;
+ MidiPortAndEndpoint* const mpe = (MidiPortAndEndpoint*) internal;
if (message.isSysEx())
{
@@ -272902,7 +273990,11 @@ void MidiOutput::sendMessageNow (const MidiMessage& message)
p = MIDIPacketNext (p);
}
- MIDISend (mpe->port, mpe->endPoint, packets);
+ if (mpe->port != 0)
+ MIDISend (mpe->port, mpe->endPoint, packets);
+ else
+ MIDIReceived (mpe->endPoint, packets);
+
juce_free (packets);
}
else
@@ -272913,7 +274005,10 @@ void MidiOutput::sendMessageNow (const MidiMessage& message)
packets.packet[0].length = message.getRawDataSize();
*(int*) (packets.packet[0].data) = *(const int*) message.getRawData();
- MIDISend (mpe->port, mpe->endPoint, &packets);
+ if (mpe->port != 0)
+ MIDISend (mpe->port, mpe->endPoint, &packets);
+ else
+ MIDIReceived (mpe->endPoint, &packets);
}
}
@@ -272952,8 +274047,7 @@ int MidiInput::getDefaultDeviceIndex()
struct MidiPortAndCallback
{
MidiInput* input;
- MIDIPortRef port;
- MIDIEndpointRef endPoint;
+ MidiPortAndEndpoint* portAndEndpoint;
MidiInputCallback* callback;
MemoryBlock pendingData;
int pendingBytes;
@@ -272964,26 +274058,26 @@ struct MidiPortAndCallback
static CriticalSection callbackLock;
static VoidArray activeCallbacks;
-static void processSysex (MidiPortAndCallback* const mpe, const uint8*& d, int& size, const double time)
+static void processSysex (MidiPortAndCallback* const mpc, const uint8*& d, int& size, const double time)
{
if (*d == 0xf0)
{
- mpe->pendingBytes = 0;
- mpe->pendingDataTime = time;
+ mpc->pendingBytes = 0;
+ mpc->pendingDataTime = time;
}
- mpe->pendingData.ensureSize (mpe->pendingBytes + size, false);
- uint8* totalMessage = (uint8*) mpe->pendingData.getData();
+ mpc->pendingData.ensureSize (mpc->pendingBytes + size, false);
+ uint8* totalMessage = (uint8*) mpc->pendingData.getData();
- uint8* dest = totalMessage + mpe->pendingBytes;
+ uint8* dest = totalMessage + mpc->pendingBytes;
while (size > 0)
{
- if (mpe->pendingBytes > 0 && *d >= 0x80)
+ if (mpc->pendingBytes > 0 && *d >= 0x80)
{
if (*d >= 0xfa || *d == 0xf8)
{
- mpe->callback->handleIncomingMidiMessage (mpe->input, MidiMessage (*d, time));
+ mpc->callback->handleIncomingMidiMessage (mpc->input, MidiMessage (*d, time));
++d;
--size;
}
@@ -272992,7 +274086,7 @@ static void processSysex (MidiPortAndCallback* const mpe, const uint8*& d, int&
if (*d == 0xf7)
{
*dest++ = *d++;
- mpe->pendingBytes++;
+ mpc->pendingBytes++;
--size;
}
@@ -273002,24 +274096,24 @@ static void processSysex (MidiPortAndCallback* const mpe, const uint8*& d, int&
else
{
*dest++ = *d++;
- mpe->pendingBytes++;
+ mpc->pendingBytes++;
--size;
}
}
- if (totalMessage [mpe->pendingBytes - 1] == 0xf7)
+ if (totalMessage [mpc->pendingBytes - 1] == 0xf7)
{
- mpe->callback->handleIncomingMidiMessage (mpe->input, MidiMessage (totalMessage,
- mpe->pendingBytes,
- mpe->pendingDataTime));
- mpe->pendingBytes = 0;
+ mpc->callback->handleIncomingMidiMessage (mpc->input, MidiMessage (totalMessage,
+ mpc->pendingBytes,
+ mpc->pendingDataTime));
+ mpc->pendingBytes = 0;
}
else
{
- mpe->callback->handlePartialSysexMessage (mpe->input,
+ mpc->callback->handlePartialSysexMessage (mpc->input,
totalMessage,
- mpe->pendingBytes,
- mpe->pendingDataTime);
+ mpc->pendingBytes,
+ mpc->pendingDataTime);
}
}
@@ -273030,10 +274124,10 @@ static void midiInputProc (const MIDIPacketList* pktlist,
double time = Time::getMillisecondCounterHiRes() * 0.001;
const double originalTime = time;
- MidiPortAndCallback* const mpe = (MidiPortAndCallback*) readProcRefCon;
+ MidiPortAndCallback* const mpc = (MidiPortAndCallback*) readProcRefCon;
const ScopedLock sl (callbackLock);
- if (activeCallbacks.contains (mpe) && mpe->active)
+ if (activeCallbacks.contains (mpc) && mpc->active)
{
const MIDIPacket* packet = &pktlist->packet[0];
@@ -273046,9 +274140,9 @@ static void midiInputProc (const MIDIPacketList* pktlist,
{
time = originalTime;
- if (mpe->pendingBytes > 0 || d[0] == 0xf0)
+ if (mpc->pendingBytes > 0 || d[0] == 0xf0)
{
- processSysex (mpe, d, size, time);
+ processSysex (mpc, d, size, time);
}
else
{
@@ -273062,7 +274156,7 @@ static void midiInputProc (const MIDIPacketList* pktlist,
}
else
{
- mpe->callback->handleIncomingMidiMessage (mpe->input, m);
+ mpc->callback->handleIncomingMidiMessage (mpc->input, m);
}
size -= used;
@@ -273095,35 +274189,34 @@ MidiInput* MidiInput::openDevice (int index, MidiInputCallback* callback)
{
MIDIPortRef port;
- MidiPortAndCallback* const mpe = new MidiPortAndCallback();
- mpe->active = false;
+ MidiPortAndCallback* const mpc = new MidiPortAndCallback();
+ mpc->active = false;
- if (OK (MIDIInputPortCreate (globalMidiClient, pname, midiInputProc, mpe, &port)))
+ if (OK (MIDIInputPortCreate (globalMidiClient, pname, midiInputProc, mpc, &port)))
{
if (OK (MIDIPortConnectSource (port, endPoint, 0)))
{
- mpe->port = port;
- mpe->endPoint = endPoint;
- mpe->callback = callback;
- mpe->pendingBytes = 0;
- mpe->pendingData.ensureSize (128);
+ mpc->portAndEndpoint = new MidiPortAndEndpoint (port, endPoint);
+ mpc->callback = callback;
+ mpc->pendingBytes = 0;
+ mpc->pendingData.ensureSize (128);
mi = new MidiInput (getDevices() [index]);
- mpe->input = mi;
- mi->internal = (void*) mpe;
+ mpc->input = mi;
+ mi->internal = (void*) mpc;
const ScopedLock sl (callbackLock);
- activeCallbacks.add (mpe);
+ activeCallbacks.add (mpc);
}
else
{
OK (MIDIPortDispose (port));
- delete mpe;
+ delete mpc;
}
}
else
{
- delete mpe;
+ delete mpc;
}
}
}
@@ -273135,6 +274228,42 @@ MidiInput* MidiInput::openDevice (int index, MidiInputCallback* callback)
return mi;
}
+MidiInput* MidiInput::createNewDevice (const String& deviceName, MidiInputCallback* callback)
+{
+ MidiInput* mi = 0;
+
+ if (makeSureClientExists())
+ {
+ MidiPortAndCallback* const mpc = new MidiPortAndCallback();
+ mpc->active = false;
+
+ MIDIEndpointRef endPoint;
+ CFStringRef name = PlatformUtilities::juceStringToCFString(deviceName);
+ if (OK (MIDIDestinationCreate (globalMidiClient, name, midiInputProc, mpc, &endPoint)))
+ {
+ mpc->portAndEndpoint = new MidiPortAndEndpoint (0, endPoint);
+ mpc->callback = callback;
+ mpc->pendingBytes = 0;
+ mpc->pendingData.ensureSize (128);
+
+ mi = new MidiInput (deviceName);
+ mpc->input = mi;
+ mi->internal = (void*) mpc;
+
+ const ScopedLock sl (callbackLock);
+ activeCallbacks.add (mpc);
+ }
+ else
+ {
+ delete mpc;
+ }
+
+ CFRelease (name);
+ }
+
+ return mi;
+}
+
MidiInput::MidiInput (const String& name_)
: name (name_)
{
@@ -273142,30 +274271,32 @@ MidiInput::MidiInput (const String& name_)
MidiInput::~MidiInput()
{
- MidiPortAndCallback* const mpe = (MidiPortAndCallback*) internal;
- mpe->active = false;
+ MidiPortAndCallback* const mpc = (MidiPortAndCallback*) internal;
+ mpc->active = false;
callbackLock.enter();
- activeCallbacks.removeValue (mpe);
+ activeCallbacks.removeValue (mpc);
callbackLock.exit();
- OK (MIDIPortDisconnectSource (mpe->port, mpe->endPoint));
- OK (MIDIPortDispose (mpe->port));
- delete mpe;
+ if (mpc->portAndEndpoint->port != 0)
+ OK (MIDIPortDisconnectSource (mpc->portAndEndpoint->port, mpc->portAndEndpoint->endPoint));
+
+ delete mpc->portAndEndpoint;
+ delete mpc;
}
void MidiInput::start()
{
- MidiPortAndCallback* const mpe = (MidiPortAndCallback*) internal;
+ MidiPortAndCallback* const mpc = (MidiPortAndCallback*) internal;
const ScopedLock sl (callbackLock);
- mpe->active = true;
+ mpc->active = true;
}
void MidiInput::stop()
{
- MidiPortAndCallback* const mpe = (MidiPortAndCallback*) internal;
+ MidiPortAndCallback* const mpc = (MidiPortAndCallback*) internal;
const ScopedLock sl (callbackLock);
- mpe->active = false;
+ mpc->active = false;
}
#undef log
diff --git a/juce_amalgamated.h b/juce_amalgamated.h
index 681bdafdbd..71b3aeffc8 100644
--- a/juce_amalgamated.h
+++ b/juce_amalgamated.h
@@ -148,17 +148,14 @@
#define JUCE_32BIT 1
#endif
- #if (MAC_OS_X_VERSION_MIN_REQUIRED < MAC_OS_X_VERSION_10_3)
- #error "Building for OSX 10.2 is no longer supported!"
+ #if MAC_OS_X_VERSION_MIN_REQUIRED < MAC_OS_X_VERSION_10_4
+ #error "Building for OSX 10.3 is no longer supported!"
#endif
- #if (! defined (MAC_OS_X_VERSION_10_4)) || (MAC_OS_X_VERSION_MIN_REQUIRED < MAC_OS_X_VERSION_10_4)
- #define MACOS_10_3_OR_EARLIER 1
+ #ifndef MAC_OS_X_VERSION_10_5
+ #error "To build with 10.4 compatibility, use a 10.5 or 10.6 SDK and set the deployment target to 10.4"
#endif
- #if (! defined (MAC_OS_X_VERSION_10_5)) || (MAC_OS_X_VERSION_MIN_REQUIRED < MAC_OS_X_VERSION_10_5)
- #define MACOS_10_4_OR_EARLIER 1
- #endif
#endif
#if JUCE_IPHONE
@@ -679,11 +676,7 @@
#endif
#if JUCE_MAC
- #if MACOS_10_3_OR_EARLIER
- #include
- #else
- #include
- #endif
+ #include
#endif
#if JUCE_LINUX
@@ -1077,19 +1070,8 @@ const float float_Pi = 3.14159265358979323846f;
/** The isfinite() method seems to vary greatly between platforms, so this is a
platform-independent macro for it.
*/
-#if JUCE_LINUX
+#if JUCE_LINUX || JUCE_MAC || JUCE_IPHONE
#define juce_isfinite(v) std::isfinite(v)
-#elif JUCE_MAC
- #if MACOS_10_3_OR_EARLIER
- #ifdef isfinite
- #define juce_isfinite(v) isfinite(v)
- #else
- // no idea why the isfinite macro is sometimes impossible to include, so just copy the built-in one..
- static __inline__ int juce_isfinite (double __x) { return __x == __x && __builtin_fabs (__x) != __builtin_inf(); }
- #endif
- #else
- #define juce_isfinite(v) std::isfinite(v)
- #endif
#elif JUCE_WINDOWS && ! defined (isfinite)
#define juce_isfinite(v) _finite(v)
#else
@@ -2589,20 +2571,11 @@ BEGIN_JUCE_NAMESPACE
#if (JUCE_MAC || JUCE_IPHONE) && ! DOXYGEN
- #if ! MACOS_10_3_OR_EARLIER
-
#include
static forcedinline void atomicIncrement (int& variable) throw() { OSAtomicIncrement32 ((int32_t*) &variable); }
static forcedinline int atomicIncrementAndReturn (int& variable) throw() { return OSAtomicIncrement32 ((int32_t*) &variable); }
static forcedinline void atomicDecrement (int& variable) throw() { OSAtomicDecrement32 ((int32_t*) &variable); }
static forcedinline int atomicDecrementAndReturn (int& variable) throw() { return OSAtomicDecrement32 ((int32_t*) &variable); }
- #else
-
- forcedinline void atomicIncrement (int& variable) throw() { OTAtomicAdd32 (1, (SInt32*) &variable); }
- forcedinline int atomicIncrementAndReturn (int& variable) throw() { return OTAtomicAdd32 (1, (SInt32*) &variable); }
- forcedinline void atomicDecrement (int& variable) throw() { OTAtomicAdd32 (-1, (SInt32*) &variable); }
- forcedinline int atomicDecrementAndReturn (int& variable) throw() { return OTAtomicAdd32 (-1, (SInt32*) &variable); }
- #endif
#elif JUCE_GCC
@@ -6837,6 +6810,9 @@ public:
On the mac this will return the unix binary, not the package folder - see
currentApplicationFile for that.
+
+ See also invokedExecutableFile, which is similar, but if the exe was launched from a
+ file link, invokedExecutableFile will return the name of the link.
*/
currentExecutableFile,
@@ -6850,6 +6826,13 @@ public:
*/
currentApplicationFile,
+ /** Returns the file that was invoked to launch this executable.
+ This may differ from currentExecutableFile if the app was started from e.g. a link - this
+ will return the name of the link that was used, whereas currentExecutableFile will return
+ the actual location of the target executable.
+ */
+ invokedExecutableFile,
+
/** The directory in which applications normally get installed.
So on windows, this would be something like "c:\program files", on the
@@ -16628,6 +16611,10 @@ public:
/** Returns true if this transform maps to a singularity - i.e. if it has no inverse. */
bool isSingularity() const throw();
+ /** Returns true if the transform only translates, and doesn't scale or rotate the
+ points. */
+ bool isOnlyTranslation() const throw();
+
juce_UseDebuggingNewOperator
/* The transform matrix is:
@@ -16774,6 +16761,12 @@ public:
void setBounds (const int newX, const int newY,
const int newWidth, const int newHeight) throw();
+ /** Changes the rectangle's width */
+ void setWidth (const int newWidth) throw();
+
+ /** Changes the rectangle's height */
+ void setHeight (const int newHeight) throw();
+
/** Moves the x position, adjusting the width so that the right-hand edge remains in the same place.
If the x is moved to be on the right of the current right-hand edge, the width will be set to zero.
*/
@@ -17076,7 +17069,6 @@ private:
class Path;
class Image;
-class Rectangle;
/**
A table of horizontal scan-line segments - used for rasterising Paths.
@@ -17092,13 +17084,13 @@ public:
A table is created with a fixed vertical range, and only sections of the path
which lie within this range will be added to the table.
- @param y the top y co-ordinate that the table can contain
- @param height the number of horizontal lines it contains
+ @param clipLimits only the region of the path that lies within this area will be added
@param pathToAdd the path to add to the table
@param transform a transform to apply to the path being added
*/
- EdgeTable (const int y, const int height,
- const Path& pathToAdd, const AffineTransform& transform) throw();
+ EdgeTable (const Rectangle& clipLimits,
+ const Path& pathToAdd,
+ const AffineTransform& transform) throw();
/** Creates an edge table containing a rectangle.
*/
@@ -17113,10 +17105,10 @@ public:
/** Destructor. */
~EdgeTable() throw();
- void clipToRectangle (const Rectangle& r) throw();
+ /*void clipToRectangle (const Rectangle& r) throw();
void excludeRectangle (const Rectangle& r) throw();
void clipToEdgeTable (const EdgeTable& other);
- void clipToImageAlpha (Image& image, int x, int y) throw();
+ void clipToImageAlpha (Image& image, int x, int y) throw();*/
/** Reduces the amount of space the table has allocated.
@@ -17137,27 +17129,13 @@ public:
inline void handleEdgeTableLine (int x, int width, int alphaLevel) const;
@endcode
(these don't necessarily have to be 'const', but it might help it go faster)
- @param clipLeft the left-hand edge of the rectangle which should be iterated
- @param clipTop the top edge of the rectangle which should be iterated
- @param clipRight the right-hand edge of the rectangle which should be iterated
- @param clipBottom the bottom edge of the rectangle which should be iterated
- @param subPixelXOffset a fraction of 1 pixel by which to shift the table rightwards, in the range 0 to 255
*/
template
- void iterate (EdgeTableIterationCallback& iterationCallback,
- const int clipLeft, int clipTop,
- const int clipRight, int clipBottom,
- const int subPixelXOffset) const throw()
+ void iterate (EdgeTableIterationCallback& iterationCallback) const throw()
{
- if (clipTop < top)
- clipTop = top;
+ const int* lineStart = table;
- if (clipBottom > top + height)
- clipBottom = top + height;
-
- const int* lineStart = table + lineStrideElements * (clipTop - top);
-
- for (int y = clipTop; y < clipBottom; ++y)
+ for (int y = 0; y < bounds.getHeight(); ++y)
{
const int* line = lineStart;
lineStart += lineStrideElements;
@@ -17165,7 +17143,8 @@ public:
if (--numPoints > 0)
{
- int x = subPixelXOffset + *++line;
+ int x = *++line;
+ jassert ((x >> 8) >= bounds.getX() && (x >> 8) < bounds.getRight());
int level = *++line;
int levelAccumulator = 0;
@@ -17177,9 +17156,9 @@ public:
if (correctedLevel >> 8)
correctedLevel = 0xff;
- const int endX = subPixelXOffset + *++line;
+ const int endX = *++line;
jassert (endX >= x);
- int endOfRun = (endX >> 8);
+ const int endOfRun = (endX >> 8);
if (endOfRun == (x >> 8))
{
@@ -17192,42 +17171,22 @@ public:
// plot the fist pixel of this segment, including any accumulated
// levels from smaller segments that haven't been drawn yet
levelAccumulator += (0xff - (x & 0xff)) * correctedLevel;
-
+ levelAccumulator >>= 8;
x >>= 8;
- if (x >= clipRight)
- {
- levelAccumulator = 0;
- break;
- }
- if (x >= clipLeft)
+ if (levelAccumulator > 0)
{
- levelAccumulator >>= 8;
- if (levelAccumulator > 0)
- {
- if (levelAccumulator >> 8)
- levelAccumulator = 0xff;
+ if (levelAccumulator >> 8)
+ levelAccumulator = 0xff;
- iterationCallback.handleEdgeTablePixel (x, levelAccumulator);
- }
- }
-
- if (++x >= clipRight)
- {
- levelAccumulator = 0;
- break;
+ iterationCallback.handleEdgeTablePixel (x, levelAccumulator);
}
// if there's a segment of solid pixels, do it all in one go..
- if (correctedLevel > 0 && endOfRun > x)
+ if (correctedLevel > 0)
{
- if (x < clipLeft)
- x = clipLeft;
-
- if (endOfRun > clipRight)
- endOfRun = clipRight;
-
- const int numPix = endOfRun - x;
+ jassert (endOfRun <= bounds.getRight());
+ const int numPix = endOfRun - ++x;
if (numPix > 0)
iterationCallback.handleEdgeTableLine (x, numPix, correctedLevel);
@@ -17248,8 +17207,8 @@ public:
levelAccumulator = 0xff;
x >>= 8;
- if (x >= clipLeft && x < clipRight)
- iterationCallback.handleEdgeTablePixel (x, levelAccumulator);
+ jassert (x >= bounds.getX() && x < bounds.getRight());
+ iterationCallback.handleEdgeTablePixel (x, levelAccumulator);
}
}
}
@@ -17260,11 +17219,13 @@ public:
private:
// table line format: number of points; point0 x, point0 levelDelta, point1 x, point1 levelDelta, etc
int* table;
- int top, height, maxEdgesPerLine, lineStrideElements;
+ Rectangle bounds;
+ int maxEdgesPerLine, lineStrideElements;
void addEdgePoint (const int x, const int y, const int winding) throw();
void remapTableForNumEdges (const int newNumEdgesPerLine) throw();
void clearLineSection (const int y, int minX, int maxX) throw();
+ void intersectWithEdgeTableLine (const int y, const int* otherLine) throw();
};
#endif // __JUCE_EDGETABLE_JUCEHEADER__
@@ -19344,6 +19305,13 @@ public:
*/
const Colour overlaidWith (const Colour& foregroundColour) const throw();
+ /** Returns a colour that lies somewhere between this one and another.
+
+ If amountOfOther is zero, the result is 100% this colour, if amountOfOther
+ is 1.0, the result is 100% of the other colour.
+ */
+ const Colour interpolatedWith (const Colour& other, float proportionOfOther) const throw();
+
/** Returns the colour's hue component.
The value returned is in the range 0.0 to 1.0
*/
@@ -27267,8 +27235,8 @@ public:
static MidiInput* openDevice (int deviceIndex,
MidiInputCallback* callback);
-#if JUCE_LINUX || DOXYGEN
- /** LINUX ONLY - This will try to create a new midi input device.
+#if JUCE_LINUX || JUCE_MAC || DOXYGEN
+ /** This will try to create a new midi input device (Not available on Windows).
This will attempt to create a new midi input device with the specified name,
for other apps to connect to.
@@ -33046,8 +33014,8 @@ public:
*/
static MidiOutput* openDevice (int deviceIndex);
-#if JUCE_LINUX || DOXYGEN
- /** LINUX ONLY - This will try to create a new midi output device.
+#if JUCE_LINUX || JUCE_MAC || DOXYGEN
+ /** This will try to create a new midi output device (Not available on Windows).
This will attempt to create a new midi output device that other apps can connect
to and use as their midi input.
@@ -39109,6 +39077,8 @@ public:
/** Creates an in-memory image with a specified size and format.
+ To create an image that can use native OS rendering methods, see createNativeImage().
+
@param format the number of colour channels in the image
@param imageWidth the desired width of the image, in pixels - this value must be
greater than zero (otherwise a width of 1 will be used)
@@ -39132,6 +39102,16 @@ public:
/** Destructor. */
virtual ~Image();
+ /** Tries to create an image that is uses native drawing methods when you render
+ onto it.
+
+ On some platforms this will just return a normal software-based image.
+ */
+ static Image* createNativeImage (const PixelFormat format,
+ const int imageWidth,
+ const int imageHeight,
+ const bool clearImage);
+
/** Returns the image's width (in pixels). */
int getWidth() const throw() { return imageWidth; }
@@ -39946,6 +39926,9 @@ public:
bool reduceClipRegion (const RectangleList& clipRegion);
void excludeClipRegion (int x, int y, int w, int h);
+ void clipToPath (const Path& path, const AffineTransform& transform);
+ void clipToImage (Image& image, int imageX, int imageY);
+
void saveState();
void restoreState();
@@ -54414,7 +54397,7 @@ public:
*/
static bool isQuickTimeAvailable() throw();
- /** Tries to load a QuickTime movie into the player.
+ /** Tries to load a QuickTime movie from a file into the player.
It's best to call this function once you've added the component to a window,
(or put it on the desktop as a heavyweight window). Loading a movie when the
@@ -54428,6 +54411,33 @@ public:
bool loadMovie (const File& movieFile,
const bool isControllerVisible);
+ /** Tries to load a QuickTime movie from a URL into the player.
+
+ It's best to call this function once you've added the component to a window,
+ (or put it on the desktop as a heavyweight window). Loading a movie when the
+ component isn't visible can cause problems, because QuickTime needs a window
+ handle to do its stuff.
+
+ @param movieFile the .mov file to open
+ @param isControllerVisible whether to show a controller bar at the bottom
+ @returns true if the movie opens successfully
+ */
+ bool loadMovie (const URL& movieURL,
+ const bool isControllerVisible);
+
+ /** Tries to load a QuickTime movie from a stream into the player.
+
+ It's best to call this function once you've added the component to a window,
+ (or put it on the desktop as a heavyweight window). Loading a movie when the
+ component isn't visible can cause problems, because QuickTime needs a window
+ handle to do its stuff.
+
+ @param movieStream a stream containing a .mov file. The component may try
+ to read the whole stream before playing, rather than
+ streaming from it.
+ @param isControllerVisible whether to show a controller bar at the bottom
+ @returns true if the movie opens successfully
+ */
bool loadMovie (InputStream* movieStream,
const bool isControllerVisible);
diff --git a/src/audio/devices/juce_AudioDeviceManager.cpp b/src/audio/devices/juce_AudioDeviceManager.cpp
index d7a4fb39dc..039821cb32 100644
--- a/src/audio/devices/juce_AudioDeviceManager.cpp
+++ b/src/audio/devices/juce_AudioDeviceManager.cpp
@@ -108,6 +108,7 @@ const OwnedArray & AudioDeviceManager::getAvailableDeviceType
//==============================================================================
AudioIODeviceType* juce_createAudioIODeviceType_CoreAudio();
+AudioIODeviceType* juce_createAudioIODeviceType_iPhoneAudio();
AudioIODeviceType* juce_createAudioIODeviceType_WASAPI();
AudioIODeviceType* juce_createAudioIODeviceType_DirectSound();
AudioIODeviceType* juce_createAudioIODeviceType_ASIO();
@@ -135,6 +136,10 @@ void AudioDeviceManager::createAudioDeviceTypes (OwnedArray &
list.add (juce_createAudioIODeviceType_CoreAudio());
#endif
+ #if JUCE_IPHONE
+ list.add (juce_createAudioIODeviceType_iPhoneAudio());
+ #endif
+
#if JUCE_LINUX && JUCE_ALSA
list.add (juce_createAudioIODeviceType_ALSA());
#endif
diff --git a/src/audio/devices/juce_MidiInput.h b/src/audio/devices/juce_MidiInput.h
index fbbbdd4765..ec015b90ce 100644
--- a/src/audio/devices/juce_MidiInput.h
+++ b/src/audio/devices/juce_MidiInput.h
@@ -125,8 +125,8 @@ public:
static MidiInput* openDevice (int deviceIndex,
MidiInputCallback* callback);
-#if JUCE_LINUX || DOXYGEN
- /** LINUX ONLY - This will try to create a new midi input device.
+#if JUCE_LINUX || JUCE_MAC || DOXYGEN
+ /** This will try to create a new midi input device (Not available on Windows).
This will attempt to create a new midi input device with the specified name,
for other apps to connect to.
diff --git a/src/audio/devices/juce_MidiOutput.h b/src/audio/devices/juce_MidiOutput.h
index 352ad0a7d0..6f5e13419f 100644
--- a/src/audio/devices/juce_MidiOutput.h
+++ b/src/audio/devices/juce_MidiOutput.h
@@ -73,8 +73,8 @@ public:
static MidiOutput* openDevice (int deviceIndex);
-#if JUCE_LINUX || DOXYGEN
- /** LINUX ONLY - This will try to create a new midi output device.
+#if JUCE_LINUX || JUCE_MAC || DOXYGEN
+ /** This will try to create a new midi output device (Not available on Windows).
This will attempt to create a new midi output device that other apps can connect
to and use as their midi input.
diff --git a/src/audio/plugins/formats/juce_AudioUnitPluginFormat.mm b/src/audio/plugins/formats/juce_AudioUnitPluginFormat.mm
index 7cff3a7488..88b7681390 100644
--- a/src/audio/plugins/formats/juce_AudioUnitPluginFormat.mm
+++ b/src/audio/plugins/formats/juce_AudioUnitPluginFormat.mm
@@ -54,10 +54,6 @@ BEGIN_JUCE_NAMESPACE
#if JUCE_MAC
-#if MACOS_10_3_OR_EARLIER
- #define kAudioUnitType_Generator 'augn'
-#endif
-
// Change this to disable logging of various activities
#ifndef AU_LOGGING
#define AU_LOGGING 1
diff --git a/src/core/juce_Atomic.h b/src/core/juce_Atomic.h
index a4d1c7f03e..3659642f68 100644
--- a/src/core/juce_Atomic.h
+++ b/src/core/juce_Atomic.h
@@ -33,20 +33,12 @@
//==============================================================================
#if (JUCE_MAC || JUCE_IPHONE) && ! DOXYGEN
- #if ! MACOS_10_3_OR_EARLIER
//==============================================================================
#include
static forcedinline void atomicIncrement (int& variable) throw() { OSAtomicIncrement32 ((int32_t*) &variable); }
static forcedinline int atomicIncrementAndReturn (int& variable) throw() { return OSAtomicIncrement32 ((int32_t*) &variable); }
static forcedinline void atomicDecrement (int& variable) throw() { OSAtomicDecrement32 ((int32_t*) &variable); }
static forcedinline int atomicDecrementAndReturn (int& variable) throw() { return OSAtomicDecrement32 ((int32_t*) &variable); }
- #else
- //==============================================================================
- forcedinline void atomicIncrement (int& variable) throw() { OTAtomicAdd32 (1, (SInt32*) &variable); }
- forcedinline int atomicIncrementAndReturn (int& variable) throw() { return OTAtomicAdd32 (1, (SInt32*) &variable); }
- forcedinline void atomicDecrement (int& variable) throw() { OTAtomicAdd32 (-1, (SInt32*) &variable); }
- forcedinline int atomicDecrementAndReturn (int& variable) throw() { return OTAtomicAdd32 (-1, (SInt32*) &variable); }
- #endif
#elif JUCE_GCC
//==============================================================================
diff --git a/src/core/juce_MathsFunctions.h b/src/core/juce_MathsFunctions.h
index 06561de1b5..5c7e738c8a 100644
--- a/src/core/juce_MathsFunctions.h
+++ b/src/core/juce_MathsFunctions.h
@@ -246,19 +246,8 @@ const float float_Pi = 3.14159265358979323846f;
/** The isfinite() method seems to vary greatly between platforms, so this is a
platform-independent macro for it.
*/
-#if JUCE_LINUX
+#if JUCE_LINUX || JUCE_MAC || JUCE_IPHONE
#define juce_isfinite(v) std::isfinite(v)
-#elif JUCE_MAC
- #if MACOS_10_3_OR_EARLIER
- #ifdef isfinite
- #define juce_isfinite(v) isfinite(v)
- #else
- // no idea why the isfinite macro is sometimes impossible to include, so just copy the built-in one..
- static __inline__ int juce_isfinite (double __x) { return __x == __x && __builtin_fabs (__x) != __builtin_inf(); }
- #endif
- #else
- #define juce_isfinite(v) std::isfinite(v)
- #endif
#elif JUCE_WINDOWS && ! defined (isfinite)
#define juce_isfinite(v) _finite(v)
#else
diff --git a/src/core/juce_StandardHeader.h b/src/core/juce_StandardHeader.h
index fd8b11cc07..677229df9e 100644
--- a/src/core/juce_StandardHeader.h
+++ b/src/core/juce_StandardHeader.h
@@ -83,11 +83,7 @@
#endif
#if JUCE_MAC
- #if MACOS_10_3_OR_EARLIER
- #include
- #else
- #include
- #endif
+ #include
#endif
#if JUCE_LINUX
diff --git a/src/core/juce_TargetPlatform.h b/src/core/juce_TargetPlatform.h
index a77b8341fd..9c0205477a 100644
--- a/src/core/juce_TargetPlatform.h
+++ b/src/core/juce_TargetPlatform.h
@@ -102,17 +102,14 @@
#define JUCE_32BIT 1
#endif
- #if (MAC_OS_X_VERSION_MIN_REQUIRED < MAC_OS_X_VERSION_10_3)
- #error "Building for OSX 10.2 is no longer supported!"
+ #if MAC_OS_X_VERSION_MIN_REQUIRED < MAC_OS_X_VERSION_10_4
+ #error "Building for OSX 10.3 is no longer supported!"
#endif
- #if (! defined (MAC_OS_X_VERSION_10_4)) || (MAC_OS_X_VERSION_MIN_REQUIRED < MAC_OS_X_VERSION_10_4)
- #define MACOS_10_3_OR_EARLIER 1
+ #ifndef MAC_OS_X_VERSION_10_5
+ #error "To build with 10.4 compatibility, use a 10.5 or 10.6 SDK and set the deployment target to 10.4"
#endif
- #if (! defined (MAC_OS_X_VERSION_10_5)) || (MAC_OS_X_VERSION_MIN_REQUIRED < MAC_OS_X_VERSION_10_5)
- #define MACOS_10_4_OR_EARLIER 1
- #endif
#endif
//==============================================================================
diff --git a/src/gui/components/controls/juce_ListBox.cpp b/src/gui/components/controls/juce_ListBox.cpp
index 5b80cc9bc3..d1f2a35b49 100644
--- a/src/gui/components/controls/juce_ListBox.cpp
+++ b/src/gui/components/controls/juce_ListBox.cpp
@@ -897,7 +897,7 @@ void ListBox::repaintRow (const int rowNumber) throw()
Image* ListBox::createSnapshotOfSelectedRows()
{
- Image* snapshot = new Image (Image::ARGB, getWidth(), getHeight(), true);
+ Image* snapshot = Image::createNativeImage (Image::ARGB, getWidth(), getHeight(), true);
Graphics g (*snapshot);
const int firstRow = getRowContainingPosition (0, 0);
diff --git a/src/gui/components/controls/juce_TextEditor.cpp b/src/gui/components/controls/juce_TextEditor.cpp
index 64b1f874b4..7566535595 100644
--- a/src/gui/components/controls/juce_TextEditor.cpp
+++ b/src/gui/components/controls/juce_TextEditor.cpp
@@ -1838,7 +1838,7 @@ void TextEditor::mouseUp (const MouseEvent& e)
if (wasFocused || ! selectAllTextWhenFocused)
{
- if (! (popupMenuEnabled && e.mods.isPopupMenu()))
+ if (e.mouseWasClicked() && ! (popupMenuEnabled && e.mods.isPopupMenu()))
{
moveCaret (getTextIndexAt (e.x, e.y));
}
diff --git a/src/gui/components/juce_Component.cpp b/src/gui/components/juce_Component.cpp
index 86c75a8ea8..f068a18b35 100644
--- a/src/gui/components/juce_Component.cpp
+++ b/src/gui/components/juce_Component.cpp
@@ -1727,9 +1727,9 @@ void Component::paintEntireComponent (Graphics& originalContext)
if (effect_ != 0)
{
- effectImage = new Image (flags.opaqueFlag ? Image::RGB : Image::ARGB,
- getWidth(), getHeight(),
- ! flags.opaqueFlag);
+ effectImage = Image::createNativeImage (flags.opaqueFlag ? Image::RGB : Image::ARGB,
+ getWidth(), getHeight(),
+ ! flags.opaqueFlag);
g = new Graphics (*effectImage);
}
@@ -1750,8 +1750,8 @@ void Component::paintEntireComponent (Graphics& originalContext)
{
if (bufferedImage_ == 0)
{
- bufferedImage_ = new Image (flags.opaqueFlag ? Image::RGB : Image::ARGB,
- getWidth(), getHeight(), ! flags.opaqueFlag);
+ bufferedImage_ = Image::createNativeImage (flags.opaqueFlag ? Image::RGB : Image::ARGB,
+ getWidth(), getHeight(), ! flags.opaqueFlag);
Graphics imG (*bufferedImage_);
paint (imG);
@@ -1832,10 +1832,10 @@ Image* Component::createComponentSnapshot (const Rectangle& areaToGrab,
if (clipImageToComponentBounds)
r = r.getIntersection (Rectangle (0, 0, getWidth(), getHeight()));
- Image* const componentImage = new Image (flags.opaqueFlag ? Image::RGB : Image::ARGB,
- jmax (1, r.getWidth()),
- jmax (1, r.getHeight()),
- true);
+ Image* const componentImage = Image::createNativeImage (flags.opaqueFlag ? Image::RGB : Image::ARGB,
+ jmax (1, r.getWidth()),
+ jmax (1, r.getHeight()),
+ true);
Graphics imageContext (*componentImage);
imageContext.setOrigin (-r.getX(),
diff --git a/src/gui/components/lookandfeel/juce_LookAndFeel.cpp b/src/gui/components/lookandfeel/juce_LookAndFeel.cpp
index 1449791742..dc2bd8d791 100644
--- a/src/gui/components/lookandfeel/juce_LookAndFeel.cpp
+++ b/src/gui/components/lookandfeel/juce_LookAndFeel.cpp
@@ -1541,14 +1541,15 @@ void LookAndFeel::drawRotarySlider (Graphics& g,
}
if (slider.isEnabled())
- {
g.setColour (slider.findColour (Slider::rotarySliderOutlineColourId));
- Path outlineArc;
- outlineArc.addPieSegment (rx, ry, rw, rw, rotaryStartAngle, rotaryEndAngle, thickness);
- outlineArc.closeSubPath();
+ else
+ g.setColour (Colour (0x80808080));
- g.strokePath (outlineArc, PathStrokeType (slider.isEnabled() ? (isMouseOver ? 2.0f : 1.2f) : 0.3f));
- }
+ Path outlineArc;
+ outlineArc.addPieSegment (rx, ry, rw, rw, rotaryStartAngle, rotaryEndAngle, thickness);
+ outlineArc.closeSubPath();
+
+ g.strokePath (outlineArc, PathStrokeType (slider.isEnabled() ? (isMouseOver ? 2.0f : 1.2f) : 0.3f));
}
else
{
diff --git a/src/gui/components/menus/juce_PopupMenu.cpp b/src/gui/components/menus/juce_PopupMenu.cpp
index 5fc1984334..17ff40a039 100644
--- a/src/gui/components/menus/juce_PopupMenu.cpp
+++ b/src/gui/components/menus/juce_PopupMenu.cpp
@@ -908,8 +908,8 @@ private:
y = jmax (mon.getY(), maxY - heightToUse);
}
- x = jlimit (mon.getX() + 1, mon.getRight() - (widthToUse + 6), x);
- y = jlimit (mon.getY() + 1, mon.getBottom() - (heightToUse + 6), y);
+ x = jmax (mon.getX() + 1, jmin (mon.getRight() - (widthToUse + 6), x));
+ y = jmax (mon.getY() + 1, jmin (mon.getBottom() - (heightToUse + 6), y));
windowPos.setBounds (x, y, widthToUse, heightToUse);
diff --git a/src/gui/components/mouse/juce_DragAndDropContainer.cpp b/src/gui/components/mouse/juce_DragAndDropContainer.cpp
index b10efaaa27..a4ee0dff3d 100644
--- a/src/gui/components/mouse/juce_DragAndDropContainer.cpp
+++ b/src/gui/components/mouse/juce_DragAndDropContainer.cpp
@@ -380,7 +380,7 @@ void DragAndDropContainer::startDragging (const String& sourceDescription,
if (im->getFormat() != Image::ARGB)
{
- Image* newIm = new Image (Image::ARGB, im->getWidth(), im->getHeight(), true);
+ Image* newIm = Image::createNativeImage (Image::ARGB, im->getWidth(), im->getHeight(), true);
Graphics g2 (*newIm);
g2.drawImageAt (im, 0, 0);
diff --git a/src/gui/components/special/juce_DropShadower.cpp b/src/gui/components/special/juce_DropShadower.cpp
index 326da80be2..548628d67f 100644
--- a/src/gui/components/special/juce_DropShadower.cpp
+++ b/src/gui/components/special/juce_DropShadower.cpp
@@ -242,7 +242,7 @@ void DropShadower::updateShadows()
if (bigIm == 0)
{
- bigIm = new Image (Image::ARGB, shadowEdge * 5, shadowEdge * 5, true);
+ bigIm = Image::createNativeImage (Image::ARGB, shadowEdge * 5, shadowEdge * 5, true);
Graphics bigG (*bigIm);
bigG.setColour (Colours::black.withAlpha (alpha));
diff --git a/src/gui/components/special/juce_QuickTimeMovieComponent.h b/src/gui/components/special/juce_QuickTimeMovieComponent.h
index cf1d45ae8b..d4922864e8 100644
--- a/src/gui/components/special/juce_QuickTimeMovieComponent.h
+++ b/src/gui/components/special/juce_QuickTimeMovieComponent.h
@@ -67,7 +67,7 @@ public:
static bool isQuickTimeAvailable() throw();
//==============================================================================
- /** Tries to load a QuickTime movie into the player.
+ /** Tries to load a QuickTime movie from a file into the player.
It's best to call this function once you've added the component to a window,
(or put it on the desktop as a heavyweight window). Loading a movie when the
@@ -81,6 +81,33 @@ public:
bool loadMovie (const File& movieFile,
const bool isControllerVisible);
+ /** Tries to load a QuickTime movie from a URL into the player.
+
+ It's best to call this function once you've added the component to a window,
+ (or put it on the desktop as a heavyweight window). Loading a movie when the
+ component isn't visible can cause problems, because QuickTime needs a window
+ handle to do its stuff.
+
+ @param movieFile the .mov file to open
+ @param isControllerVisible whether to show a controller bar at the bottom
+ @returns true if the movie opens successfully
+ */
+ bool loadMovie (const URL& movieURL,
+ const bool isControllerVisible);
+
+ /** Tries to load a QuickTime movie from a stream into the player.
+
+ It's best to call this function once you've added the component to a window,
+ (or put it on the desktop as a heavyweight window). Loading a movie when the
+ component isn't visible can cause problems, because QuickTime needs a window
+ handle to do its stuff.
+
+ @param movieStream a stream containing a .mov file. The component may try
+ to read the whole stream before playing, rather than
+ streaming from it.
+ @param isControllerVisible whether to show a controller bar at the bottom
+ @returns true if the movie opens successfully
+ */
bool loadMovie (InputStream* movieStream,
const bool isControllerVisible);
diff --git a/src/gui/graphics/colour/juce_Colour.cpp b/src/gui/graphics/colour/juce_Colour.cpp
index 82248ff47b..d96c9db824 100644
--- a/src/gui/graphics/colour/juce_Colour.cpp
+++ b/src/gui/graphics/colour/juce_Colour.cpp
@@ -299,6 +299,16 @@ const Colour Colour::overlaidWith (const Colour& src) const throw()
}
}
+const Colour Colour::interpolatedWith (const Colour& other, float proportionOfOther) const throw()
+{
+ const int amount = jlimit (0, 256, (int) (proportionOfOther * 256.0f));
+
+ return Colour ((uint8) (getRed() + (((other.getRed() - getRed()) * amount) >> 8)),
+ (uint8) (getGreen() + (((other.getGreen() - getGreen()) * amount) >> 8)),
+ (uint8) (getBlue() + (((other.getBlue() - getBlue()) * amount) >> 8)),
+ (uint8) (getAlpha() + (((other.getAlpha() - getAlpha()) * amount) >> 8)));
+}
+
//==============================================================================
float Colour::getFloatRed() const throw()
{
diff --git a/src/gui/graphics/colour/juce_Colour.h b/src/gui/graphics/colour/juce_Colour.h
index 7f797b7312..92219a4c90 100644
--- a/src/gui/graphics/colour/juce_Colour.h
+++ b/src/gui/graphics/colour/juce_Colour.h
@@ -231,6 +231,13 @@ public:
*/
const Colour overlaidWith (const Colour& foregroundColour) const throw();
+ /** Returns a colour that lies somewhere between this one and another.
+
+ If amountOfOther is zero, the result is 100% this colour, if amountOfOther
+ is 1.0, the result is 100% of the other colour.
+ */
+ const Colour interpolatedWith (const Colour& other, float proportionOfOther) const throw();
+
//==============================================================================
/** Returns the colour's hue component.
The value returned is in the range 0.0 to 1.0
diff --git a/src/gui/graphics/colour/juce_ColourGradient.cpp b/src/gui/graphics/colour/juce_ColourGradient.cpp
index 69f9a23513..e50f44ee0b 100644
--- a/src/gui/graphics/colour/juce_ColourGradient.cpp
+++ b/src/gui/graphics/colour/juce_ColourGradient.cpp
@@ -129,17 +129,12 @@ const Colour ColourGradient::getColourAtPosition (const float position) const th
return Colour (colours.getUnchecked(i));
const int pos1 = colours.getUnchecked (i);
- PixelARGB pix1 (colours.getUnchecked (i + 1));
- pix1.premultiply();
+ const Colour col1 (colours.getUnchecked (i + 1));
const int pos2 = colours.getUnchecked (i + 2);
- PixelARGB pix2 (colours.getUnchecked (i + 3));
- pix2.premultiply();
+ const Colour col2 (colours.getUnchecked (i + 3));
- pix1.tween (pix2, ((integerPos - pos1) << 8) / (pos2 - pos1));
- pix1.unpremultiply();
-
- return Colour (pix1.getARGB());
+ return col1.interpolatedWith (col2, (integerPos - pos1) / (float) (pos2 - pos1));
}
//==============================================================================
diff --git a/src/gui/graphics/contexts/juce_EdgeTable.cpp b/src/gui/graphics/contexts/juce_EdgeTable.cpp
index 4754d1d417..7cb7ebaf5c 100644
--- a/src/gui/graphics/contexts/juce_EdgeTable.cpp
+++ b/src/gui/graphics/contexts/juce_EdgeTable.cpp
@@ -33,23 +33,25 @@ BEGIN_JUCE_NAMESPACE
const int juce_edgeTableDefaultEdgesPerLine = 32;
//==============================================================================
-EdgeTable::EdgeTable (const int top_, const int height_,
+EdgeTable::EdgeTable (const Rectangle& bounds_,
const Path& path, const AffineTransform& transform) throw()
- : top (top_),
- height (height_),
+ : bounds (bounds_),
maxEdgesPerLine (juce_edgeTableDefaultEdgesPerLine),
lineStrideElements ((juce_edgeTableDefaultEdgesPerLine << 1) + 1)
{
- table = (int*) juce_malloc (height_ * lineStrideElements * sizeof (int));
+ table = (int*) juce_malloc ((bounds.getHeight() + 1) * lineStrideElements * sizeof (int));
int* t = table;
- for (int i = height_; --i >= 0;)
+ for (int i = bounds.getHeight(); --i >= 0;)
{
*t = 0;
t += lineStrideElements;
}
- const int topLimit = top << 8;
- const int bottomLimit = height << 8;
+ const int topLimit = bounds.getY() << 8;
+ const int heightLimit = bounds.getHeight() << 8;
+ const int leftLimit = bounds.getX() << 8;
+ const int rightLimit = bounds.getRight() << 8;
+
PathFlatteningIterator iter (path, transform);
while (iter.next())
@@ -62,33 +64,41 @@ EdgeTable::EdgeTable (const int top_, const int height_,
y1 -= topLimit;
y2 -= topLimit;
- const double startX = 256.0f * iter.x1;
const int startY = y1;
- const double multiplier = (iter.x2 - iter.x1) / (iter.y2 - iter.y1);
- int winding = -1;
+ int direction = -1;
if (y1 > y2)
{
swapVariables (y1, y2);
- winding = 1;
+ direction = 1;
}
if (y1 < 0)
y1 = 0;
- if (y2 > bottomLimit)
- y2 = bottomLimit;
+ if (y2 > heightLimit)
+ y2 = heightLimit;
- const int stepSize = jlimit (1, 256, 256 / (1 + (int) fabs (multiplier)));
-
- while (y1 < y2)
+ if (y1 < y2)
{
- const int step = jmin (stepSize, y2 - y1, 256 - (y1 & 255));
+ const double startX = 256.0f * iter.x1;
+ const double multiplier = (iter.x2 - iter.x1) / (iter.y2 - iter.y1);
+ const int stepSize = jlimit (1, 256, 256 / (1 + (int) fabs (multiplier)));
- addEdgePoint (roundDoubleToInt (startX + multiplier * (y1 - startY)),
- y1 >> 8, winding * step);
+ do
+ {
+ const int step = jmin (stepSize, y2 - y1, 256 - (y1 & 255));
+ int x = roundDoubleToInt (startX + multiplier * (y1 - startY));
- y1 += step;
+ if (x < leftLimit)
+ x = leftLimit;
+ else if (x >= rightLimit)
+ x = rightLimit - 1;
+
+ addEdgePoint (x, y1 >> 8, direction * step);
+ y1 += step;
+ }
+ while (y1 < y2);
}
}
}
@@ -97,7 +107,7 @@ EdgeTable::EdgeTable (const int top_, const int height_,
{
int* lineStart = table;
- for (int i = height; --i >= 0;)
+ for (int i = bounds.getHeight(); --i >= 0;)
{
int* line = lineStart;
lineStart += lineStrideElements;
@@ -125,14 +135,11 @@ EdgeTable::EdgeTable (const int top_, const int height_,
}
EdgeTable::EdgeTable (const Rectangle& rectangleToAdd) throw()
- : top (rectangleToAdd.getY()),
- height (jmax (1, rectangleToAdd.getHeight())),
+ : bounds (rectangleToAdd),
maxEdgesPerLine (juce_edgeTableDefaultEdgesPerLine),
lineStrideElements ((juce_edgeTableDefaultEdgesPerLine << 1) + 1)
{
- jassert (! rectangleToAdd.isEmpty());
-
- table = (int*) juce_malloc (height * lineStrideElements * sizeof (int));
+ table = (int*) juce_malloc (jmax (1, bounds.getHeight()) * lineStrideElements * sizeof (int));
*table = 0;
const int x1 = rectangleToAdd.getX();
@@ -160,12 +167,11 @@ const EdgeTable& EdgeTable::operator= (const EdgeTable& other) throw()
{
juce_free (table);
- top = other.top;
- height = other.height;
+ bounds = other.bounds;
maxEdgesPerLine = other.maxEdgesPerLine;
lineStrideElements = other.lineStrideElements;
- const int tableSize = height * lineStrideElements * sizeof (int);
+ const int tableSize = jmax (1, bounds.getHeight()) * lineStrideElements * sizeof (int);
table = (int*) juce_malloc (tableSize);
memcpy (table, other.table, tableSize);
@@ -184,10 +190,11 @@ void EdgeTable::remapTableForNumEdges (const int newNumEdgesPerLine) throw()
{
maxEdgesPerLine = newNumEdgesPerLine;
+ jassert (bounds.getHeight() > 0);
const int newLineStrideElements = maxEdgesPerLine * 2 + 1;
- int* const newTable = (int*) juce_malloc (height * newLineStrideElements * sizeof (int));
+ int* const newTable = (int*) juce_malloc (bounds.getHeight() * newLineStrideElements * sizeof (int));
- for (int i = 0; i < height; ++i)
+ for (int i = 0; i < bounds.getHeight(); ++i)
{
const int* srcLine = table + lineStrideElements * i;
int* dstLine = newTable + newLineStrideElements * i;
@@ -210,90 +217,229 @@ void EdgeTable::optimiseTable() throw()
{
int maxLineElements = 0;
- for (int i = height; --i >= 0;)
- maxLineElements = jmax (maxLineElements,
- table [i * lineStrideElements]);
+ for (int i = bounds.getHeight(); --i >= 0;)
+ maxLineElements = jmax (maxLineElements, table [i * lineStrideElements]);
remapTableForNumEdges (maxLineElements);
}
void EdgeTable::addEdgePoint (const int x, const int y, const int winding) throw()
{
- jassert (y >= 0 && y < height)
+ jassert (y >= 0 && y < bounds.getHeight());
- int* lineStart = table + lineStrideElements * y;
- int n = lineStart[0];
+ int* line = table + lineStrideElements * y;
+ const int numPoints = line[0];
+ int n = line[0] << 1;
- if (n >= maxEdgesPerLine)
+ if (n > 0)
{
- remapTableForNumEdges (maxEdgesPerLine + juce_edgeTableDefaultEdgesPerLine);
- jassert (n < maxEdgesPerLine);
- lineStart = table + lineStrideElements * y;
+ while (n > 0)
+ {
+ const int cx = line [n - 1];
+
+ if (cx <= x)
+ {
+ if (cx == x)
+ {
+ line [n] += winding;
+ return;
+ }
+
+ break;
+ }
+
+ n -= 2;
+ }
+
+ if (numPoints >= maxEdgesPerLine)
+ {
+ remapTableForNumEdges (maxEdgesPerLine + juce_edgeTableDefaultEdgesPerLine);
+ jassert (numPoints < maxEdgesPerLine);
+ line = table + lineStrideElements * y;
+ }
+
+ memmove (line + (n + 3), line + (n + 1), sizeof (int) * ((numPoints << 1) - n));
}
- n <<= 1;
-
- int* const line = lineStart + 1;
-
- while (n > 0)
- {
- const int cx = line [n - 2];
-
- if (cx <= x)
- break;
-
- line [n] = cx;
- line [n + 1] = line [n - 1];
- n -= 2;
- }
-
- line [n] = x;
- line [n + 1] = winding;
-
- lineStart[0]++;
+ line [n + 1] = x;
+ line [n + 2] = winding;
+ line[0]++;
}
void EdgeTable::clearLineSection (const int y, int minX, int maxX) throw()
{
-// int* line = table + lineStrideElements * y;
+ jassert (y >= 0 && y < bounds.getHeight());
+ jassert (maxX > minX);
+ int* lineStart = table + lineStrideElements * y;
+ const int totalPoints = *lineStart;
+ int* line = lineStart;
+ int level = 0;
+ int num = totalPoints;
+ while (--num >= 0)
+ {
+ int x = *++line;
+
+ if (x < minX)
+ {
+ level += *++line;
+ continue;
+ }
+
+ if (x > maxX)
+ {
+ if (level != 0)
+ {
+ addEdgePoint (minX, y, -level);
+ addEdgePoint (maxX, y, level);
+ }
+
+ return;
+ }
+
+ if (level != 0)
+ {
+ const int oldLevel = level;
+ level += line[1];
+ line[0] = minX;
+ line[1] = -oldLevel;
+ line += 2;
+ }
+ else
+ {
+ ++num;
+ }
+
+ int* cutPoint = line;
+ int numToDelete = 0;
+
+ while (--num >= 0)
+ {
+ x = *line++;
+
+ if (x <= maxX)
+ {
+ level += *line++;
+ ++numToDelete;
+ continue;
+ }
+
+ break;
+ }
+
+ if (num < 0)
+ {
+ lineStart[0] -= numToDelete;
+ }
+ else
+ {
+ if (--numToDelete > 0)
+ {
+ char* startOfSrcSection = (char*) (cutPoint + numToDelete * 2);
+ memmove (cutPoint, startOfSrcSection,
+ ((char*) (lineStart + (1 + 2 * totalPoints))) - startOfSrcSection);
+
+ lineStart[0] -= numToDelete;
+ }
+
+ if (numToDelete < 0)
+ {
+ addEdgePoint (maxX, y, level);
+ }
+ else
+ {
+ cutPoint[0] = maxX;
+ cutPoint[1] = level;
+ }
+ }
+
+ break;
+ }
+}
+
+void EdgeTable::intersectWithEdgeTableLine (const int y, const int* otherLine) throw()
+{
+// int otherNum = otherLine[0];
}
//==============================================================================
-void EdgeTable::clipToRectangle (const Rectangle& r) throw()
+/*void EdgeTable::clipToRectangle (const Rectangle& r) throw()
{
- const int rectTop = jmax (0, r.getY() - top);
- const int rectBottom = jmin (height, r.getBottom() - top);
+ const Rectangle clipped (r.getIntersection (bounds));
- for (int i = rectTop - 1; --i >= 0;)
- table [lineStrideElements * i] = 0;
-
- for (int i = rectBottom; i < height; ++i)
- table [lineStrideElements * i] = 0;
-
- for (int i = rectTop; i < rectBottom; ++i)
+ if (clipped.isEmpty())
{
- clearLineSection (i, -INT_MAX, r.getX());
- clearLineSection (i, r.getRight(), INT_MAX);
+ bounds.setHeight (0);
+ }
+ else
+ {
+ const int top = clipped.getY() - bounds.getY();
+ const int bottom = clipped.getBottom() - bounds.getY();
+
+ if (bottom < bounds.getHeight())
+ bounds.setHeight (bottom);
+
+ if (clipped.getRight() < bounds.getRight())
+ bounds.setRight (clipped.getRight());
+
+ for (int i = top; --i >= 0;)
+ table [lineStrideElements * i] = 0;
+
+ if (clipped.getX() > bounds.getX())
+ for (int i = top; i < bottom; ++i)
+ clearLineSection (i, bounds.getX(), clipped.getX());
}
}
void EdgeTable::excludeRectangle (const Rectangle& r) throw()
{
- const int rectTop = jmax (0, r.getY() - top);
- const int rectBottom = jmin (height, r.getBottom() - top);
+ const Rectangle clipped (r.getIntersection (bounds));
- for (int i = rectTop; i < rectBottom; ++i)
- clearLineSection (i, r.getX(), r.getRight());
+ if (! clipped.isEmpty())
+ {
+ const int top = clipped.getY() - bounds.getY();
+ const int bottom = clipped.getBottom() - bounds.getY();
+
+ for (int i = top; i < bottom; ++i)
+ clearLineSection (i, clipped.getX(), clipped.getRight());
+ }
}
void EdgeTable::clipToEdgeTable (const EdgeTable& other)
{
+ const Rectangle clipped (other.bounds.getIntersection (bounds));
+
+ if (clipped.isEmpty())
+ {
+ bounds.setHeight (0);
+ }
+ else
+ {
+ const int top = clipped.getY() - bounds.getY();
+ const int bottom = clipped.getBottom() - bounds.getY();
+
+ if (bottom < bounds.getHeight())
+ bounds.setHeight (bottom);
+
+ if (clipped.getRight() < bounds.getRight())
+ bounds.setRight (clipped.getRight());
+
+ for (int i = top; --i >= 0;)
+ table [lineStrideElements * i] = 0;
+
+ const int* otherLine = other.table + other.lineStrideElements * (top + (bounds.getY() - other.bounds.getY()));
+
+ for (int i = top; i < bottom; ++i)
+ {
+ intersectWithEdgeTableLine (i, otherLine);
+ otherLine += other.lineStrideElements;
+ }
+ }
}
void EdgeTable::clipToImageAlpha (Image& image, int x, int y) throw()
{
}
-
+*/
END_JUCE_NAMESPACE
diff --git a/src/gui/graphics/contexts/juce_EdgeTable.h b/src/gui/graphics/contexts/juce_EdgeTable.h
index bf184b1e12..026ad3a735 100644
--- a/src/gui/graphics/contexts/juce_EdgeTable.h
+++ b/src/gui/graphics/contexts/juce_EdgeTable.h
@@ -27,10 +27,11 @@
#define __JUCE_EDGETABLE_JUCEHEADER__
#include "../geometry/juce_AffineTransform.h"
+#include "../geometry/juce_Rectangle.h"
#include "../../../containers/juce_MemoryBlock.h"
class Path;
class Image;
-class Rectangle;
+
//==============================================================================
/**
@@ -47,13 +48,13 @@ public:
A table is created with a fixed vertical range, and only sections of the path
which lie within this range will be added to the table.
- @param y the top y co-ordinate that the table can contain
- @param height the number of horizontal lines it contains
+ @param clipLimits only the region of the path that lies within this area will be added
@param pathToAdd the path to add to the table
@param transform a transform to apply to the path being added
*/
- EdgeTable (const int y, const int height,
- const Path& pathToAdd, const AffineTransform& transform) throw();
+ EdgeTable (const Rectangle& clipLimits,
+ const Path& pathToAdd,
+ const AffineTransform& transform) throw();
/** Creates an edge table containing a rectangle.
*/
@@ -69,10 +70,10 @@ public:
~EdgeTable() throw();
//==============================================================================
- void clipToRectangle (const Rectangle& r) throw();
+ /*void clipToRectangle (const Rectangle& r) throw();
void excludeRectangle (const Rectangle& r) throw();
void clipToEdgeTable (const EdgeTable& other);
- void clipToImageAlpha (Image& image, int x, int y) throw();
+ void clipToImageAlpha (Image& image, int x, int y) throw();*/
/** Reduces the amount of space the table has allocated.
@@ -95,27 +96,13 @@ public:
inline void handleEdgeTableLine (int x, int width, int alphaLevel) const;
@endcode
(these don't necessarily have to be 'const', but it might help it go faster)
- @param clipLeft the left-hand edge of the rectangle which should be iterated
- @param clipTop the top edge of the rectangle which should be iterated
- @param clipRight the right-hand edge of the rectangle which should be iterated
- @param clipBottom the bottom edge of the rectangle which should be iterated
- @param subPixelXOffset a fraction of 1 pixel by which to shift the table rightwards, in the range 0 to 255
*/
template
- void iterate (EdgeTableIterationCallback& iterationCallback,
- const int clipLeft, int clipTop,
- const int clipRight, int clipBottom,
- const int subPixelXOffset) const throw()
+ void iterate (EdgeTableIterationCallback& iterationCallback) const throw()
{
- if (clipTop < top)
- clipTop = top;
+ const int* lineStart = table;
- if (clipBottom > top + height)
- clipBottom = top + height;
-
- const int* lineStart = table + lineStrideElements * (clipTop - top);
-
- for (int y = clipTop; y < clipBottom; ++y)
+ for (int y = 0; y < bounds.getHeight(); ++y)
{
const int* line = lineStart;
lineStart += lineStrideElements;
@@ -123,7 +110,8 @@ public:
if (--numPoints > 0)
{
- int x = subPixelXOffset + *++line;
+ int x = *++line;
+ jassert ((x >> 8) >= bounds.getX() && (x >> 8) < bounds.getRight());
int level = *++line;
int levelAccumulator = 0;
@@ -135,9 +123,9 @@ public:
if (correctedLevel >> 8)
correctedLevel = 0xff;
- const int endX = subPixelXOffset + *++line;
+ const int endX = *++line;
jassert (endX >= x);
- int endOfRun = (endX >> 8);
+ const int endOfRun = (endX >> 8);
if (endOfRun == (x >> 8))
{
@@ -150,42 +138,22 @@ public:
// plot the fist pixel of this segment, including any accumulated
// levels from smaller segments that haven't been drawn yet
levelAccumulator += (0xff - (x & 0xff)) * correctedLevel;
-
+ levelAccumulator >>= 8;
x >>= 8;
- if (x >= clipRight)
- {
- levelAccumulator = 0;
- break;
- }
- if (x >= clipLeft)
+ if (levelAccumulator > 0)
{
- levelAccumulator >>= 8;
- if (levelAccumulator > 0)
- {
- if (levelAccumulator >> 8)
- levelAccumulator = 0xff;
+ if (levelAccumulator >> 8)
+ levelAccumulator = 0xff;
- iterationCallback.handleEdgeTablePixel (x, levelAccumulator);
- }
- }
-
- if (++x >= clipRight)
- {
- levelAccumulator = 0;
- break;
+ iterationCallback.handleEdgeTablePixel (x, levelAccumulator);
}
// if there's a segment of solid pixels, do it all in one go..
- if (correctedLevel > 0 && endOfRun > x)
+ if (correctedLevel > 0)
{
- if (x < clipLeft)
- x = clipLeft;
-
- if (endOfRun > clipRight)
- endOfRun = clipRight;
-
- const int numPix = endOfRun - x;
+ jassert (endOfRun <= bounds.getRight());
+ const int numPix = endOfRun - ++x;
if (numPix > 0)
iterationCallback.handleEdgeTableLine (x, numPix, correctedLevel);
@@ -206,8 +174,8 @@ public:
levelAccumulator = 0xff;
x >>= 8;
- if (x >= clipLeft && x < clipRight)
- iterationCallback.handleEdgeTablePixel (x, levelAccumulator);
+ jassert (x >= bounds.getX() && x < bounds.getRight());
+ iterationCallback.handleEdgeTablePixel (x, levelAccumulator);
}
}
}
@@ -219,11 +187,13 @@ public:
private:
// table line format: number of points; point0 x, point0 levelDelta, point1 x, point1 levelDelta, etc
int* table;
- int top, height, maxEdgesPerLine, lineStrideElements;
+ Rectangle bounds;
+ int maxEdgesPerLine, lineStrideElements;
void addEdgePoint (const int x, const int y, const int winding) throw();
void remapTableForNumEdges (const int newNumEdgesPerLine) throw();
void clearLineSection (const int y, int minX, int maxX) throw();
+ void intersectWithEdgeTableLine (const int y, const int* otherLine) throw();
};
diff --git a/src/gui/graphics/contexts/juce_LowLevelGraphicsSoftwareRenderer.cpp b/src/gui/graphics/contexts/juce_LowLevelGraphicsSoftwareRenderer.cpp
index afb3d5b3fe..3989d0af53 100644
--- a/src/gui/graphics/contexts/juce_LowLevelGraphicsSoftwareRenderer.cpp
+++ b/src/gui/graphics/contexts/juce_LowLevelGraphicsSoftwareRenderer.cpp
@@ -1180,6 +1180,14 @@ void LowLevelGraphicsSoftwareRenderer::excludeClipRegion (int x, int y, int w, i
clip->subtract (Rectangle (x + xOffset, y + yOffset, w, h));
}
+void LowLevelGraphicsSoftwareRenderer::clipToPath (const Path& path, const AffineTransform& transform)
+{
+}
+
+void LowLevelGraphicsSoftwareRenderer::clipToImage (Image& image, int imageX, int imageY)
+{
+}
+
bool LowLevelGraphicsSoftwareRenderer::clipRegionIntersects (int x, int y, int w, int h)
{
return clip->intersectsRectangle (Rectangle (x + xOffset, y + yOffset, w, h));
@@ -1362,7 +1370,7 @@ void LowLevelGraphicsSoftwareRenderer::clippedFillPath (int clipX, int clipY, in
if (getPathBounds (clipX, clipY, clipW, clipH, path, transform, cx, cy, cw, ch))
{
- EdgeTable edgeTable (0, ch, path, transform.translated ((float) -cx, (float) -cy));
+ EdgeTable edgeTable (Rectangle (0, 0, cw, ch), path, transform.translated ((float) -cx, (float) -cy));
int stride, pixelStride;
uint8* const pixels = (uint8*) image.lockPixelDataReadWrite (cx, cy, cw, ch, stride, pixelStride);
@@ -1398,18 +1406,18 @@ void LowLevelGraphicsSoftwareRenderer::clippedFillPath (int clipX, int clipY, in
if (isIdentity)
{
GradientEdgeTableRenderer renderer (pixels, stride, g2, lookupTable, numLookupEntries);
- edgeTable.iterate (renderer, 0, 0, cw, ch, 0);
+ edgeTable.iterate (renderer);
}
else
{
GradientEdgeTableRenderer renderer (pixels, stride, g2, lookupTable, numLookupEntries);
- edgeTable.iterate (renderer, 0, 0, cw, ch, 0);
+ edgeTable.iterate (renderer);
}
}
else
{
GradientEdgeTableRenderer renderer (pixels, stride, g2, lookupTable, numLookupEntries);
- edgeTable.iterate (renderer, 0, 0, cw, ch, 0);
+ edgeTable.iterate (renderer);
}
}
else if (image.getFormat() == Image::ARGB)
@@ -1421,18 +1429,18 @@ void LowLevelGraphicsSoftwareRenderer::clippedFillPath (int clipX, int clipY, in
if (isIdentity)
{
GradientEdgeTableRenderer renderer (pixels, stride, g2, lookupTable, numLookupEntries);
- edgeTable.iterate (renderer, 0, 0, cw, ch, 0);
+ edgeTable.iterate (renderer);
}
else
{
GradientEdgeTableRenderer renderer (pixels, stride, g2, lookupTable, numLookupEntries);
- edgeTable.iterate (renderer, 0, 0, cw, ch, 0);
+ edgeTable.iterate (renderer);
}
}
else
{
GradientEdgeTableRenderer renderer (pixels, stride, g2, lookupTable, numLookupEntries);
- edgeTable.iterate (renderer, 0, 0, cw, ch, 0);
+ edgeTable.iterate (renderer);
}
}
else if (image.getFormat() == Image::SingleChannel)
@@ -1448,19 +1456,19 @@ void LowLevelGraphicsSoftwareRenderer::clippedFillPath (int clipX, int clipY, in
{
jassert (pixelStride == 3);
SolidColourEdgeTableRenderer renderer (pixels, stride, colour);
- edgeTable.iterate (renderer, 0, 0, cw, ch, 0);
+ edgeTable.iterate (renderer);
}
else if (image.getFormat() == Image::ARGB)
{
jassert (pixelStride == 4);
SolidColourEdgeTableRenderer renderer (pixels, stride, colour);
- edgeTable.iterate (renderer, 0, 0, cw, ch, 0);
+ edgeTable.iterate (renderer);
}
else if (image.getFormat() == Image::SingleChannel)
{
jassert (pixelStride == 1);
AlphaBitmapRenderer renderer (pixels, stride);
- edgeTable.iterate (renderer, 0, 0, cw, ch, 0);
+ edgeTable.iterate (renderer);
}
}
@@ -1489,7 +1497,8 @@ void LowLevelGraphicsSoftwareRenderer::clippedFillPathWithImage (int x, int y, i
{
if (Rectangle::intersectRectangles (x, y, w, h, imageX, imageY, sourceImage.getWidth(), sourceImage.getHeight()))
{
- EdgeTable edgeTable (0, h, path, transform.translated ((float) (xOffset - x), (float) (yOffset - y)));
+ EdgeTable edgeTable (Rectangle (0, 0, w, h), path,
+ transform.translated ((float) (xOffset - x), (float) (yOffset - y)));
int stride, pixelStride;
uint8* const pixels = (uint8*) image.lockPixelDataReadWrite (x, y, w, h, stride, pixelStride);
@@ -1506,14 +1515,14 @@ void LowLevelGraphicsSoftwareRenderer::clippedFillPathWithImage (int x, int y, i
ImageFillEdgeTableRenderer renderer (pixels, stride,
srcPix, srcStride,
alpha, (PixelRGB*) 0);
- edgeTable.iterate (renderer, 0, 0, w, h, 0);
+ edgeTable.iterate (renderer);
}
else if (sourceImage.getFormat() == Image::ARGB)
{
ImageFillEdgeTableRenderer renderer (pixels, stride,
srcPix, srcStride,
alpha, (PixelARGB*) 0);
- edgeTable.iterate (renderer, 0, 0, w, h, 0);
+ edgeTable.iterate (renderer);
}
else
{
@@ -1527,14 +1536,14 @@ void LowLevelGraphicsSoftwareRenderer::clippedFillPathWithImage (int x, int y, i
ImageFillEdgeTableRenderer renderer (pixels, stride,
srcPix, srcStride,
alpha, (PixelRGB*) 0);
- edgeTable.iterate (renderer, 0, 0, w, h, 0);
+ edgeTable.iterate (renderer);
}
else if (sourceImage.getFormat() == Image::ARGB)
{
ImageFillEdgeTableRenderer renderer (pixels, stride,
srcPix, srcStride,
alpha, (PixelARGB*) 0);
- edgeTable.iterate (renderer, 0, 0, w, h, 0);
+ edgeTable.iterate (renderer);
}
else
{
diff --git a/src/gui/graphics/contexts/juce_LowLevelGraphicsSoftwareRenderer.h b/src/gui/graphics/contexts/juce_LowLevelGraphicsSoftwareRenderer.h
index f2c9a34b02..271a4eff1f 100644
--- a/src/gui/graphics/contexts/juce_LowLevelGraphicsSoftwareRenderer.h
+++ b/src/gui/graphics/contexts/juce_LowLevelGraphicsSoftwareRenderer.h
@@ -53,6 +53,9 @@ public:
bool reduceClipRegion (const RectangleList& clipRegion);
void excludeClipRegion (int x, int y, int w, int h);
+ void clipToPath (const Path& path, const AffineTransform& transform);
+ void clipToImage (Image& image, int imageX, int imageY);
+
void saveState();
void restoreState();
diff --git a/src/gui/graphics/geometry/juce_AffineTransform.cpp b/src/gui/graphics/geometry/juce_AffineTransform.cpp
index 711b89b118..04c6796ca3 100644
--- a/src/gui/graphics/geometry/juce_AffineTransform.cpp
+++ b/src/gui/graphics/geometry/juce_AffineTransform.cpp
@@ -137,8 +137,8 @@ const AffineTransform AffineTransform::followedBy (const float omat00,
const AffineTransform AffineTransform::translated (const float dx,
const float dy) const throw()
{
- return followedBy (1.0f, 0, dx,
- 0, 1.0f, dy);
+ return AffineTransform (mat00, mat01, mat02 + dx,
+ mat10, mat11, mat12 + dy);
}
const AffineTransform AffineTransform::translation (const float dx,
@@ -233,6 +233,14 @@ bool AffineTransform::isSingularity() const throw()
return (mat00 * mat11 - mat10 * mat01) == 0.0;
}
+bool AffineTransform::isOnlyTranslation() const throw()
+{
+ return (mat01 == 0)
+ && (mat10 == 0)
+ && (mat00 == 1.0f)
+ && (mat11 == 1.0f);
+}
+
//==============================================================================
void AffineTransform::transformPoint (float& x,
float& y) const throw()
diff --git a/src/gui/graphics/geometry/juce_AffineTransform.h b/src/gui/graphics/geometry/juce_AffineTransform.h
index 106d8eb631..ef5c018fe5 100644
--- a/src/gui/graphics/geometry/juce_AffineTransform.h
+++ b/src/gui/graphics/geometry/juce_AffineTransform.h
@@ -156,6 +156,9 @@ public:
/** Returns true if this transform maps to a singularity - i.e. if it has no inverse. */
bool isSingularity() const throw();
+ /** Returns true if the transform only translates, and doesn't scale or rotate the
+ points. */
+ bool isOnlyTranslation() const throw();
//==============================================================================
juce_UseDebuggingNewOperator
diff --git a/src/gui/graphics/geometry/juce_Path.cpp b/src/gui/graphics/geometry/juce_Path.cpp
index 769c5bb55e..e9391ea0a5 100644
--- a/src/gui/graphics/geometry/juce_Path.cpp
+++ b/src/gui/graphics/geometry/juce_Path.cpp
@@ -1601,17 +1601,17 @@ Image* Path::createMaskBitmap (const AffineTransform& transform,
if (imagePosition.isEmpty())
return 0;
- Image* im = new Image (Image::SingleChannel, imagePosition.getWidth(), imagePosition.getHeight(), true);
+ Image* im = Image::createNativeImage (Image::SingleChannel, imagePosition.getWidth(), imagePosition.getHeight(), true);
- EdgeTable edgeTable (0, imagePosition.getHeight(), *this,
- transform.translated (-imagePosition.getX(), -imagePosition.getY()));
+ EdgeTable edgeTable (Rectangle (0, 0, imagePosition.getWidth(), imagePosition.getHeight()),
+ *this, transform.translated (-imagePosition.getX(), -imagePosition.getY()));
int stride, pixelStride;
uint8* const pixels = (uint8*) im->lockPixelDataReadWrite (0, 0, imagePosition.getWidth(), imagePosition.getHeight(), stride, pixelStride);
jassert (pixelStride == 1);
MaskBitmapRenderer renderer (pixels, stride);
- edgeTable.iterate (renderer, 0, 0, imagePosition.getWidth(), imagePosition.getHeight(), 0);
+ edgeTable.iterate (renderer);
im->releasePixelDataReadWrite (pixels);
return im;
diff --git a/src/gui/graphics/geometry/juce_Rectangle.cpp b/src/gui/graphics/geometry/juce_Rectangle.cpp
index 5c18eb0f39..4871ff9162 100644
--- a/src/gui/graphics/geometry/juce_Rectangle.cpp
+++ b/src/gui/graphics/geometry/juce_Rectangle.cpp
@@ -100,6 +100,16 @@ void Rectangle::setSize (const int w_,
h = h_;
}
+void Rectangle::setWidth (const int newWidth) throw()
+{
+ w = newWidth;
+}
+
+void Rectangle::setHeight (const int newHeight) throw()
+{
+ h = newHeight;
+}
+
void Rectangle::setLeft (const int newLeft) throw()
{
w = jmax (0, x + w - newLeft);
diff --git a/src/gui/graphics/geometry/juce_Rectangle.h b/src/gui/graphics/geometry/juce_Rectangle.h
index 03326d6e51..32bae3d4cb 100644
--- a/src/gui/graphics/geometry/juce_Rectangle.h
+++ b/src/gui/graphics/geometry/juce_Rectangle.h
@@ -96,6 +96,12 @@ public:
void setBounds (const int newX, const int newY,
const int newWidth, const int newHeight) throw();
+ /** Changes the rectangle's width */
+ void setWidth (const int newWidth) throw();
+
+ /** Changes the rectangle's height */
+ void setHeight (const int newHeight) throw();
+
/** Moves the x position, adjusting the width so that the right-hand edge remains in the same place.
If the x is moved to be on the right of the current right-hand edge, the width will be set to zero.
*/
diff --git a/src/gui/graphics/imaging/image_file_formats/juce_GIFLoader.cpp b/src/gui/graphics/imaging/image_file_formats/juce_GIFLoader.cpp
index 2e1378d21d..d36af50d24 100644
--- a/src/gui/graphics/imaging/image_file_formats/juce_GIFLoader.cpp
+++ b/src/gui/graphics/imaging/image_file_formats/juce_GIFLoader.cpp
@@ -102,8 +102,8 @@ GIFLoader::GIFLoader (InputStream& in)
if (! readPalette (numColours))
break;
- image = new Image ((transparent >= 0) ? Image::ARGB : Image::RGB,
- imageWidth, imageHeight, (transparent >= 0));
+ image = Image::createNativeImage ((transparent >= 0) ? Image::ARGB : Image::RGB,
+ imageWidth, imageHeight, (transparent >= 0));
readImage (imageWidth, imageHeight,
(buf[8] & 0x40) != 0,
diff --git a/src/gui/graphics/imaging/image_file_formats/juce_JPEGLoader.cpp b/src/gui/graphics/imaging/image_file_formats/juce_JPEGLoader.cpp
index a39c0519f4..58b1021261 100644
--- a/src/gui/graphics/imaging/image_file_formats/juce_JPEGLoader.cpp
+++ b/src/gui/graphics/imaging/image_file_formats/juce_JPEGLoader.cpp
@@ -221,7 +221,7 @@ Image* juce_loadJPEGImageFromStream (InputStream& in) throw()
if (jpeg_start_decompress (&jpegDecompStruct))
{
- image = new Image (Image::RGB, width, height, false);
+ image = Image::createNativeImage (Image::RGB, width, height, false);
for (int y = 0; y < height; ++y)
{
diff --git a/src/gui/graphics/imaging/image_file_formats/juce_PNGLoader.cpp b/src/gui/graphics/imaging/image_file_formats/juce_PNGLoader.cpp
index 96a623e00c..18c1a0cc96 100644
--- a/src/gui/graphics/imaging/image_file_formats/juce_PNGLoader.cpp
+++ b/src/gui/graphics/imaging/image_file_formats/juce_PNGLoader.cpp
@@ -192,8 +192,8 @@ Image* juce_loadPNGImageFromStream (InputStream& in) throw()
png_destroy_read_struct (&pngReadStruct, &pngInfoStruct, 0);
// now convert the data to a juce image format..
- image = new Image (hasAlphaChan ? Image::ARGB : Image::RGB,
- width, height, hasAlphaChan);
+ image = Image::createNativeImage (hasAlphaChan ? Image::ARGB : Image::RGB,
+ width, height, hasAlphaChan);
int stride, pixelStride;
uint8* const pixels = image->lockPixelDataReadWrite (0, 0, width, height, stride, pixelStride);
diff --git a/src/gui/graphics/imaging/juce_Image.cpp b/src/gui/graphics/imaging/juce_Image.cpp
index 1d4a56ca4b..6afd42663b 100644
--- a/src/gui/graphics/imaging/juce_Image.cpp
+++ b/src/gui/graphics/imaging/juce_Image.cpp
@@ -204,7 +204,7 @@ Image* Image::createCopy (int newWidth, int newHeight,
if (newHeight < 0)
newHeight = imageHeight;
- Image* const newImage = new Image (format, newWidth, newHeight, true);
+ Image* const newImage = Image::createNativeImage (format, newWidth, newHeight, true);
Graphics g (*newImage);
g.setImageResamplingQuality (quality);
@@ -221,7 +221,7 @@ Image* Image::createCopyOfAlphaChannel() const
{
jassert (format != SingleChannel);
- Image* const newImage = new Image (SingleChannel, imageWidth, imageHeight, false);
+ Image* const newImage = Image::createNativeImage (SingleChannel, imageWidth, imageHeight, false);
if (! hasAlphaChannel())
{
diff --git a/src/gui/graphics/imaging/juce_Image.h b/src/gui/graphics/imaging/juce_Image.h
index ee6c6162df..1cb1ff3538 100644
--- a/src/gui/graphics/imaging/juce_Image.h
+++ b/src/gui/graphics/imaging/juce_Image.h
@@ -66,6 +66,8 @@ public:
//==============================================================================
/** Creates an in-memory image with a specified size and format.
+ To create an image that can use native OS rendering methods, see createNativeImage().
+
@param format the number of colour channels in the image
@param imageWidth the desired width of the image, in pixels - this value must be
greater than zero (otherwise a width of 1 will be used)
@@ -89,6 +91,17 @@ public:
/** Destructor. */
virtual ~Image();
+ //==============================================================================
+ /** Tries to create an image that is uses native drawing methods when you render
+ onto it.
+
+ On some platforms this will just return a normal software-based image.
+ */
+ static Image* createNativeImage (const PixelFormat format,
+ const int imageWidth,
+ const int imageHeight,
+ const bool clearImage);
+
//==============================================================================
/** Returns the image's width (in pixels). */
int getWidth() const throw() { return imageWidth; }
diff --git a/src/native/juce_mac_NativeCode.mm b/src/native/juce_mac_NativeCode.mm
index af014c44bd..1cd29699df 100644
--- a/src/native/juce_mac_NativeCode.mm
+++ b/src/native/juce_mac_NativeCode.mm
@@ -98,6 +98,7 @@ BEGIN_JUCE_NAMESPACE
#if ! JUCE_ONLY_BUILD_CORE_LIBRARY
#if JUCE_IPHONE
#include "mac/juce_mac_Fonts.mm"
+ #include "mac/juce_mac_CoreGraphicsContext.mm"
#include "mac/juce_iphone_UIViewComponentPeer.mm"
#include "mac/juce_iphone_MessageManager.mm"
#include "mac/juce_mac_FileChooser.mm"
diff --git a/src/native/linux/juce_linux_Windowing.cpp b/src/native/linux/juce_linux_Windowing.cpp
index 138dda04e9..8752290f46 100644
--- a/src/native/linux/juce_linux_Windowing.cpp
+++ b/src/native/linux/juce_linux_Windowing.cpp
@@ -2902,6 +2902,11 @@ Image* juce_createIconForFile (const File& file)
return 0;
}
+Image* Image::createNativeImage (const PixelFormat format, const int imageWidth, const int imageHeight, const bool clearImage)
+{
+ return new Image (format, imageWidth, imageHeight, clearImage);
+}
+
//==============================================================================
#if JUCE_OPENGL
diff --git a/src/native/mac/juce_iphone_Audio.cpp b/src/native/mac/juce_iphone_Audio.cpp
index be1cc64d1c..64eb2343a6 100644
--- a/src/native/mac/juce_iphone_Audio.cpp
+++ b/src/native/mac/juce_iphone_Audio.cpp
@@ -308,8 +308,8 @@ private:
}
else
{
- zeromem (inputChannels[0], sizeof (float) * inNumberFrames);
- zeromem (inputChannels[1], sizeof (float) * inNumberFrames);
+ for (int i = numInputChannels; --i >= 0;)
+ zeromem (inputChannels[i], sizeof (float) * inNumberFrames);
}
callback->audioDeviceIOCallback ((const float**) inputChannels, numInputChannels,
@@ -543,7 +543,7 @@ public:
const StringArray getDeviceNames (const bool wantInputNames) const
{
StringArray s;
- s.add (wantInputNames ? "Microphone" : "Speaker");
+ s.add ("iPhone Audio");
return s;
}
diff --git a/src/native/mac/juce_iphone_MessageManager.mm b/src/native/mac/juce_iphone_MessageManager.mm
index 2ede5fc287..efb2a30926 100644
--- a/src/native/mac/juce_iphone_MessageManager.mm
+++ b/src/native/mac/juce_iphone_MessageManager.mm
@@ -217,11 +217,7 @@ static const int quitMessageId = 0xfffff321;
void MessageManager::stopDispatchLoop()
{
- Message* const m = new Message (quitMessageId, 0, 0, 0);
- m->messageRecipient = 0;
- postMessageToQueue (m);
-
- quitMessagePosted = true;
+ exit (0); // iPhone apps get no mercy..
}
bool MessageManager::runDispatchLoopUntil (int millisecondsToRunFor)
diff --git a/src/native/mac/juce_iphone_MiscUtilities.mm b/src/native/mac/juce_iphone_MiscUtilities.mm
index 47404ddba6..ce530d63d2 100644
--- a/src/native/mac/juce_iphone_MiscUtilities.mm
+++ b/src/native/mac/juce_iphone_MiscUtilities.mm
@@ -169,22 +169,6 @@ bool DragAndDropContainer::performExternalDragDropOfText (const String& text)
return false;
}
-//==============================================================================
-bool Desktop::canUseSemiTransparentWindows() throw()
-{
- return true;
-}
-
-void Desktop::getMousePosition (int& x, int& y) throw()
-{
- x = 0;
- y = 0;
-}
-
-void Desktop::setMousePosition (int x, int y) throw()
-{
-}
-
//==============================================================================
void Desktop::setScreenSaverEnabled (const bool isEnabled) throw()
{
diff --git a/src/native/mac/juce_iphone_UIViewComponentPeer.mm b/src/native/mac/juce_iphone_UIViewComponentPeer.mm
index e3f6682a66..3647b2889a 100644
--- a/src/native/mac/juce_iphone_UIViewComponentPeer.mm
+++ b/src/native/mac/juce_iphone_UIViewComponentPeer.mm
@@ -54,6 +54,8 @@ END_JUCE_NAMESPACE
- (BOOL) resignFirstResponder;
- (BOOL) canBecomeFirstResponder;
+- (void) asyncRepaint: (id) rect;
+
@end
//==============================================================================
@@ -186,9 +188,14 @@ static int getModifierForButtonNumber (const int num) throw()
static int64 getMouseTime (UIEvent* e) { return (int64) [e timestamp] * 1000.0; }
+int juce_lastMouseX = 0, juce_lastMouseY = 0;
+
//==============================================================================
- (void) touchesBegan: (NSSet*) touches withEvent: (UIEvent*) event
{
+ if (owner == 0)
+ return;
+
NSArray* const t = [[event touchesForView: self] allObjects];
switch ([t count])
@@ -198,7 +205,15 @@ static int64 getMouseTime (UIEvent* e) { return (int64) [e timestamp] * 1000.0;
CGPoint p = [[t objectAtIndex: 0] locationInView: self];
currentModifiers |= getModifierForButtonNumber (0);
- owner->handleMouseDown (p.x, p.y, getMouseTime (event));
+ int x, y, w, h;
+ owner->getBounds (x, y, w, h, true);
+ juce_lastMouseX = p.x + x;
+ juce_lastMouseY = p.y + y;
+
+ owner->handleMouseMove (p.x, p.y, getMouseTime (event));
+
+ if (owner != 0)
+ owner->handleMouseDown (p.x, p.y, getMouseTime (event));
}
default:
@@ -209,6 +224,9 @@ static int64 getMouseTime (UIEvent* e) { return (int64) [e timestamp] * 1000.0;
- (void) touchesMoved: (NSSet*) touches withEvent: (UIEvent*) event
{
+ if (owner == 0)
+ return;
+
NSArray* const t = [[event touchesForView: self] allObjects];
switch ([t count])
@@ -216,6 +234,12 @@ static int64 getMouseTime (UIEvent* e) { return (int64) [e timestamp] * 1000.0;
case 1: // One finger..
{
CGPoint p = [[t objectAtIndex: 0] locationInView: self];
+
+ int x, y, w, h;
+ owner->getBounds (x, y, w, h, true);
+ juce_lastMouseX = p.x + x;
+ juce_lastMouseY = p.y + y;
+
owner->handleMouseDrag (p.x, p.y, getMouseTime (event));
}
@@ -227,6 +251,9 @@ static int64 getMouseTime (UIEvent* e) { return (int64) [e timestamp] * 1000.0;
- (void) touchesEnded: (NSSet*) touches withEvent: (UIEvent*) event
{
+ if (owner == 0)
+ return;
+
NSArray* const t = [[event touchesForView: self] allObjects];
switch ([t count])
@@ -234,6 +261,12 @@ static int64 getMouseTime (UIEvent* e) { return (int64) [e timestamp] * 1000.0;
case 1: // One finger..
{
CGPoint p = [[t objectAtIndex: 0] locationInView: self];
+
+ int x, y, w, h;
+ owner->getBounds (x, y, w, h, true);
+ juce_lastMouseX = p.x + x;
+ juce_lastMouseY = p.y + y;
+
const int oldMods = currentModifiers;
currentModifiers &= ~getModifierForButtonNumber (0);
owner->handleMouseUp (oldMods, p.x, p.y, getMouseTime (event));
@@ -272,6 +305,11 @@ static int64 getMouseTime (UIEvent* e) { return (int64) [e timestamp] * 1000.0;
return owner != 0 && owner->canBecomeKeyWindow();
}
+- (void) asyncRepaint: (id) rect
+{
+ CGRect* r = (CGRect*) [((NSData*) rect) bytes];
+ [self setNeedsDisplayInRect: *r];
+}
@end
@@ -298,119 +336,6 @@ static int64 getMouseTime (UIEvent* e) { return (int64) [e timestamp] * 1000.0;
//==============================================================================
BEGIN_JUCE_NAMESPACE
-//==============================================================================
-class JuceUIImage
-{
-public:
- JuceUIImage (const int width, const int height, const bool hasAlpha)
- : juceImage (hasAlpha ? Image::ARGB : Image::RGB,
- width, height, hasAlpha)
- {
- lineStride = 0;
- pixelStride = 0;
- imageData = juceImage.lockPixelDataReadWrite (0, 0, width, height,
- lineStride, pixelStride);
-
- CGDataProviderRef provider = CGDataProviderCreateWithData (0, imageData, lineStride * pixelStride, 0);
- CGColorSpaceRef colourSpace = CGColorSpaceCreateDeviceRGB();
-
- CGImageRef imageRef = CGImageCreate (width, height,
- 8, pixelStride * 8, lineStride,
- colourSpace,
- hasAlpha ? (kCGImageAlphaFirst | kCGBitmapByteOrder32Little) : kCGBitmapByteOrderDefault,
- provider,
- 0,
- true, kCGRenderingIntentDefault);
-
- CGColorSpaceRelease (colourSpace);
- CGDataProviderRelease (provider);
-
- juceImage.releasePixelDataReadWrite (imageData);
-
- uiImage = [[UIImage imageWithCGImage: imageRef] retain];
- }
-
- ~JuceUIImage()
- {
- [uiImage release];
- CGImageRelease (imageRef);
- }
-
- Image& getJuceImage() throw() { return juceImage; }
-
- void draw (const float x, const float y) const
- {
- [uiImage drawAtPoint: CGPointMake (x, y)
- blendMode: kCGBlendModeCopy
- alpha: 1.0f];
- }
-
- void drawUIImage (UIImage* imageToDraw)
- {
- const ScopedAutoReleasePool pool;
-
- jassertfalse
- /*[NSGraphicsContext saveGraphicsState];
- [NSGraphicsContext setCurrentContext:
- [NSGraphicsContext graphicsContextWithBitmapImageRep: imageRep]];
-
- [imageToDraw drawAtPoint: NSZeroPoint
- fromRect: NSMakeRect (0, 0, [imageToDraw size].width, [imageToDraw size].height)
- operation: NSCompositeSourceOver
- fraction: 1.0f];
-
- [[NSGraphicsContext currentContext] flushGraphics];
- [NSGraphicsContext restoreGraphicsState];
-
- if (juceImage.hasAlphaChannel())
- swapRGBOrder (0, 0, juceImage.getWidth(), juceImage.getHeight());*/
-
- }
-
-private:
- Image juceImage;
- CGImageRef imageRef;
- CGDataProviderRef provider;
- UIImage* uiImage;
- uint8* imageData;
- int pixelStride, lineStride;
-
-/* void swapRGBOrder (const int x, const int y, const int w, int h) const
- {
-#if JUCE_BIG_ENDIAN
- jassert (pixelStride == 4);
-#endif
- jassert (Rectangle (0, 0, juceImage.getWidth(), juceImage.getHeight())
- .contains (Rectangle (x, y, w, h)));
-
- uint8* start = imageData + x * pixelStride + y * lineStride;
-
- while (--h >= 0)
- {
- uint8* p = start;
- start += lineStride;
-
- for (int i = w; --i >= 0;)
- {
-#if JUCE_BIG_ENDIAN
- const uint8 oldp3 = p[3];
- const uint8 oldp1 = p[1];
- p[3] = p[0];
- p[0] = oldp1;
- p[1] = p[2];
- p[2] = oldp3;
-#else
- const uint8 oldp0 = p[0];
- p[0] = p[2];
- p[2] = oldp0;
-#endif
-
- p += pixelStride;
- }
- }
- }*/
-};
-
//==============================================================================
UIViewComponentPeer::UIViewComponentPeer (Component* const component,
const int windowStyleFlags,
@@ -444,6 +369,12 @@ UIViewComponentPeer::UIViewComponentPeer (Component* const component,
window = [[JuceUIWindow alloc] init];
window.frame = r;
+
+ window.opaque = component->isOpaque();
+ view.opaque = component->isOpaque();
+ window.backgroundColor = [[UIColor blackColor] colorWithAlphaComponent: 0];
+ view.backgroundColor = [[UIColor blackColor] colorWithAlphaComponent: 0];
+
[((JuceUIWindow*) window) setOwner: this];
if (component->isAlwaysOnTop())
@@ -451,6 +382,9 @@ UIViewComponentPeer::UIViewComponentPeer (Component* const component,
[window addSubview: view];
view.frame = CGRectMake (0, 0, r.size.width, r.size.height);
+
+ view.hidden = ! component->isVisible();
+ window.hidden = ! component->isVisible();
}
setTitle (component->getName());
@@ -478,6 +412,9 @@ void* UIViewComponentPeer::getNativeHandle() const
void UIViewComponentPeer::setVisible (bool shouldBeVisible)
{
view.hidden = ! shouldBeVisible;
+
+ if (! isSharedWindow)
+ window.hidden = ! shouldBeVisible;
}
void UIViewComponentPeer::setTitle (const String& title)
@@ -519,8 +456,6 @@ void UIViewComponentPeer::setBounds (int x, int y, int w, int h, const bool isNo
}
else
{
- //r.origin.y = [[UIScreen mainScreen] bounds].size.height - (r.origin.y + r.size.height);
-
window.frame = r;
view.frame = CGRectMake (0, 0, r.size.width, r.size.height);
}
@@ -536,15 +471,10 @@ void UIViewComponentPeer::getBounds (int& x, int& y, int& w, int& h, const bool
CGRect wr = [[view window] frame];
r.origin.x += wr.origin.x;
r.origin.y += wr.origin.y;
-
- y = (int) ([[UIScreen mainScreen] bounds].size.height - r.origin.y - r.size.height);
- }
- else
- {
- y = (int) ([[view superview] frame].size.height - r.origin.y - r.size.height);
}
x = (int) r.origin.x;
+ y = (int) r.origin.y;
w = (int) r.size.width;
h = (int) r.size.height;
}
@@ -796,23 +726,14 @@ void UIViewComponentPeer::drawRect (CGRect r)
if (r.size.width < 1.0f || r.size.height < 1.0f)
return;
- DBG (Rectangle (r.origin.x, r.origin.y, r.size.width, r.size.height).toString());
+ CGContextRef cg = UIGraphicsGetCurrentContext();
- const float y = r.origin.y;//[view frame].size.height - (r.origin.y + r.size.height);
+ if (! component->isOpaque())
+ CGContextClearRect (cg, CGContextGetClipBoundingBox (cg));
- JuceUIImage temp ((int) (r.size.width + 0.5f),
- (int) (r.size.height + 0.5f),
- true);//! getComponent()->isOpaque());
-
- LowLevelGraphicsSoftwareRenderer context (temp.getJuceImage());
- const int originX = -roundFloatToInt (r.origin.x);
- const int originY = -roundFloatToInt (y);
- context.setOrigin (originX, originY);
-
- handlePaint (context);
-
- //CGContextClipToRect (UIGraphicsGetCurrentContext(), r);
- temp.draw (r.origin.x, r.origin.y);
+ CGContextConcatCTM (cg, CGAffineTransformMake (1, 0, 0, -1, 0, view.bounds.size.height));
+ CoreGraphicsContext g (cg, view.bounds.size.height);
+ handlePaint (g);
}
bool UIViewComponentPeer::canBecomeKeyWindow()
@@ -842,9 +763,18 @@ void juce_setKioskComponent (Component* kioskModeComponent, bool enableOrDisable
//==============================================================================
void UIViewComponentPeer::repaint (int x, int y, int w, int h)
{
- [view setNeedsDisplayInRect:
- CGRectMake ((float) x, (float) y,//([view frame].size.height - (y + h)),
- (float) w, (float) h)];
+ CGRect r = CGRectMake ((float) x, (float) y, (float) w, (float) h);
+
+ if (! MessageManager::getInstance()->isThisTheMessageThread())
+ {
+ [view performSelectorOnMainThread: @selector (asyncRepaint:)
+ withObject: [NSData dataWithBytes: &r length: sizeof (r)]
+ waitUntilDone: NO];
+ }
+ else
+ {
+ [view setNeedsDisplayInRect: r];
+ }
}
void UIViewComponentPeer::performAnyPendingRepaintsNow()
@@ -857,21 +787,27 @@ ComponentPeer* Component::createNewPeer (int styleFlags, void* windowToAttachTo)
}
//==============================================================================
-static Image* UIImageToJuceImage (UIImage* image)
-{
- JuceUIImage juceIm ((int) [image size].width,
- (int) [image size].height,
- true);
-
- juceIm.drawUIImage (image);
- return juceIm.getJuceImage().createCopy();
-}
-
Image* juce_createIconForFile (const File& file)
{
return 0;
}
+//==============================================================================
+bool Desktop::canUseSemiTransparentWindows() throw()
+{
+ return true;
+}
+
+void Desktop::getMousePosition (int& x, int& y) throw()
+{
+ x = juce_lastMouseX;
+ y = juce_lastMouseY;
+}
+
+void Desktop::setMousePosition (int x, int y) throw()
+{
+}
+
//==============================================================================
const int KeyPress::spaceKey = ' ';
const int KeyPress::returnKey = 0x0d;
diff --git a/src/native/mac/juce_mac_CoreAudio.cpp b/src/native/mac/juce_mac_CoreAudio.cpp
index bf6be0f8c6..17a7342b32 100644
--- a/src/native/mac/juce_mac_CoreAudio.cpp
+++ b/src/native/mac/juce_mac_CoreAudio.cpp
@@ -68,7 +68,7 @@ public:
: inputLatency (0),
outputLatency (0),
callback (0),
-#if ! MACOS_10_4_OR_EARLIER
+#if MAC_OS_X_VERSION_MIN_REQUIRED >= MAC_OS_X_VERSION_10_5
audioProcID (0),
#endif
inputDevice (0),
@@ -535,7 +535,7 @@ public:
if (deviceID != 0)
{
-#if MACOS_10_4_OR_EARLIER
+#if MAC_OS_X_VERSION_MIN_REQUIRED < MAC_OS_X_VERSION_10_5
if (OK (AudioDeviceAddIOProc (deviceID, audioIOProc, (void*) this)))
#else
if (OK (AudioDeviceCreateIOProcID (deviceID, audioIOProc, (void*) this, &audioProcID)))
@@ -547,7 +547,7 @@ public:
}
else
{
-#if MACOS_10_4_OR_EARLIER
+#if MAC_OS_X_VERSION_MIN_REQUIRED < MAC_OS_X_VERSION_10_5
OK (AudioDeviceRemoveIOProc (deviceID, audioIOProc));
#else
OK (AudioDeviceDestroyIOProcID (deviceID, audioProcID));
@@ -582,7 +582,7 @@ public:
{
OK (AudioDeviceStop (deviceID, audioIOProc));
-#if MACOS_10_4_OR_EARLIER
+#if MAC_OS_X_VERSION_MIN_REQUIRED < MAC_OS_X_VERSION_10_5
OK (AudioDeviceRemoveIOProc (deviceID, audioIOProc));
#else
OK (AudioDeviceDestroyIOProcID (deviceID, audioProcID));
@@ -802,7 +802,7 @@ public:
Array sampleRates;
Array bufferSizes;
AudioIODeviceCallback* callback;
-#if ! MACOS_10_4_OR_EARLIER
+#if MAC_OS_X_VERSION_MIN_REQUIRED >= MAC_OS_X_VERSION_10_5
AudioDeviceIOProcID audioProcID;
#endif
diff --git a/src/native/mac/juce_mac_CoreGraphicsContext.mm b/src/native/mac/juce_mac_CoreGraphicsContext.mm
index 6bd41f455d..51afa1bc60 100644
--- a/src/native/mac/juce_mac_CoreGraphicsContext.mm
+++ b/src/native/mac/juce_mac_CoreGraphicsContext.mm
@@ -27,6 +27,41 @@
// compiled on its own).
#if JUCE_INCLUDED_FILE
+//==============================================================================
+class CoreGraphicsImage : public Image
+{
+public:
+ CoreGraphicsImage (const PixelFormat format,
+ const int imageWidth,
+ const int imageHeight,
+ const bool clearImage)
+ : Image (format, imageWidth, imageHeight, clearImage)
+ {
+ CGColorSpaceRef colourSpace = format == Image::SingleChannel ? CGColorSpaceCreateDeviceGray()
+ : CGColorSpaceCreateDeviceRGB();
+
+ context = CGBitmapContextCreate (imageData, imageWidth, imageHeight, 8, lineStride,
+ colourSpace,
+ format == Image::ARGB ? (kCGImageAlphaPremultipliedFirst | kCGBitmapByteOrder32Little)
+ : kCGBitmapByteOrderDefault);
+
+ CGColorSpaceRelease (colourSpace);
+ }
+
+ ~CoreGraphicsImage()
+ {
+ CGContextRelease (context);
+ }
+
+ LowLevelGraphicsContext* createLowLevelContext();
+
+ CGContextRef context;
+};
+
+Image* Image::createNativeImage (const PixelFormat format, const int imageWidth, const int imageHeight, const bool clearImage)
+{
+ return new CoreGraphicsImage (format == RGB ? ARGB : format, imageWidth, imageHeight, clearImage);
+}
//==============================================================================
class CoreGraphicsContext : public LowLevelGraphicsContext
@@ -39,12 +74,19 @@ public:
CGContextRetain (context);
CGContextSetShouldSmoothFonts (context, true);
CGContextSetBlendMode (context, kCGBlendModeNormal);
+ rgbColourSpace = CGColorSpaceCreateDeviceRGB();
+ greyColourSpace = CGColorSpaceCreateDeviceGray();
+ gradientCallbacks.version = 0;
+ gradientCallbacks.evaluate = gradientCallback;
+ gradientCallbacks.releaseInfo = 0;
state = new SavedState();
}
~CoreGraphicsContext()
{
CGContextRelease (context);
+ CGColorSpaceRelease (rgbColourSpace);
+ CGColorSpaceRelease (greyColourSpace);
delete state;
}
@@ -166,7 +208,17 @@ public:
{
if (replaceExistingContents)
{
- CGContextSetBlendMode (context, kCGBlendModeCopy);
+#if MAC_OS_X_VERSION_MAX_ALLOWED < MAC_OS_X_VERSION_10_5
+ CGContextClearRect (context, CGRectMake (x, y, w, h));
+#else
+ #if MAC_OS_X_VERSION_MIN_REQUIRED < MAC_OS_X_VERSION_10_5
+ if (CGContextDrawLinearGradient == 0) // (just a way of checking whether we're running in 10.5 or later)
+ CGContextClearRect (context, CGRectMake (x, y, w, h));
+ else
+ #endif
+ CGContextSetBlendMode (context, kCGBlendModeCopy);
+#endif
+
fillRect (x, y, w, h, false);
CGContextSetBlendMode (context, kCGBlendModeNormal);
}
@@ -352,7 +404,7 @@ public:
void drawGlyph (int glyphNumber, float x, float y)
{
- if (state->fontRef != 0)
+ if (state->fontRef != 0 && state->gradient == 0)
{
CGGlyph g = glyphNumber;
CGContextShowGlyphsAtPoint (context, x, flipHeight - roundFloatToInt (y), &g, 1);
@@ -390,6 +442,8 @@ public:
private:
CGContextRef context;
const float flipHeight;
+ CGColorSpaceRef rgbColourSpace, greyColourSpace;
+ CGFunctionCallbacks gradientCallbacks;
struct SavedState
{
@@ -422,6 +476,10 @@ private:
SavedState* state;
OwnedArray stateStack;
+#if ! CGFLOAT_DEFINED
+ #define CGFloat float
+#endif
+
static void gradientCallback (void* info, const CGFloat* inData, CGFloat* outData)
{
const ColourGradient* const g = (const ColourGradient*) info;
@@ -432,30 +490,25 @@ private:
outData[3] = c.getFloatAlpha();
}
- static CGShadingRef createGradient (const ColourGradient* const gradient) throw()
+ CGShadingRef createGradient (const ColourGradient* const gradient) const throw()
{
CGShadingRef result = 0;
- CGColorSpaceRef colourSpace = CGColorSpaceCreateDeviceRGB();
-
- CGFunctionCallbacks callbacks = { 0, gradientCallback, 0 };
- CGFunctionRef function = CGFunctionCreate ((void*) gradient, 1, 0, 4, 0, &callbacks);
- CGPoint p1 = CGPointMake (gradient->x1, gradient->y1);
+ CGFunctionRef function = CGFunctionCreate ((void*) gradient, 1, 0, 4, 0, &gradientCallbacks);
+ CGPoint p1 (CGPointMake (gradient->x1, gradient->y1));
if (gradient->isRadial)
{
- result = CGShadingCreateRadial (colourSpace,
- p1, 0,
+ result = CGShadingCreateRadial (rgbColourSpace, p1, 0,
p1, hypotf (gradient->x1 - gradient->x2, gradient->y1 - gradient->y2),
function, true, true);
}
else
{
- result = CGShadingCreateAxial (colourSpace, p1,
+ result = CGShadingCreateAxial (rgbColourSpace, p1,
CGPointMake (gradient->x2, gradient->y2),
function, true, true);
}
- CGColorSpaceRelease (colourSpace);
CGFunctionRelease (function);
return result;
}
@@ -537,30 +590,37 @@ private:
CGImageRef createImage (const Image& juceImage, const bool forAlpha) const throw()
{
- int lineStride = 0;
- int pixelStride = 0;
- const uint8* imageData = juceImage.lockPixelDataReadOnly (0, 0, juceImage.getWidth(), juceImage.getHeight(),
- lineStride, pixelStride);
+ const CoreGraphicsImage* nativeImage = dynamic_cast (&juceImage);
- CGDataProviderRef provider = CGDataProviderCreateWithData (0, imageData, lineStride * pixelStride, 0);
+ if (nativeImage != 0 && (juceImage.getFormat() == Image::SingleChannel || ! forAlpha))
+ {
+ return CGBitmapContextCreateImage (nativeImage->context);
+ }
+ else
+ {
+ int lineStride = 0;
+ int pixelStride = 0;
+ const uint8* imageData = juceImage.lockPixelDataReadOnly (0, 0, juceImage.getWidth(), juceImage.getHeight(),
+ lineStride, pixelStride);
- CGColorSpaceRef colourSpace = forAlpha ? CGColorSpaceCreateDeviceGray()
- : CGColorSpaceCreateDeviceRGB();
+ CGDataProviderRef provider = CGDataProviderCreateWithData (0, imageData, lineStride * pixelStride, 0);
- CGImageRef imageRef = CGImageCreate (juceImage.getWidth(), juceImage.getHeight(),
- 8, pixelStride * 8, lineStride,
- colourSpace,
- (juceImage.hasAlphaChannel() && ! forAlpha)
- ? (kCGImageAlphaPremultipliedFirst | kCGBitmapByteOrder32Little)
- : kCGBitmapByteOrderDefault,
- provider,
- 0, true, kCGRenderingIntentDefault);
+ CGColorSpaceRef colourSpace = forAlpha ? greyColourSpace : rgbColourSpace;
- CGColorSpaceRelease (colourSpace);
- CGDataProviderRelease (provider);
+ CGImageRef imageRef = CGImageCreate (juceImage.getWidth(), juceImage.getHeight(),
+ 8, pixelStride * 8, lineStride,
+ colourSpace,
+ (juceImage.hasAlphaChannel() && ! forAlpha)
+ ? (kCGImageAlphaPremultipliedFirst | kCGBitmapByteOrder32Little)
+ : kCGBitmapByteOrderDefault,
+ provider,
+ 0, true, kCGRenderingIntentDefault);
- juceImage.releasePixelDataReadOnly (imageData);
- return imageRef;
+ CGDataProviderRelease (provider);
+
+ juceImage.releasePixelDataReadOnly (imageData);
+ return imageRef;
+ }
}
static Image* createAlphaChannelImage (const Image& im) throw()
@@ -593,7 +653,16 @@ private:
t.ty = transform.mat12;
CGContextConcatCTM (context, t);
}
+
+ float flipY (float y) const throw()
+ {
+ return flipHeight - y;
+ }
};
+LowLevelGraphicsContext* CoreGraphicsImage::createLowLevelContext()
+{
+ return new CoreGraphicsContext (context, imageHeight);
+}
#endif
diff --git a/src/native/mac/juce_mac_CoreMidi.cpp b/src/native/mac/juce_mac_CoreMidi.cpp
index 119d45a451..aeae3a17eb 100644
--- a/src/native/mac/juce_mac_CoreMidi.cpp
+++ b/src/native/mac/juce_mac_CoreMidi.cpp
@@ -233,8 +233,23 @@ static bool makeSureClientExists()
return hasGlobalClientBeenCreated;
}
-struct MidiPortAndEndpoint
+class MidiPortAndEndpoint
{
+public:
+ MidiPortAndEndpoint (MIDIPortRef port, MIDIEndpointRef endpoint) throw()
+ : port (port), endPoint (endpoint)
+ {
+ }
+
+ ~MidiPortAndEndpoint() throw()
+ {
+ if (port != 0)
+ MIDIPortDispose (port);
+
+ if (endPoint != 0)
+ MIDIEndpointDispose (endPoint);
+ }
+
MIDIPortRef port;
MIDIEndpointRef endPoint;
};
@@ -258,12 +273,8 @@ MidiOutput* MidiOutput::openDevice (int index)
if (OK (MIDIOutputPortCreate (globalMidiClient, pname, &port)))
{
- MidiPortAndEndpoint* mpe = new MidiPortAndEndpoint();
- mpe->port = port;
- mpe->endPoint = endPoint;
-
mo = new MidiOutput();
- mo->internal = (void*)mpe;
+ mo->internal = (void*) new MidiPortAndEndpoint (port, endPoint);
}
}
@@ -274,10 +285,30 @@ MidiOutput* MidiOutput::openDevice (int index)
return mo;
}
+MidiOutput* MidiOutput::createNewDevice (const String& deviceName)
+{
+ MidiOutput* mo = 0;
+
+ if (makeSureClientExists())
+ {
+ MIDIEndpointRef endPoint;
+ CFStringRef name = PlatformUtilities::juceStringToCFString (deviceName);
+
+ if (OK (MIDISourceCreate (globalMidiClient, name, &endPoint)))
+ {
+ mo = new MidiOutput();
+ mo->internal = (void*) new MidiPortAndEndpoint (0, endPoint);
+ }
+
+ CFRelease (name);
+ }
+
+ return mo;
+}
+
MidiOutput::~MidiOutput()
{
- MidiPortAndEndpoint* const mpe = (MidiPortAndEndpoint*)internal;
- MIDIPortDispose (mpe->port);
+ MidiPortAndEndpoint* const mpe = (MidiPortAndEndpoint*) internal;
delete mpe;
}
@@ -296,7 +327,7 @@ void MidiOutput::setVolume (float leftVol, float rightVol)
void MidiOutput::sendMessageNow (const MidiMessage& message)
{
- MidiPortAndEndpoint* const mpe = (MidiPortAndEndpoint*)internal;
+ MidiPortAndEndpoint* const mpe = (MidiPortAndEndpoint*) internal;
if (message.isSysEx())
{
@@ -318,7 +349,11 @@ void MidiOutput::sendMessageNow (const MidiMessage& message)
p = MIDIPacketNext (p);
}
- MIDISend (mpe->port, mpe->endPoint, packets);
+ if (mpe->port != 0)
+ MIDISend (mpe->port, mpe->endPoint, packets);
+ else
+ MIDIReceived (mpe->endPoint, packets);
+
juce_free (packets);
}
else
@@ -329,7 +364,10 @@ void MidiOutput::sendMessageNow (const MidiMessage& message)
packets.packet[0].length = message.getRawDataSize();
*(int*) (packets.packet[0].data) = *(const int*) message.getRawData();
- MIDISend (mpe->port, mpe->endPoint, &packets);
+ if (mpe->port != 0)
+ MIDISend (mpe->port, mpe->endPoint, &packets);
+ else
+ MIDIReceived (mpe->endPoint, &packets);
}
}
@@ -370,8 +408,7 @@ int MidiInput::getDefaultDeviceIndex()
struct MidiPortAndCallback
{
MidiInput* input;
- MIDIPortRef port;
- MIDIEndpointRef endPoint;
+ MidiPortAndEndpoint* portAndEndpoint;
MidiInputCallback* callback;
MemoryBlock pendingData;
int pendingBytes;
@@ -382,26 +419,26 @@ struct MidiPortAndCallback
static CriticalSection callbackLock;
static VoidArray activeCallbacks;
-static void processSysex (MidiPortAndCallback* const mpe, const uint8*& d, int& size, const double time)
+static void processSysex (MidiPortAndCallback* const mpc, const uint8*& d, int& size, const double time)
{
if (*d == 0xf0)
{
- mpe->pendingBytes = 0;
- mpe->pendingDataTime = time;
+ mpc->pendingBytes = 0;
+ mpc->pendingDataTime = time;
}
- mpe->pendingData.ensureSize (mpe->pendingBytes + size, false);
- uint8* totalMessage = (uint8*) mpe->pendingData.getData();
+ mpc->pendingData.ensureSize (mpc->pendingBytes + size, false);
+ uint8* totalMessage = (uint8*) mpc->pendingData.getData();
- uint8* dest = totalMessage + mpe->pendingBytes;
+ uint8* dest = totalMessage + mpc->pendingBytes;
while (size > 0)
{
- if (mpe->pendingBytes > 0 && *d >= 0x80)
+ if (mpc->pendingBytes > 0 && *d >= 0x80)
{
if (*d >= 0xfa || *d == 0xf8)
{
- mpe->callback->handleIncomingMidiMessage (mpe->input, MidiMessage (*d, time));
+ mpc->callback->handleIncomingMidiMessage (mpc->input, MidiMessage (*d, time));
++d;
--size;
}
@@ -410,7 +447,7 @@ static void processSysex (MidiPortAndCallback* const mpe, const uint8*& d, int&
if (*d == 0xf7)
{
*dest++ = *d++;
- mpe->pendingBytes++;
+ mpc->pendingBytes++;
--size;
}
@@ -420,24 +457,24 @@ static void processSysex (MidiPortAndCallback* const mpe, const uint8*& d, int&
else
{
*dest++ = *d++;
- mpe->pendingBytes++;
+ mpc->pendingBytes++;
--size;
}
}
- if (totalMessage [mpe->pendingBytes - 1] == 0xf7)
+ if (totalMessage [mpc->pendingBytes - 1] == 0xf7)
{
- mpe->callback->handleIncomingMidiMessage (mpe->input, MidiMessage (totalMessage,
- mpe->pendingBytes,
- mpe->pendingDataTime));
- mpe->pendingBytes = 0;
+ mpc->callback->handleIncomingMidiMessage (mpc->input, MidiMessage (totalMessage,
+ mpc->pendingBytes,
+ mpc->pendingDataTime));
+ mpc->pendingBytes = 0;
}
else
{
- mpe->callback->handlePartialSysexMessage (mpe->input,
+ mpc->callback->handlePartialSysexMessage (mpc->input,
totalMessage,
- mpe->pendingBytes,
- mpe->pendingDataTime);
+ mpc->pendingBytes,
+ mpc->pendingDataTime);
}
}
@@ -448,10 +485,10 @@ static void midiInputProc (const MIDIPacketList* pktlist,
double time = Time::getMillisecondCounterHiRes() * 0.001;
const double originalTime = time;
- MidiPortAndCallback* const mpe = (MidiPortAndCallback*) readProcRefCon;
+ MidiPortAndCallback* const mpc = (MidiPortAndCallback*) readProcRefCon;
const ScopedLock sl (callbackLock);
- if (activeCallbacks.contains (mpe) && mpe->active)
+ if (activeCallbacks.contains (mpc) && mpc->active)
{
const MIDIPacket* packet = &pktlist->packet[0];
@@ -464,9 +501,9 @@ static void midiInputProc (const MIDIPacketList* pktlist,
{
time = originalTime;
- if (mpe->pendingBytes > 0 || d[0] == 0xf0)
+ if (mpc->pendingBytes > 0 || d[0] == 0xf0)
{
- processSysex (mpe, d, size, time);
+ processSysex (mpc, d, size, time);
}
else
{
@@ -480,7 +517,7 @@ static void midiInputProc (const MIDIPacketList* pktlist,
}
else
{
- mpe->callback->handleIncomingMidiMessage (mpe->input, m);
+ mpc->callback->handleIncomingMidiMessage (mpc->input, m);
}
size -= used;
@@ -513,35 +550,34 @@ MidiInput* MidiInput::openDevice (int index, MidiInputCallback* callback)
{
MIDIPortRef port;
- MidiPortAndCallback* const mpe = new MidiPortAndCallback();
- mpe->active = false;
+ MidiPortAndCallback* const mpc = new MidiPortAndCallback();
+ mpc->active = false;
- if (OK (MIDIInputPortCreate (globalMidiClient, pname, midiInputProc, mpe, &port)))
+ if (OK (MIDIInputPortCreate (globalMidiClient, pname, midiInputProc, mpc, &port)))
{
if (OK (MIDIPortConnectSource (port, endPoint, 0)))
{
- mpe->port = port;
- mpe->endPoint = endPoint;
- mpe->callback = callback;
- mpe->pendingBytes = 0;
- mpe->pendingData.ensureSize (128);
+ mpc->portAndEndpoint = new MidiPortAndEndpoint (port, endPoint);
+ mpc->callback = callback;
+ mpc->pendingBytes = 0;
+ mpc->pendingData.ensureSize (128);
mi = new MidiInput (getDevices() [index]);
- mpe->input = mi;
- mi->internal = (void*) mpe;
+ mpc->input = mi;
+ mi->internal = (void*) mpc;
const ScopedLock sl (callbackLock);
- activeCallbacks.add (mpe);
+ activeCallbacks.add (mpc);
}
else
{
OK (MIDIPortDispose (port));
- delete mpe;
+ delete mpc;
}
}
else
{
- delete mpe;
+ delete mpc;
}
}
}
@@ -553,6 +589,42 @@ MidiInput* MidiInput::openDevice (int index, MidiInputCallback* callback)
return mi;
}
+MidiInput* MidiInput::createNewDevice (const String& deviceName, MidiInputCallback* callback)
+{
+ MidiInput* mi = 0;
+
+ if (makeSureClientExists())
+ {
+ MidiPortAndCallback* const mpc = new MidiPortAndCallback();
+ mpc->active = false;
+
+ MIDIEndpointRef endPoint;
+ CFStringRef name = PlatformUtilities::juceStringToCFString(deviceName);
+ if (OK (MIDIDestinationCreate (globalMidiClient, name, midiInputProc, mpc, &endPoint)))
+ {
+ mpc->portAndEndpoint = new MidiPortAndEndpoint (0, endPoint);
+ mpc->callback = callback;
+ mpc->pendingBytes = 0;
+ mpc->pendingData.ensureSize (128);
+
+ mi = new MidiInput (deviceName);
+ mpc->input = mi;
+ mi->internal = (void*) mpc;
+
+ const ScopedLock sl (callbackLock);
+ activeCallbacks.add (mpc);
+ }
+ else
+ {
+ delete mpc;
+ }
+
+ CFRelease (name);
+ }
+
+ return mi;
+}
+
MidiInput::MidiInput (const String& name_)
: name (name_)
{
@@ -560,30 +632,32 @@ MidiInput::MidiInput (const String& name_)
MidiInput::~MidiInput()
{
- MidiPortAndCallback* const mpe = (MidiPortAndCallback*) internal;
- mpe->active = false;
+ MidiPortAndCallback* const mpc = (MidiPortAndCallback*) internal;
+ mpc->active = false;
callbackLock.enter();
- activeCallbacks.removeValue (mpe);
+ activeCallbacks.removeValue (mpc);
callbackLock.exit();
- OK (MIDIPortDisconnectSource (mpe->port, mpe->endPoint));
- OK (MIDIPortDispose (mpe->port));
- delete mpe;
+ if (mpc->portAndEndpoint->port != 0)
+ OK (MIDIPortDisconnectSource (mpc->portAndEndpoint->port, mpc->portAndEndpoint->endPoint));
+
+ delete mpc->portAndEndpoint;
+ delete mpc;
}
void MidiInput::start()
{
- MidiPortAndCallback* const mpe = (MidiPortAndCallback*) internal;
+ MidiPortAndCallback* const mpc = (MidiPortAndCallback*) internal;
const ScopedLock sl (callbackLock);
- mpe->active = true;
+ mpc->active = true;
}
void MidiInput::stop()
{
- MidiPortAndCallback* const mpe = (MidiPortAndCallback*) internal;
+ MidiPortAndCallback* const mpc = (MidiPortAndCallback*) internal;
const ScopedLock sl (callbackLock);
- mpe->active = false;
+ mpc->active = false;
}
#undef log
diff --git a/src/native/mac/juce_mac_Fonts.mm b/src/native/mac/juce_mac_Fonts.mm
index 25897367c4..16a3899056 100644
--- a/src/native/mac/juce_mac_Fonts.mm
+++ b/src/native/mac/juce_mac_Fonts.mm
@@ -31,6 +31,10 @@
#define SUPPORT_10_4_FONTS 1
#define NEW_CGFONT_FUNCTIONS_UNAVAILABLE (CGFontCreateWithFontName == 0)
+ #if MAC_OS_X_VERSION_MAX_ALLOWED < MAC_OS_X_VERSION_10_5
+ #define SUPPORT_ONLY_10_4_FONTS 1
+ #endif
+
END_JUCE_NAMESPACE
@interface NSFont (PrivateHack)
- (NSGlyph) _defaultGlyphForChar: (unichar) theChar;
@@ -44,8 +48,10 @@ class MacTypeface : public Typeface
public:
//==============================================================================
MacTypeface (const Font& font)
- : Typeface (font.getTypefaceName()),
- charToGlyphMapper (0)
+ : Typeface (font.getTypefaceName())
+#if ! SUPPORT_ONLY_10_4_FONTS
+ , charToGlyphMapper (0)
+#endif
{
const ScopedAutoReleasePool pool;
renderingTransform = CGAffineTransformIdentity;
@@ -90,9 +96,11 @@ public:
fontRef = CGFontCreateWithFontName ((CFStringRef) fontName);
- const int totalHeight = abs (CGFontGetAscent (fontRef)) + abs (CGFontGetDescent (fontRef));
+ const int ascender = abs (CGFontGetAscent (fontRef));
+ const float totalHeight = ascender + abs (CGFontGetDescent (fontRef));
+ ascent = ascender / totalHeight;
unitsToHeightScaleFactor = 1.0f / totalHeight;
- fontHeightToCGSizeFactor = CGFontGetUnitsPerEm (fontRef) / (float) totalHeight;
+ fontHeightToCGSizeFactor = CGFontGetUnitsPerEm (fontRef) / totalHeight;
#else
nsFont = [NSFont fontWithName: juceStringToNS (font.getTypefaceName()) size: 1024];
@@ -124,7 +132,19 @@ public:
renderingTransform.c = 0.15f;
}
-#if SUPPORT_10_4_FONTS
+#if SUPPORT_ONLY_10_4_FONTS
+ ATSFontRef atsFont = ATSFontFindFromName ((CFStringRef) [nsFont fontName], kATSOptionFlagsDefault);
+
+ if (atsFont == 0)
+ atsFont = ATSFontFindFromPostScriptName ((CFStringRef) [nsFont fontName], kATSOptionFlagsDefault);
+
+ fontRef = CGFontCreateWithPlatformFont ((void*) &atsFont);
+
+ const float totalHeight = fabsf ([nsFont ascender]) + fabsf([nsFont descender]);
+ unitsToHeightScaleFactor = 1.0f / totalHeight;
+ fontHeightToCGSizeFactor = 1024.0f / totalHeight;
+#else
+ #if SUPPORT_10_4_FONTS
if (NEW_CGFONT_FUNCTIONS_UNAVAILABLE)
{
ATSFontRef atsFont = ATSFontFindFromName ((CFStringRef) [nsFont fontName], kATSOptionFlagsDefault);
@@ -139,7 +159,7 @@ public:
fontHeightToCGSizeFactor = 1024.0f / totalHeight;
}
else
-#endif
+ #endif
{
fontRef = CGFontCreateWithFontName ((CFStringRef) [nsFont fontName]);
@@ -147,18 +167,22 @@ public:
unitsToHeightScaleFactor = 1.0f / totalHeight;
fontHeightToCGSizeFactor = CGFontGetUnitsPerEm (fontRef) / (float) totalHeight;
}
+#endif
#endif
}
~MacTypeface()
{
+#if ! JUCE_IPHONE
[nsFont release];
-
+#endif
if (fontRef != 0)
CGFontRelease (fontRef);
+#if ! SUPPORT_ONLY_10_4_FONTS
delete charToGlyphMapper;
+#endif
}
float getAscent() const
@@ -181,7 +205,16 @@ public:
int x = 0;
-#if SUPPORT_10_4_FONTS
+#if SUPPORT_ONLY_10_4_FONTS
+ NSSize* const advances = (NSSize*) juce_malloc (length * sizeof (NSSize));
+ [nsFont getAdvancements: advances forGlyphs: (NSGlyph*) glyphs count: length];
+
+ for (int i = 0; i < length; ++i)
+ x += advances[i].width;
+
+ juce_free (advances);
+#else
+ #if SUPPORT_10_4_FONTS
if (NEW_CGFONT_FUNCTIONS_UNAVAILABLE)
{
NSSize* const advances = (NSSize*) juce_malloc (length * sizeof (NSSize));
@@ -193,7 +226,7 @@ public:
juce_free (advances);
}
else
-#endif
+ #endif
{
int* const advances = (int*) juce_malloc (length * sizeof (int));
@@ -203,6 +236,7 @@ public:
juce_free (advances);
}
+#endif
juce_free (glyphs);
@@ -219,7 +253,21 @@ public:
const int length = text.length();
CGGlyph* const glyphs = createGlyphsForString (text, length);
-#if SUPPORT_10_4_FONTS
+#if SUPPORT_ONLY_10_4_FONTS
+ NSSize* const advances = (NSSize*) juce_malloc (length * sizeof (NSSize));
+ [nsFont getAdvancements: advances forGlyphs: (NSGlyph*) glyphs count: length];
+
+ int x = 0;
+ for (int i = 0; i < length; ++i)
+ {
+ x += advances[i].width;
+ xOffsets.add (x * unitsToHeightScaleFactor);
+ resultGlyphs.add (((NSGlyph*) glyphs)[i]);
+ }
+
+ juce_free (advances);
+#else
+ #if SUPPORT_10_4_FONTS
if (NEW_CGFONT_FUNCTIONS_UNAVAILABLE)
{
NSSize* const advances = (NSSize*) juce_malloc (length * sizeof (NSSize));
@@ -236,7 +284,7 @@ public:
juce_free (advances);
}
else
-#endif
+ #endif
{
int* const advances = (int*) juce_malloc (length * sizeof (int));
@@ -253,6 +301,7 @@ public:
juce_free (advances);
}
+#endif
juce_free (glyphs);
}
@@ -323,7 +372,9 @@ private:
CGGlyph* createGlyphsForString (const juce_wchar* const text, const int length) throw()
{
#if SUPPORT_10_4_FONTS
+ #if ! SUPPORT_ONLY_10_4_FONTS
if (NEW_CGFONT_FUNCTIONS_UNAVAILABLE)
+ #endif
{
NSGlyph* const g = (NSGlyph*) juce_malloc (sizeof (NSGlyph) * length);
@@ -333,6 +384,8 @@ private:
return (CGGlyph*) g;
}
#endif
+
+#if ! SUPPORT_ONLY_10_4_FONTS
if (charToGlyphMapper == 0)
charToGlyphMapper = new CharToGlyphMapper (fontRef);
@@ -342,8 +395,10 @@ private:
g[i] = (CGGlyph) charToGlyphMapper->getGlyphForCharacter (text[i]);
return g;
+#endif
}
+#if ! SUPPORT_ONLY_10_4_FONTS
// Reads a CGFontRef's character map table to convert unicode into glyph numbers
class CharToGlyphMapper
{
@@ -442,6 +497,7 @@ private:
};
CharToGlyphMapper* charToGlyphMapper;
+#endif
};
const Typeface::Ptr Typeface::createSystemTypefaceFor (const Font& font)
@@ -471,9 +527,15 @@ const StringArray Font::findAllTypefaceNames() throw()
void Font::getPlatformDefaultFontNames (String& defaultSans, String& defaultSerif, String& defaultFixed) throw()
{
+#if JUCE_IPHONE
+ defaultSans = "Helvetica";
+ defaultSerif = "Times New Roman";
+ defaultFixed = "Courier New";
+#else
defaultSans = "Lucida Grande";
defaultSerif = "Times New Roman";
defaultFixed = "Monaco";
+#endif
}
#endif
diff --git a/src/native/mac/juce_mac_MiscUtilities.mm b/src/native/mac/juce_mac_MiscUtilities.mm
index b5f511488c..fda70de5b0 100644
--- a/src/native/mac/juce_mac_MiscUtilities.mm
+++ b/src/native/mac/juce_mac_MiscUtilities.mm
@@ -149,18 +149,12 @@ void Desktop::setMousePosition (int x, int y) throw()
// this rubbish needs to be done around the warp call, to avoid causing a
// bizarre glitch..
CGAssociateMouseAndMouseCursorPosition (false);
-#if (! defined (MAC_OS_X_VERSION_10_6)) || MAC_OS_X_VERSION_MAX_ALLOWED < MAC_OS_X_VERSION_10_6
- CGSetLocalEventsSuppressionInterval (0);
-#endif
-
- CGPoint pos = { x, y };
- CGWarpMouseCursorPosition (pos);
-
+ CGWarpMouseCursorPosition (CGPointMake (x, y));
CGAssociateMouseAndMouseCursorPosition (true);
}
//==============================================================================
-#if MACOS_10_4_OR_EARLIER
+#if MAC_OS_X_VERSION_MIN_REQUIRED < MAC_OS_X_VERSION_10_5
class ScreenSaverDefeater : public Timer,
public DeletedAtShutdown
{
diff --git a/src/native/mac/juce_mac_QuickTimeMovieComponent.mm b/src/native/mac/juce_mac_QuickTimeMovieComponent.mm
index 072d537f12..9c45774881 100644
--- a/src/native/mac/juce_mac_QuickTimeMovieComponent.mm
+++ b/src/native/mac/juce_mac_QuickTimeMovieComponent.mm
@@ -89,6 +89,12 @@ static QTMovie* openMovieFromStream (InputStream* movieStream, File& movieFile)
return movie;
}
+bool QuickTimeMovieComponent::loadMovie (const File& movieFile_,
+ const bool isControllerVisible)
+{
+ return loadMovie ((InputStream*) movieFile_.createInputStream(), isControllerVisible);
+}
+
bool QuickTimeMovieComponent::loadMovie (InputStream* movieStream,
const bool controllerVisible)
{
@@ -113,6 +119,36 @@ bool QuickTimeMovieComponent::loadMovie (InputStream* movieStream,
return movie != nil;
}
+bool QuickTimeMovieComponent::loadMovie (const URL& movieURL,
+ const bool isControllerVisible)
+{
+ // unfortunately, QTMovie objects can only be created on the main thread..
+ jassert (MessageManager::getInstance()->isThisTheMessageThread());
+
+ closeMovie();
+
+ if (getPeer() == 0)
+ {
+ // To open a movie, this component must be visible inside a functioning window, so that
+ // the QT control can be assigned to the window.
+ jassertfalse
+ return false;
+ }
+
+ NSURL* url = [NSURL URLWithString: juceStringToNS (movieURL.toString (true))];
+ NSError* err;
+ if ([QTMovie canInitWithURL: url])
+ movie = [QTMovie movieWithURL: url error: &err];
+
+ [theMovie retain];
+ QTMovieView* view = (QTMovieView*) getView();
+ [view setMovie: theMovie];
+ [view setControllerVisible: controllerVisible];
+ setLooping (looping);
+
+ return movie != nil;
+}
+
void QuickTimeMovieComponent::closeMovie()
{
stop();
@@ -232,14 +268,6 @@ bool QuickTimeMovieComponent::isControllerVisible() const
}
//==============================================================================
-bool QuickTimeMovieComponent::loadMovie (const File& movieFile_,
- const bool isControllerVisible)
-{
- const bool ok = loadMovie ((InputStream*) movieFile_.createInputStream(), isControllerVisible);
- movieFile = movieFile_;
- return ok;
-}
-
void QuickTimeMovieComponent::goToStart()
{
setPosition (0.0);
diff --git a/src/native/mac/juce_mac_SystemStats.mm b/src/native/mac/juce_mac_SystemStats.mm
index d810d747a1..59c78259e5 100644
--- a/src/native/mac/juce_mac_SystemStats.mm
+++ b/src/native/mac/juce_mac_SystemStats.mm
@@ -211,7 +211,7 @@ int SystemStats::getCpuSpeedInMegaherz() throw()
int SystemStats::getNumCpus() throw()
{
-#if MACOS_10_4_OR_EARLIER
+#if MAC_OS_X_VERSION_MIN_REQUIRED < MAC_OS_X_VERSION_10_5
return MPProcessors();
#else
return [[NSProcessInfo processInfo] activeProcessorCount];
diff --git a/src/native/windows/juce_win32_QuickTimeMovieComponent.cpp b/src/native/windows/juce_win32_QuickTimeMovieComponent.cpp
index aaa2f66c5d..b1b4f1b815 100644
--- a/src/native/windows/juce_win32_QuickTimeMovieComponent.cpp
+++ b/src/native/windows/juce_win32_QuickTimeMovieComponent.cpp
@@ -474,6 +474,12 @@ bool QuickTimeMovieComponent::loadMovie (const File& movieFile_,
return ok;
}
+bool QuickTimeMovieComponent::loadMovie (const URL& movieURL,
+ const bool isControllerVisible)
+{
+ return loadMovie ((InputStream*) movieURL_.createInputStream (false), isControllerVisible);
+}
+
void QuickTimeMovieComponent::goToStart()
{
setPosition (0.0);
diff --git a/src/native/windows/juce_win32_Windowing.cpp b/src/native/windows/juce_win32_Windowing.cpp
index d40ff2f6a3..15b653997c 100644
--- a/src/native/windows/juce_win32_Windowing.cpp
+++ b/src/native/windows/juce_win32_Windowing.cpp
@@ -2336,6 +2336,12 @@ void Desktop::setMousePosition (int x, int y) throw()
SetCursorPos (x, y);
}
+//==============================================================================
+Image* Image::createNativeImage (const PixelFormat format, const int imageWidth, const int imageHeight, const bool clearImage)
+{
+ return new Image (format, imageWidth, imageHeight, clearImage);
+}
+
//==============================================================================
class ScreenSaverDefeater : public Timer,
public DeletedAtShutdown
diff --git a/src/text/juce_CharacterFunctions.cpp b/src/text/juce_CharacterFunctions.cpp
index b9f02d098d..672df27ae4 100644
--- a/src/text/juce_CharacterFunctions.cpp
+++ b/src/text/juce_CharacterFunctions.cpp
@@ -772,14 +772,7 @@ int CharacterFunctions::vprintf (char* const dest, const int maxLength, const ch
int CharacterFunctions::vprintf (juce_wchar* const dest, const int maxLength, const juce_wchar* const format, va_list& args) throw()
{
-#if MACOS_10_3_OR_EARLIER
- const String formatTemp (format);
- size_t num = vprintf ((char*) dest, maxLength, formatTemp, args);
- String temp ((char*) dest);
- temp.copyToBuffer (dest, num);
- dest [num] = 0;
- return (int) num;
-#elif defined (JUCE_WIN32)
+#if defined (JUCE_WIN32)
return (int) _vsnwprintf (dest, maxLength, format, args);
#else
return (int) vswprintf (dest, maxLength, format, args);