1
0
Fork 0
mirror of https://github.com/juce-framework/JUCE.git synced 2026-01-21 01:24:21 +00:00

The first working check-in of an iPhone build! Added an iPhone project for the normal juce demo, which runs.. although it isn't exactly designed for a hand-held form factor!

Also in this check-in is support for creation of custom Mac MIDI input and output devices, and an option to load URLs with the QuickTimeComponent
This commit is contained in:
Julian Storer 2009-11-13 16:17:22 +00:00
parent 6c66134173
commit d779fa9759
56 changed files with 3074 additions and 1166 deletions

View file

@ -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;
};

View file

@ -0,0 +1,28 @@
<?xml version="1.0" encoding="UTF-8"?>
<!DOCTYPE plist PUBLIC "-//Apple//DTD PLIST 1.0//EN" "http://www.apple.com/DTDs/PropertyList-1.0.dtd">
<plist version="1.0">
<dict>
<key>CFBundleDevelopmentRegion</key>
<string>English</string>
<key>CFBundleDisplayName</key>
<string>${PRODUCT_NAME}</string>
<key>CFBundleExecutable</key>
<string>${EXECUTABLE_NAME}</string>
<key>CFBundleIconFile</key>
<string></string>
<key>CFBundleIdentifier</key>
<string>com.synchromation.rawmaterial</string>
<key>CFBundleInfoDictionaryVersion</key>
<string>6.0</string>
<key>CFBundleName</key>
<string>${PRODUCT_NAME}</string>
<key>CFBundlePackageType</key>
<string>APPL</string>
<key>CFBundleSignature</key>
<string>????</string>
<key>CFBundleVersion</key>
<string>1.0</string>
<key>LSRequiresIPhoneOS</key>
<true/>
</dict>
</plist>

View file

@ -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 = "<absolute>"; };
840F1D9B10AD6701002A03A6 /* CodeEditorDemo.cpp */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.cpp.cpp; path = CodeEditorDemo.cpp; sourceTree = "<group>"; };
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 = "<group>"; };
84816891107E7DA6008FEC33 /* DragAndDropDemo.cpp */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.cpp.cpp; path = DragAndDropDemo.cpp; sourceTree = "<group>"; };
84816892107E7DA6008FEC33 /* InterprocessCommsDemo.cpp */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.cpp.cpp; path = InterprocessCommsDemo.cpp; sourceTree = "<group>"; };
84816893107E7DA6008FEC33 /* OpenGLDemo.cpp */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.cpp.cpp; path = OpenGLDemo.cpp; sourceTree = "<group>"; };
84816894107E7DA6008FEC33 /* PathsAndTransformsDemo.cpp */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.cpp.cpp; path = PathsAndTransformsDemo.cpp; sourceTree = "<group>"; };
84816895107E7DA6008FEC33 /* QuickTimeDemo.cpp */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.cpp.cpp; path = QuickTimeDemo.cpp; sourceTree = "<group>"; };
84816896107E7DA6008FEC33 /* TableDemo.cpp */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.cpp.cpp; path = TableDemo.cpp; sourceTree = "<group>"; };
84816897107E7DA6008FEC33 /* ThreadingDemo.cpp */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.cpp.cpp; path = ThreadingDemo.cpp; sourceTree = "<group>"; };
84816898107E7DA6008FEC33 /* AudioDemoTabComponent.cpp */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.cpp.cpp; path = AudioDemoTabComponent.cpp; sourceTree = "<group>"; };
84816899107E7DA6008FEC33 /* WebBrowserDemo.cpp */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.cpp.cpp; path = WebBrowserDemo.cpp; sourceTree = "<group>"; };
8481689A107E7DA6008FEC33 /* WidgetsDemo.cpp */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.cpp.cpp; path = WidgetsDemo.cpp; sourceTree = "<group>"; };
8481689B107E7DA6008FEC33 /* AudioDemoSetupPage.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = AudioDemoSetupPage.h; sourceTree = "<group>"; };
8481689C107E7DA6008FEC33 /* AudioDemoLatencyPage.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = AudioDemoLatencyPage.h; sourceTree = "<group>"; };
8481689D107E7DA6008FEC33 /* AudioDemoRecordPage.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = AudioDemoRecordPage.h; sourceTree = "<group>"; };
8481689E107E7DA6008FEC33 /* AudioDemoPlaybackPage.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = AudioDemoPlaybackPage.h; sourceTree = "<group>"; };
8481689F107E7DA6008FEC33 /* AudioDemoSetupPage.cpp */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.cpp.cpp; path = AudioDemoSetupPage.cpp; sourceTree = "<group>"; };
848168A0107E7DA6008FEC33 /* AudioDemoPlaybackPage.cpp */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.cpp.cpp; path = AudioDemoPlaybackPage.cpp; sourceTree = "<group>"; };
848168A1107E7DA6008FEC33 /* AudioDemoSynthPage.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = AudioDemoSynthPage.h; sourceTree = "<group>"; };
848168A2107E7DA6008FEC33 /* AudioDemoTabComponent.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = AudioDemoTabComponent.h; sourceTree = "<group>"; };
848168A3107E7DA6008FEC33 /* AudioDemoSynthPage.cpp */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.cpp.cpp; path = AudioDemoSynthPage.cpp; sourceTree = "<group>"; };
848168A4107E7DA6008FEC33 /* AudioDemoRecordPage.cpp */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.cpp.cpp; path = AudioDemoRecordPage.cpp; sourceTree = "<group>"; };
848168A5107E7DA6008FEC33 /* TreeViewDemo.cpp */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.cpp.cpp; path = TreeViewDemo.cpp; sourceTree = "<group>"; };
848168A6107E7DA6008FEC33 /* FontsAndTextDemo.cpp */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.cpp.cpp; path = FontsAndTextDemo.cpp; sourceTree = "<group>"; };
848168A7107E7DA6008FEC33 /* AudioDemoLatencyPage.cpp */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.cpp.cpp; path = AudioDemoLatencyPage.cpp; sourceTree = "<group>"; };
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 = "<group>"; };
/* 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 = "<group>";
};
29B97314FDCFA39411CA2CEA /* CustomTemplate */ = {
isa = PBXGroup;
children = (
29B97315FDCFA39411CA2CEA /* Other Sources */,
29B97317FDCFA39411CA2CEA /* Resources */,
29B97323FDCFA39411CA2CEA /* Frameworks */,
19C28FACFE9D520D11CA2CBB /* Products */,
);
name = CustomTemplate;
sourceTree = "<group>";
};
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 = "<group>";
};
29B97317FDCFA39411CA2CEA /* Resources */ = {
isa = PBXGroup;
children = (
8D1107310486CEB800E47090 /* JuceDemo-Info.plist */,
);
name = Resources;
sourceTree = "<group>";
};
29B97323FDCFA39411CA2CEA /* Frameworks */ = {
isa = PBXGroup;
children = (
848170FB1080CB2A008FEC33 /* Juce.xcodeproj */,
1DF5F4DF0D08C38300B7A737 /* UIKit.framework */,
1D30AB110D05D00D00671497 /* Foundation.framework */,
288765FC0DF74451002DB57D /* CoreGraphics.framework */,
840F1D8410AD66DE002A03A6 /* AudioToolbox.framework */,
);
name = Frameworks;
sourceTree = "<group>";
};
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 = "<group>";
};
/* 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 */;
}

View file

@ -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=""/>
<LABEL name="" id="1162fb2599a768b4" memberName="explanationLabel" virtualName=""
explicitFocusOrder="0" pos="184 88 194M 120" edTextCol="ff000000"
edBkgCol="0" labelText="This page demonstrates how to record a wave file from the live audio input..&#10;&#10;Pressing record will start recording a file to your desktop."
explicitFocusOrder="0" pos="160 88 169M 216" edTextCol="ff000000"
edBkgCol="0" labelText="This page demonstrates how to record a wave file from the live audio input..&#10;&#10;Pressing record will start recording a file in your &quot;Documents&quot; folder."
editableSingleClick="0" editableDoubleClick="0" focusDiscardsChanges="0"
fontname="Default font" fontsize="15" bold="0" italic="0" justification="9"/>
<TEXTBUTTON name="" id="2c10a0ba9fad39da" memberName="recordButton" virtualName=""

View file

@ -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
@ -19,8 +19,8 @@
==============================================================================
*/
#ifndef __JUCER_HEADER_AUDIODEMORECORDPAGE_AUDIODEMORECORDPAGE_9632FFAA__
#define __JUCER_HEADER_AUDIODEMORECORDPAGE_AUDIODEMORECORDPAGE_9632FFAA__
#ifndef __JUCER_HEADER_AUDIODEMORECORDPAGE_AUDIODEMORECORDPAGE_4FF281BF__
#define __JUCER_HEADER_AUDIODEMORECORDPAGE_AUDIODEMORECORDPAGE_4FF281BF__
//[Headers] -- You can add your own extra header files here --
#include "../jucedemo_headers.h"
@ -77,4 +77,4 @@ private:
};
#endif // __JUCER_HEADER_AUDIODEMORECORDPAGE_AUDIODEMORECORDPAGE_9632FFAA__
#endif // __JUCER_HEADER_AUDIODEMORECORDPAGE_AUDIODEMORECORDPAGE_4FF281BF__

File diff suppressed because it is too large Load diff

View file

@ -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 <CoreServices/CoreServices.h>
#else
#include <libkern/OSAtomic.h>
#endif
#include <libkern/OSAtomic.h>
#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 <libkern/OSAtomic.h>
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 <class EdgeTableIterationCallback>
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);

View file

@ -108,6 +108,7 @@ const OwnedArray <AudioIODeviceType>& 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 <AudioIODeviceType>&
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

View file

@ -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.

View file

@ -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.

View file

@ -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

View file

@ -33,20 +33,12 @@
//==============================================================================
#if (JUCE_MAC || JUCE_IPHONE) && ! DOXYGEN
#if ! MACOS_10_3_OR_EARLIER
//==============================================================================
#include <libkern/OSAtomic.h>
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
//==============================================================================

View file

@ -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

View file

@ -83,11 +83,7 @@
#endif
#if JUCE_MAC
#if MACOS_10_3_OR_EARLIER
#include <CoreServices/CoreServices.h>
#else
#include <libkern/OSAtomic.h>
#endif
#include <libkern/OSAtomic.h>
#endif
#if JUCE_LINUX

View file

@ -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
//==============================================================================

View file

@ -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);

View file

@ -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));
}

View file

@ -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(),

View file

@ -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
{

View file

@ -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);

View file

@ -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);

View file

@ -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));

View file

@ -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);

View file

@ -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()
{

View file

@ -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

View file

@ -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));
}
//==============================================================================

View file

@ -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

View file

@ -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 <class EdgeTableIterationCallback>
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();
};

View file

@ -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 <PixelRGB, RadialGradientPixelGenerator> renderer (pixels, stride, g2, lookupTable, numLookupEntries);
edgeTable.iterate (renderer, 0, 0, cw, ch, 0);
edgeTable.iterate (renderer);
}
else
{
GradientEdgeTableRenderer <PixelRGB, TransformedRadialGradientPixelGenerator> renderer (pixels, stride, g2, lookupTable, numLookupEntries);
edgeTable.iterate (renderer, 0, 0, cw, ch, 0);
edgeTable.iterate (renderer);
}
}
else
{
GradientEdgeTableRenderer <PixelRGB, LinearGradientPixelGenerator> 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 <PixelARGB, RadialGradientPixelGenerator> renderer (pixels, stride, g2, lookupTable, numLookupEntries);
edgeTable.iterate (renderer, 0, 0, cw, ch, 0);
edgeTable.iterate (renderer);
}
else
{
GradientEdgeTableRenderer <PixelARGB, TransformedRadialGradientPixelGenerator> renderer (pixels, stride, g2, lookupTable, numLookupEntries);
edgeTable.iterate (renderer, 0, 0, cw, ch, 0);
edgeTable.iterate (renderer);
}
}
else
{
GradientEdgeTableRenderer <PixelARGB, LinearGradientPixelGenerator> 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 <PixelRGB> 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 <PixelARGB> 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 <PixelRGB, PixelRGB> 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 <PixelRGB, PixelARGB> 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 <PixelARGB, PixelRGB> 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 <PixelARGB, PixelARGB> renderer (pixels, stride,
srcPix, srcStride,
alpha, (PixelARGB*) 0);
edgeTable.iterate (renderer, 0, 0, w, h, 0);
edgeTable.iterate (renderer);
}
else
{

View file

@ -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();

View file

@ -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()

View file

@ -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

View file

@ -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;

View file

@ -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);

View file

@ -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.
*/

View file

@ -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,

View file

@ -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)
{

View file

@ -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);

View file

@ -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())
{

View file

@ -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; }

View file

@ -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"

View file

@ -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

View file

@ -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;
}

View file

@ -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)

View file

@ -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()
{

View file

@ -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;

View file

@ -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 <double> sampleRates;
Array <int> 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

View file

@ -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 <SavedState> 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 <const CoreGraphicsImage*> (&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

View file

@ -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

View file

@ -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

View file

@ -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
{

View file

@ -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);

View file

@ -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];

View file

@ -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);

View file

@ -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

View file

@ -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);