├── Cartfile ├── Archimedes ├── en.lproj │ └── InfoPlist.strings ├── Archimedes.h ├── Info.plist ├── Archimedes-Info.plist ├── MEDEdgeInsets.m ├── MEDEdgeInsets.h ├── NSValue+MEDGeometryAdditions.h ├── NSValue+MEDGeometryAdditions.m ├── CGGeometry+MEDConvenienceAdditions.m └── CGGeometry+MEDConvenienceAdditions.h ├── ArchimedesTests ├── en.lproj │ └── InfoPlist.strings ├── MEDGeometryTestObject.m ├── MEDGeometryTestObject.h ├── SwiftSpec.swift ├── ArchimedesTests-Info.plist ├── Info.plist ├── MEDEdgeInsetsSpec.m ├── MEDNSValueAdditionsSpec.m └── MEDCGGeometryAdditionsSpec.m ├── Cartfile.private ├── Cartfile.resolved ├── script ├── schemes.awk ├── targets.awk ├── xctool.awk ├── xcodebuild.awk ├── LICENSE.md ├── bootstrap ├── README.md └── cibuild ├── .gitignore ├── .travis.yml ├── .gitmodules ├── Archimedes.xcworkspace └── contents.xcworkspacedata ├── README.md ├── CONTRIBUTING.md ├── LICENSE.md └── Archimedes.xcodeproj ├── xcshareddata └── xcschemes │ ├── Archimedes Mac.xcscheme │ └── Archimedes iOS.xcscheme └── project.pbxproj /Cartfile: -------------------------------------------------------------------------------- 1 | -------------------------------------------------------------------------------- /Archimedes/en.lproj/InfoPlist.strings: -------------------------------------------------------------------------------- 1 | /* Localized versions of Info.plist keys */ 2 | 3 | -------------------------------------------------------------------------------- /ArchimedesTests/en.lproj/InfoPlist.strings: -------------------------------------------------------------------------------- 1 | /* Localized versions of Info.plist keys */ 2 | 3 | -------------------------------------------------------------------------------- /Cartfile.private: -------------------------------------------------------------------------------- 1 | github "jspahrsummers/xcconfigs" >= 0.7.1 2 | github "Quick/Quick" ~> 0.2 3 | github "Quick/Nimble" ~> 0.2 4 | -------------------------------------------------------------------------------- /Cartfile.resolved: -------------------------------------------------------------------------------- 1 | github "Quick/Nimble" "v0.2.0" 2 | github "Quick/Quick" "v0.2.3" 3 | github "jspahrsummers/xcconfigs" "0.8.1" 4 | -------------------------------------------------------------------------------- /script/schemes.awk: -------------------------------------------------------------------------------- 1 | BEGIN { 2 | FS = "\n"; 3 | } 4 | 5 | /Schemes:/ { 6 | while (getline && $0 != "") { 7 | sub(/^ +/, ""); 8 | print "'" $0 "'"; 9 | } 10 | } 11 | -------------------------------------------------------------------------------- /script/targets.awk: -------------------------------------------------------------------------------- 1 | BEGIN { 2 | FS = "\n"; 3 | } 4 | 5 | /Targets:/ { 6 | while (getline && $0 != "") { 7 | if ($0 ~ /Tests/) continue; 8 | 9 | sub(/^ +/, ""); 10 | print "'" $0 "'"; 11 | } 12 | } 13 | -------------------------------------------------------------------------------- /.gitignore: -------------------------------------------------------------------------------- 1 | # Xcode 2 | build/* 3 | *.pbxuser 4 | !default.pbxuser 5 | *.mode1v3 6 | !default.mode1v3 7 | *.mode2v3 8 | !default.mode2v3 9 | *.perspectivev3 10 | !default.perspectivev3 11 | *.xcworkspace 12 | !default.xcworkspace 13 | xcuserdata 14 | profile 15 | *.moved-aside 16 | -------------------------------------------------------------------------------- /ArchimedesTests/MEDGeometryTestObject.m: -------------------------------------------------------------------------------- 1 | // 2 | // MEDGeometryTestObject.m 3 | // Archimedes 4 | // 5 | // Created by Justin Spahr-Summers on 2012-10-15. 6 | // Copyright (c) 2012 GitHub. All rights reserved. 7 | // 8 | 9 | #import "MEDGeometryTestObject.h" 10 | 11 | @implementation MEDGeometryTestObject 12 | @end 13 | -------------------------------------------------------------------------------- /.travis.yml: -------------------------------------------------------------------------------- 1 | language: objective-c 2 | script: script/cibuild 3 | notifications: 4 | email: false 5 | campfire: 6 | on_success: always 7 | on_failure: always 8 | rooms: 9 | - secure: "QVVzkmaWyLgGMOgtaBF2EUQS3Ot1Bj7jc8CI7L1mqxrDpNnxtemgSNBkvFNrec0RoSMiHBY9t+aVdnHsCLlqhDs3mX55zxlbTJPDpFTVI2p77n90teuOr1kK+a3DYoyaxO6acrAJwhjOe6j9zd3o/su+VG5OsXqCXhBFfnc863w=" 10 | -------------------------------------------------------------------------------- /.gitmodules: -------------------------------------------------------------------------------- 1 | [submodule "Carthage.checkout/Nimble"] 2 | path = Carthage/Checkouts/Nimble 3 | url = https://github.com/Quick/Nimble.git 4 | [submodule "Carthage.checkout/Quick"] 5 | path = Carthage/Checkouts/Quick 6 | url = https://github.com/Quick/Quick.git 7 | [submodule "Carthage.checkout/xcconfigs"] 8 | path = Carthage/Checkouts/xcconfigs 9 | url = https://github.com/jspahrsummers/xcconfigs.git 10 | -------------------------------------------------------------------------------- /Archimedes.xcworkspace/contents.xcworkspacedata: -------------------------------------------------------------------------------- 1 | 2 | 4 | 6 | 7 | 9 | 10 | 12 | 13 | 14 | -------------------------------------------------------------------------------- /script/xctool.awk: -------------------------------------------------------------------------------- 1 | # Exit statuses: 2 | # 3 | # 0 - No errors found. 4 | # 1 - Wrong SDK. Retry with SDK `iphonesimulator`. 5 | # 2 - Missing target. 6 | 7 | BEGIN { 8 | status = 0; 9 | } 10 | 11 | { 12 | print; 13 | } 14 | 15 | /Testing with the '(.+)' SDK is not yet supported/ { 16 | status = 1; 17 | } 18 | 19 | /does not contain a target named/ { 20 | status = 2; 21 | } 22 | 23 | END { 24 | exit status; 25 | } 26 | -------------------------------------------------------------------------------- /ArchimedesTests/MEDGeometryTestObject.h: -------------------------------------------------------------------------------- 1 | // 2 | // MEDGeometryTestObject.h 3 | // Archimedes 4 | // 5 | // Created by Justin Spahr-Summers on 2012-10-15. 6 | // Copyright (c) 2012 GitHub. All rights reserved. 7 | // 8 | 9 | #import 10 | #import 11 | 12 | @interface MEDGeometryTestObject : NSObject 13 | 14 | @property (nonatomic, assign) CGRect slice; 15 | @property (nonatomic, assign) CGRect remainder; 16 | 17 | @end 18 | -------------------------------------------------------------------------------- /ArchimedesTests/SwiftSpec.swift: -------------------------------------------------------------------------------- 1 | // 2 | // SwiftSpec.swift 3 | // Archimedes 4 | // 5 | // Created by Justin Spahr-Summers on 2014-10-02. 6 | // Copyright (c) 2014 GitHub. All rights reserved. 7 | // 8 | 9 | import Foundation 10 | import Nimble 11 | import Quick 12 | 13 | // Without this, the Swift stdlib won't be linked into the test target (even if 14 | // “Embedded Content Contains Swift Code” is enabled). 15 | class SwiftSpec: QuickSpec { 16 | override func spec() { 17 | expect(true).to(beTruthy()) 18 | } 19 | } 20 | -------------------------------------------------------------------------------- /README.md: -------------------------------------------------------------------------------- 1 | # Archimedes 2 | 3 | Archimedes contains useful geometry functions for your Cocoa or Cocoa Touch application. 4 | 5 | ## Getting Started 6 | 7 | To start building the framework, clone this repository and then run `script/bootstrap`. 8 | This will automatically pull down any dependencies. 9 | 10 | Use the `.xcworkspace` file if you’re working on Archimedes in isolation, or the `.xcodeproj` if you’re using it in another project. 11 | 12 | ## License 13 | 14 | Archimedes is released under the MIT license. See [LICENSE.md](https://github.com/github/Archimedes/blob/master/LICENSE.md). 15 | -------------------------------------------------------------------------------- /Archimedes/Archimedes.h: -------------------------------------------------------------------------------- 1 | // 2 | // Archimedes.h 3 | // Archimedes 4 | // 5 | // Created by Justin Spahr-Summers on 2014-10-02. 6 | // Copyright (c) 2014 GitHub. All rights reserved. 7 | // 8 | 9 | #import 10 | #import 11 | 12 | //! Project version number for Archimedes. 13 | FOUNDATION_EXPORT double ArchimedesVersionNumber; 14 | 15 | //! Project version string for Archimedes. 16 | FOUNDATION_EXPORT const unsigned char ArchimedesVersionString[]; 17 | 18 | #import 19 | #import 20 | #import 21 | -------------------------------------------------------------------------------- /script/xcodebuild.awk: -------------------------------------------------------------------------------- 1 | # Exit statuses: 2 | # 3 | # 0 - No errors found. 4 | # 1 - Build or test failure. Errors will be logged automatically. 5 | # 2 - Untestable target. Retry with the "build" action. 6 | 7 | BEGIN { 8 | status = 0; 9 | } 10 | 11 | { 12 | print; 13 | fflush(stdout); 14 | } 15 | 16 | /is not valid for Testing/ { 17 | exit 2; 18 | } 19 | 20 | /[0-9]+: (error|warning):/ { 21 | errors = errors $0 "\n"; 22 | } 23 | 24 | /(TEST|BUILD) FAILED/ { 25 | status = 1; 26 | } 27 | 28 | END { 29 | if (length(errors) > 0) { 30 | print "\n*** All errors:\n" errors; 31 | } 32 | 33 | fflush(stdout); 34 | exit status; 35 | } 36 | -------------------------------------------------------------------------------- /ArchimedesTests/ArchimedesTests-Info.plist: -------------------------------------------------------------------------------- 1 | 2 | 3 | 4 | 5 | CFBundleDevelopmentRegion 6 | en 7 | CFBundleExecutable 8 | ${EXECUTABLE_NAME} 9 | CFBundleIdentifier 10 | com.github.${PRODUCT_NAME:rfc1034identifier} 11 | CFBundleInfoDictionaryVersion 12 | 6.0 13 | CFBundlePackageType 14 | BNDL 15 | CFBundleShortVersionString 16 | 1.0 17 | CFBundleSignature 18 | ???? 19 | CFBundleVersion 20 | 1 21 | 22 | 23 | -------------------------------------------------------------------------------- /ArchimedesTests/Info.plist: -------------------------------------------------------------------------------- 1 | 2 | 3 | 4 | 5 | CFBundleDevelopmentRegion 6 | en 7 | CFBundleExecutable 8 | $(EXECUTABLE_NAME) 9 | CFBundleIdentifier 10 | $(PRODUCT_BUNDLE_IDENTIFIER) 11 | CFBundleInfoDictionaryVersion 12 | 6.0 13 | CFBundleName 14 | $(PRODUCT_NAME) 15 | CFBundlePackageType 16 | BNDL 17 | CFBundleShortVersionString 18 | 1.0 19 | CFBundleSignature 20 | ???? 21 | CFBundleVersion 22 | 1 23 | 24 | 25 | -------------------------------------------------------------------------------- /Archimedes/Info.plist: -------------------------------------------------------------------------------- 1 | 2 | 3 | 4 | 5 | CFBundleDevelopmentRegion 6 | en 7 | CFBundleExecutable 8 | $(EXECUTABLE_NAME) 9 | CFBundleIdentifier 10 | $(PRODUCT_BUNDLE_IDENTIFIER) 11 | CFBundleInfoDictionaryVersion 12 | 6.0 13 | CFBundleName 14 | $(PRODUCT_NAME) 15 | CFBundlePackageType 16 | FMWK 17 | CFBundleShortVersionString 18 | 1.0 19 | CFBundleSignature 20 | ???? 21 | CFBundleVersion 22 | $(CURRENT_PROJECT_VERSION) 23 | NSPrincipalClass 24 | 25 | 26 | 27 | -------------------------------------------------------------------------------- /CONTRIBUTING.md: -------------------------------------------------------------------------------- 1 | We love that you're interested in contributing to this project! 2 | 3 | To make the process as painless as possible, we have just a couple of guidelines 4 | that should make life easier for everyone involved. 5 | 6 | ## Prefer Pull Requests 7 | 8 | If you know exactly how to implement the feature being suggested or fix the bug 9 | being reported, please open a pull request instead of an issue. Pull requests are easier than 10 | patches or inline code blocks for discussing and merging the changes. 11 | 12 | If you can't make the change yourself, please open an issue after making sure 13 | that one isn't already logged. 14 | 15 | ## Contributing Code 16 | 17 | Fork this repository, make it awesomer (preferably in a branch named for the 18 | topic), send a pull request! 19 | 20 | All code contributions should match our [coding 21 | conventions](https://github.com/github/objective-c-conventions). 22 | 23 | Thanks for contributing! :boom::camel: 24 | -------------------------------------------------------------------------------- /Archimedes/Archimedes-Info.plist: -------------------------------------------------------------------------------- 1 | 2 | 3 | 4 | 5 | CFBundleDevelopmentRegion 6 | English 7 | CFBundleExecutable 8 | ${EXECUTABLE_NAME} 9 | CFBundleIconFile 10 | 11 | CFBundleIdentifier 12 | com.github.${PRODUCT_NAME:rfc1034identifier} 13 | CFBundleInfoDictionaryVersion 14 | 6.0 15 | CFBundleName 16 | ${PRODUCT_NAME} 17 | CFBundlePackageType 18 | FMWK 19 | CFBundleShortVersionString 20 | 1.0 21 | CFBundleSignature 22 | ???? 23 | CFBundleVersion 24 | 1 25 | NSHumanReadableCopyright 26 | Copyright © 2013 GitHub. All rights reserved. 27 | NSPrincipalClass 28 | 29 | 30 | 31 | -------------------------------------------------------------------------------- /script/LICENSE.md: -------------------------------------------------------------------------------- 1 | **Copyright (c) 2013 Justin Spahr-Summers** 2 | 3 | Permission is hereby granted, free of charge, to any person obtaining a copy of 4 | this software and associated documentation files (the "Software"), to deal in 5 | the Software without restriction, including without limitation the rights to 6 | use, copy, modify, merge, publish, distribute, sublicense, and/or sell copies of 7 | the Software, and to permit persons to whom the Software is furnished to do so, 8 | subject to the following conditions: 9 | 10 | The above copyright notice and this permission notice shall be included in all 11 | copies or substantial portions of the Software. 12 | 13 | THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR 14 | IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, FITNESS 15 | FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR 16 | COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER 17 | IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN 18 | CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE. 19 | -------------------------------------------------------------------------------- /script/bootstrap: -------------------------------------------------------------------------------- 1 | #!/bin/bash 2 | 3 | export SCRIPT_DIR=$(dirname "$0") 4 | 5 | ## 6 | ## Configuration Variables 7 | ## 8 | 9 | config () 10 | { 11 | # A whitespace-separated list of executables that must be present and locatable. 12 | : ${REQUIRED_TOOLS="xctool"} 13 | 14 | export REQUIRED_TOOLS 15 | } 16 | 17 | ## 18 | ## Bootstrap Process 19 | ## 20 | 21 | main () 22 | { 23 | config 24 | 25 | if [ -n "$REQUIRED_TOOLS" ] 26 | then 27 | echo "*** Checking dependencies..." 28 | check_deps 29 | fi 30 | 31 | local submodules=$(git submodule status) 32 | local result=$? 33 | 34 | if [ "$result" -ne "0" ] 35 | then 36 | exit $result 37 | fi 38 | 39 | if [ -n "$submodules" ] 40 | then 41 | echo "*** Updating submodules..." 42 | update_submodules 43 | fi 44 | } 45 | 46 | check_deps () 47 | { 48 | for tool in $REQUIRED_TOOLS 49 | do 50 | which -s "$tool" 51 | if [ "$?" -ne "0" ] 52 | then 53 | echo "*** Error: $tool not found. Please install it and bootstrap again." 54 | exit 1 55 | fi 56 | done 57 | } 58 | 59 | bootstrap_submodule () 60 | { 61 | local bootstrap="script/bootstrap" 62 | 63 | if [ -e "$bootstrap" ] 64 | then 65 | echo "*** Bootstrapping $name..." 66 | "$bootstrap" >/dev/null 67 | else 68 | update_submodules 69 | fi 70 | } 71 | 72 | update_submodules () 73 | { 74 | git submodule sync --quiet && git submodule update --init && git submodule foreach --quiet bootstrap_submodule 75 | } 76 | 77 | export -f bootstrap_submodule 78 | export -f update_submodules 79 | 80 | main 81 | -------------------------------------------------------------------------------- /Archimedes/MEDEdgeInsets.m: -------------------------------------------------------------------------------- 1 | // 2 | // MEDEdgeInsets.m 3 | // Archimedes 4 | // 5 | // Created by Indragie Karunaratne on 8/6/2013. 6 | // Copyright (c) 2013 GitHub. All rights reserved. 7 | // 8 | 9 | #import "MEDEdgeInsets.h" 10 | 11 | MEDEdgeInsets MEDEdgeInsetsMake(CGFloat top, CGFloat left, CGFloat bottom, CGFloat right) { 12 | return (MEDEdgeInsets){ .top = top, .left = left, .bottom = bottom, .right = right }; 13 | } 14 | 15 | BOOL MEDEdgeInsetsEqualToEdgeInsets(MEDEdgeInsets insets1, MEDEdgeInsets insets2) { 16 | return (fabs(insets1.top - insets2.top) < 0.1) && 17 | (fabs(insets1.left - insets2.left) < 0.1) && 18 | (fabs(insets1.bottom - insets2.bottom) < 0.1) && 19 | (fabs(insets1.right - insets2.right) < 0.1); 20 | } 21 | 22 | CGRect MEDEdgeInsetsInsetRect(CGRect rect, MEDEdgeInsets insets) { 23 | if (((insets.top + insets.bottom) > rect.size.height) || ((insets.left + insets.right) > rect.size.width)) { 24 | return CGRectNull; 25 | } else { 26 | rect.origin.x += insets.left; 27 | #ifdef __IPHONE_OS_VERSION_MIN_REQUIRED 28 | rect.origin.y += insets.top; 29 | #elif TARGET_OS_MAC 30 | rect.origin.y += insets.bottom; 31 | #endif 32 | rect.size.height -= (insets.top + insets.bottom); 33 | rect.size.width -= (insets.left + insets.right); 34 | return rect; 35 | } 36 | } 37 | 38 | NSString * NSStringFromMEDEdgeInsets(MEDEdgeInsets insets) { 39 | return [NSString stringWithFormat:@"{%g, %g, %g, %g}", insets.top, insets.left, insets.bottom, insets.right]; 40 | } 41 | 42 | MEDEdgeInsets MEDEdgeInsetsFromString(NSString *string) { 43 | NSCParameterAssert(string != nil); 44 | double top = 0, left = 0, bottom = 0, right = 0; 45 | sscanf(string.UTF8String, "{%lg, %lg, %lg, %lg}", &top, &left, &bottom, &right); 46 | return MEDEdgeInsetsMake((CGFloat)top, (CGFloat)left, (CGFloat)bottom, (CGFloat)right); 47 | } 48 | -------------------------------------------------------------------------------- /ArchimedesTests/MEDEdgeInsetsSpec.m: -------------------------------------------------------------------------------- 1 | // 2 | // MEDEdgeInsetsSpec.m 3 | // Archimedes 4 | // 5 | // Created by Indragie Karunaratne on 8/6/2013. 6 | // Copyright (c) 2013 GitHub. All rights reserved. 7 | // 8 | 9 | #import 10 | #import 11 | #import 12 | 13 | static const MEDEdgeInsets insets = (MEDEdgeInsets){ .top = 1, .left = 2, .bottom = 3, .right = 4 }; 14 | static const MEDEdgeInsets insets2 = (MEDEdgeInsets){ .top = 1.05f, .left = 2.05f, .bottom = 3.05f, .right = 4.05f }; 15 | 16 | QuickSpecBegin(EdgeInsets) 17 | 18 | qck_it(@"should check equality between MEDEdgeInsets", ^{ 19 | MEDEdgeInsets insets3 = MEDEdgeInsetsMake(5, 6, 7, 8); 20 | expect(@(MEDEdgeInsetsEqualToEdgeInsets(insets, insets))).to(beTruthy()); 21 | expect(@(MEDEdgeInsetsEqualToEdgeInsets(insets, insets2))).to(beTruthy()); 22 | expect(@(MEDEdgeInsetsEqualToEdgeInsets(insets, insets3))).to(beFalsy()); 23 | }); 24 | 25 | qck_it(@"should make an MEDEdgeInsets", ^{ 26 | MEDEdgeInsets newInsets = MEDEdgeInsetsMake(1, 2, 3, 4); 27 | expect(MEDBox(newInsets)).to(equal(MEDBox(insets))); 28 | }); 29 | 30 | qck_it(@"should inset a CGRect", ^{ 31 | CGRect rect = CGRectMake(10, 10, 10, 10); 32 | #ifdef __IPHONE_OS_VERSION_MIN_REQUIRED 33 | CGRect insetRect = CGRectMake(12, 11, 4, 6); 34 | #elif TARGET_OS_MAC 35 | CGRect insetRect = CGRectMake(12, 13, 4, 6); 36 | #endif 37 | 38 | expect(MEDBox(MEDEdgeInsetsInsetRect(rect, insets))).to(equal(MEDBox(insetRect))); 39 | }); 40 | 41 | qck_it(@"should create a string from an MEDEdgeInsets", ^{ 42 | expect(NSStringFromMEDEdgeInsets(insets)).to(equal(@"{1, 2, 3, 4}")); 43 | expect(NSStringFromMEDEdgeInsets(insets2)).to(equal(@"{1.05, 2.05, 3.05, 4.05}")); 44 | }); 45 | 46 | qck_it(@"should create an MEDEdgeInsets from a string", ^{ 47 | expect(MEDBox(MEDEdgeInsetsFromString(@"{1, 2, 3, 4}"))).to(equal(MEDBox(insets))); 48 | expect(@(MEDEdgeInsetsEqualToEdgeInsets(MEDEdgeInsetsFromString(@"{1.05, 2.05, 3.05, 4.05}"), insets2))).to(beTruthy()); 49 | }); 50 | 51 | QuickSpecEnd 52 | -------------------------------------------------------------------------------- /Archimedes/MEDEdgeInsets.h: -------------------------------------------------------------------------------- 1 | // 2 | // MEDEdgeInsets.h 3 | // Archimedes 4 | // 5 | // Created by Indragie Karunaratne on 8/6/2013. 6 | // Copyright (c) 2013 GitHub. All rights reserved. 7 | // 8 | 9 | #import 10 | 11 | #ifdef __IPHONE_OS_VERSION_MIN_REQUIRED 12 | #import 13 | typedef UIEdgeInsets MEDEdgeInsets; 14 | #elif TARGET_OS_MAC 15 | #import 16 | typedef NSEdgeInsets MEDEdgeInsets; 17 | #endif 18 | 19 | // `MEDEdgeInsets` structure with all members set to 0. 20 | #define MEDEdgeInsetsZero (MEDEdgeInsets){ .top = 0, .left = 0, .bottom = 0, .right = 0 } 21 | 22 | // Returns an MEDEgeInsets struct with the given edge insets. 23 | MEDEdgeInsets MEDEdgeInsetsMake(CGFloat top, CGFloat left, CGFloat bottom, CGFloat right); 24 | 25 | // Returns whether the two given `MEDEdgeInsets` are equal. 26 | BOOL MEDEdgeInsetsEqualToEdgeInsets(MEDEdgeInsets insets1, MEDEdgeInsets insets2); 27 | 28 | // The top inset will affect the min Y coordinate on iOS, and max Y coordinate on 29 | // OS X, and vice-versa for bottom due to the default flippedness of drawing contexts 30 | // on each platform. 31 | // 32 | // Returns a rectangle adjusted by incrementing the origin and decrementing the size 33 | // of the given rect by applying the given insets. 34 | CGRect MEDEdgeInsetsInsetRect(CGRect rect, MEDEdgeInsets insets); 35 | 36 | // Returns a string formatted to contain data from an `MEDEdgeInsets` structure. 37 | // 38 | // This string can be passed into `MEDEdgeInsetsFromString()` to recreate the original 39 | // `MEDEdgeInsets` structure. 40 | NSString * NSStringFromMEDEdgeInsets(MEDEdgeInsets insets); 41 | 42 | // Returns an `MEDEdgeInsets` structure corresponding to data in the given string 43 | // or `MEDEdgeInsetsZero` if the string is not formatted appropriately. 44 | // 45 | // The string format is “{top, left, bottom, right}”, where each member of the 46 | // `MEDEdgeInsets` structure is separated with a comma. This function should generally 47 | // only be used to convert strings that were previously created using the 48 | // `NSStringFromMEDEdgeInsets()` function. 49 | MEDEdgeInsets MEDEdgeInsetsFromString(NSString *string); 50 | -------------------------------------------------------------------------------- /LICENSE.md: -------------------------------------------------------------------------------- 1 | **Copyright (c) 2012 - 2013, GitHub, Inc.** 2 | **All rights reserved.** 3 | 4 | Permission is hereby granted, free of charge, to any person obtaining a copy of this software and associated documentation files (the "Software"), to deal in the Software without restriction, including without limitation the rights to use, copy, modify, merge, publish, distribute, sublicense, and/or sell copies of the Software, and to permit persons to whom the Software is furnished to do so, subject to the following conditions: 5 | 6 | The above copyright notice and this permission notice shall be included in all copies or substantial portions of the Software. 7 | 8 | THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE. 9 | 10 | --- 11 | 12 | **This project uses portions of code from the Velvet framework.** 13 | **Velvet is copyright (c) 2012, Bitswift, Inc.** 14 | **All rights reserved.** 15 | 16 | Redistribution and use in source and binary forms, with or without modification, are permitted provided that the following conditions are met: 17 | 18 | * Redistributions of source code must retain the above copyright notice, this list of conditions and the following disclaimer. 19 | * Neither the name of the Bitswift, Inc. nor the names of its contributors may be used to endorse or promote products derived from this software without specific prior written permission. 20 | 21 | THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT HOLDER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. 22 | -------------------------------------------------------------------------------- /Archimedes/NSValue+MEDGeometryAdditions.h: -------------------------------------------------------------------------------- 1 | // 2 | // NSValue+MEDGeometryAdditions.h 3 | // Archimedes 4 | // 5 | // Created by Justin Spahr-Summers on 2012-12-12. 6 | // Copyright (c) 2012 GitHub. All rights reserved. 7 | // 8 | 9 | #ifdef __IPHONE_OS_VERSION_MIN_REQUIRED 10 | #import 11 | #elif TARGET_OS_MAC 12 | #import 13 | #endif 14 | #import "MEDEdgeInsets.h" 15 | 16 | // Boxes a geometry structure. 17 | // 18 | // Returns an NSValue. 19 | #define MEDBox(VALUE) \ 20 | ({ \ 21 | __typeof__(VALUE) value_ = (VALUE); \ 22 | const void *value_ptr_ = &value_; \ 23 | \ 24 | [NSValue valueWithBytes:value_ptr_ objCType:@encode(__typeof__(VALUE))]; \ 25 | }) 26 | 27 | // Indicates the type of geometry structure that an NSValue contains. 28 | // 29 | // MEDGeometryStructTypeUnknown - The NSValue contains a value of unknown type. 30 | // MEDGeometryStructTypeRect - The NSValue contains a CGRect. 31 | // MEDGeometryStructTypePoint - The NSValue contains a CGPoint. 32 | // MEDGeometryStructTypeSize - The NSValue contains a CGSize. 33 | // MEDGeometryStructTypeEdgeInsets - The NSValue contains an MEDEdgeInsets. 34 | typedef enum : NSUInteger { 35 | MEDGeometryStructTypeUnknown, 36 | MEDGeometryStructTypeRect, 37 | MEDGeometryStructTypePoint, 38 | MEDGeometryStructTypeSize, 39 | MEDGeometryStructTypeEdgeInsets 40 | } MEDGeometryStructType; 41 | 42 | // Implements a cross-platform interface for manipulating geometry structures 43 | // stored in an NSValue. 44 | @interface NSValue (MEDGeometryAdditions) 45 | 46 | // Returns an NSValue wrapping the given rectangle. 47 | + (NSValue *)med_valueWithRect:(CGRect)rect; 48 | 49 | // Returns an NSValue wrapping the given point. 50 | + (NSValue *)med_valueWithPoint:(CGPoint)point; 51 | 52 | // Returns an NSValue wrapping the given size. 53 | + (NSValue *)med_valueWithSize:(CGSize)size; 54 | 55 | // Returns an NSValue wrapping the given edge insets. 56 | + (NSValue *)med_valueWithEdgeInsets:(MEDEdgeInsets)insets; 57 | 58 | // Returns the type of geometry structure stored in the receiver, or 59 | // MEDGeometryStructTypeUnknown if the type can't be identified. 60 | @property (nonatomic, assign, readonly) MEDGeometryStructType med_geometryStructType; 61 | 62 | // Returns the CGRect value in the receiver. 63 | @property (nonatomic, assign, readonly) CGRect med_rectValue; 64 | 65 | // Returns the CGPoint value in the receiver. 66 | @property (nonatomic, assign, readonly) CGPoint med_pointValue; 67 | 68 | // Returns the CGSize value in the receiver. 69 | @property (nonatomic, assign, readonly) CGSize med_sizeValue; 70 | 71 | // Returns the MEDEdgeInsets value in the receiver. 72 | @property (nonatomic, assign, readonly) MEDEdgeInsets med_edgeInsetsValue; 73 | 74 | @end 75 | -------------------------------------------------------------------------------- /script/README.md: -------------------------------------------------------------------------------- 1 | # objc-build-scripts 2 | 3 | This project is a collection of scripts created with two goals: 4 | 5 | 1. To standardize how Objective-C projects are bootstrapped after cloning 6 | 1. To easily build Objective-C projects on continuous integration servers 7 | 8 | ## Scripts 9 | 10 | Right now, there are two important scripts: [`bootstrap`](#bootstrap) and 11 | [`cibuild`](#cibuild). Both are Bash scripts, to maximize compatibility and 12 | eliminate pesky system configuration issues (like setting up a working Ruby 13 | environment). 14 | 15 | The structure of the scripts on disk is meant to follow that of a typical Ruby 16 | project: 17 | 18 | ``` 19 | script/ 20 | bootstrap 21 | cibuild 22 | ``` 23 | 24 | ### bootstrap 25 | 26 | This script is responsible for bootstrapping (initializing) your project after 27 | it's been checked out. Here, you should install or clone any dependencies that 28 | are required for a working build and development environment. 29 | 30 | By default, the script will verify that [xctool][] is installed, then initialize 31 | and update submodules recursively. If any submodules contain `script/bootstrap`, 32 | that will be run as well. 33 | 34 | To check that other tools are installed, you can set the `REQUIRED_TOOLS` 35 | environment variable before running `script/bootstrap`, or edit it within the 36 | script directly. Note that no installation is performed automatically, though 37 | this can always be added within your specific project. 38 | 39 | ### cibuild 40 | 41 | This script is responsible for building the project, as you would want it built 42 | for continuous integration. This is preferable to putting the logic on the CI 43 | server itself, since it ensures that any changes are versioned along with the 44 | source. 45 | 46 | By default, the script will run [`bootstrap`](#bootstrap), look for any Xcode 47 | workspace or project in the working directory, then build all targets/schemes 48 | (as found by `xcodebuild -list`) using [xctool][]. 49 | 50 | You can also specify the schemes to build by passing them into the script: 51 | 52 | ```sh 53 | script/cibuild ReactiveCocoa-Mac ReactiveCocoa-iOS 54 | ``` 55 | 56 | As with the `bootstrap` script, there are several environment variables that can 57 | be used to customize behavior. They can be set on the command line before 58 | invoking the script, or the defaults changed within the script directly. 59 | 60 | ## Getting Started 61 | 62 | To add the scripts to your project, read the contents of this repository into 63 | a `script` folder: 64 | 65 | ``` 66 | $ git remote add objc-build-scripts https://github.com/jspahrsummers/objc-build-scripts.git 67 | $ git fetch objc-build-scripts 68 | $ git read-tree --prefix=script/ -u objc-build-scripts/master 69 | ``` 70 | 71 | Then commit the changes, to incorporate the scripts into your own repository's 72 | history. You can also freely tweak the scripts for your specific project's 73 | needs. 74 | 75 | To merge in upstream changes later: 76 | 77 | ``` 78 | $ git fetch -p objc-build-scripts 79 | $ git merge --ff --squash -Xsubtree=script objc-build-scripts/master 80 | ``` 81 | 82 | [xctool]: https://github.com/facebook/xctool 83 | -------------------------------------------------------------------------------- /Archimedes/NSValue+MEDGeometryAdditions.m: -------------------------------------------------------------------------------- 1 | // 2 | // NSValue+MEDGeometryAdditions.m 3 | // Archimedes 4 | // 5 | // Created by Justin Spahr-Summers on 2012-12-12. 6 | // Copyright (c) 2012 GitHub. All rights reserved. 7 | // 8 | 9 | #import "NSValue+MEDGeometryAdditions.h" 10 | 11 | #ifdef __IPHONE_OS_VERSION_MIN_REQUIRED 12 | #import 13 | #elif TARGET_OS_MAC 14 | #import 15 | #endif 16 | 17 | @implementation NSValue (MEDGeometryAdditions) 18 | 19 | #ifdef __IPHONE_OS_VERSION_MIN_REQUIRED 20 | 21 | + (NSValue *)med_valueWithRect:(CGRect)rect { 22 | return [self valueWithCGRect:rect]; 23 | } 24 | 25 | + (NSValue *)med_valueWithPoint:(CGPoint)point { 26 | return [self valueWithCGPoint:point]; 27 | } 28 | 29 | + (NSValue *)med_valueWithSize:(CGSize)size { 30 | return [self valueWithCGSize:size]; 31 | } 32 | 33 | + (NSValue *)med_valueWithEdgeInsets:(MEDEdgeInsets)insets { 34 | return [self valueWithUIEdgeInsets:insets]; 35 | } 36 | 37 | - (CGRect)med_rectValue { 38 | NSAssert(self.med_geometryStructType == MEDGeometryStructTypeRect, @"Value is not a CGRect: %@", self); 39 | return self.CGRectValue; 40 | } 41 | 42 | - (CGPoint)med_pointValue { 43 | NSAssert(self.med_geometryStructType == MEDGeometryStructTypePoint, @"Value is not a CGPoint: %@", self); 44 | return self.CGPointValue; 45 | } 46 | 47 | - (CGSize)med_sizeValue { 48 | NSAssert(self.med_geometryStructType == MEDGeometryStructTypeSize, @"Value is not a CGSize: %@", self); 49 | return self.CGSizeValue; 50 | } 51 | 52 | - (MEDEdgeInsets)med_edgeInsetsValue { 53 | NSAssert(self.med_geometryStructType == MEDGeometryStructTypeEdgeInsets, @"Value is not an MEDEdgeInsets: %@", self); 54 | return self.UIEdgeInsetsValue; 55 | } 56 | 57 | #elif TARGET_OS_MAC 58 | 59 | + (NSValue *)med_valueWithRect:(CGRect)rect { 60 | return [self valueWithRect:rect]; 61 | } 62 | 63 | + (NSValue *)med_valueWithPoint:(CGPoint)point { 64 | return [self valueWithPoint:point]; 65 | } 66 | 67 | + (NSValue *)med_valueWithSize:(CGSize)size { 68 | return [self valueWithSize:size]; 69 | } 70 | 71 | + (NSValue *)med_valueWithEdgeInsets:(MEDEdgeInsets)insets { 72 | return [self valueWithBytes:&insets objCType:@encode(MEDEdgeInsets)]; 73 | } 74 | 75 | - (CGRect)med_rectValue { 76 | NSAssert(self.med_geometryStructType == MEDGeometryStructTypeRect, @"Value is not a CGRect: %@", self); 77 | return self.rectValue; 78 | } 79 | 80 | - (CGPoint)med_pointValue { 81 | NSAssert(self.med_geometryStructType == MEDGeometryStructTypePoint, @"Value is not a CGPoint: %@", self); 82 | return self.pointValue; 83 | } 84 | 85 | - (CGSize)med_sizeValue { 86 | NSAssert(self.med_geometryStructType == MEDGeometryStructTypeSize, @"Value is not a CGSize: %@", self); 87 | return self.sizeValue; 88 | } 89 | 90 | - (MEDEdgeInsets)med_edgeInsetsValue { 91 | NSAssert(self.med_geometryStructType == MEDGeometryStructTypeEdgeInsets, @"Value is not an MEDEdgeInsets: %@", self); 92 | MEDEdgeInsets insets; 93 | [self getValue:&insets]; 94 | return insets; 95 | } 96 | #endif 97 | 98 | - (MEDGeometryStructType)med_geometryStructType { 99 | const char *type = self.objCType; 100 | 101 | if (strcmp(type, @encode(CGRect)) == 0) { 102 | return MEDGeometryStructTypeRect; 103 | } else if (strcmp(type, @encode(CGPoint)) == 0) { 104 | return MEDGeometryStructTypePoint; 105 | } else if (strcmp(type, @encode(CGSize)) == 0) { 106 | return MEDGeometryStructTypeSize; 107 | } else if (strcmp(type, @encode(MEDEdgeInsets)) == 0) { 108 | return MEDGeometryStructTypeEdgeInsets; 109 | } else { 110 | return MEDGeometryStructTypeUnknown; 111 | } 112 | } 113 | 114 | @end 115 | -------------------------------------------------------------------------------- /ArchimedesTests/MEDNSValueAdditionsSpec.m: -------------------------------------------------------------------------------- 1 | // 2 | // MEDNSValueAdditionsSpec.m 3 | // Archimedes 4 | // 5 | // Created by Justin Spahr-Summers on 2012-12-12. 6 | // Copyright (c) 2012 GitHub. All rights reserved. 7 | // 8 | 9 | #import 10 | #import 11 | #import 12 | 13 | QuickSpecBegin(NSValueAdditions) 14 | 15 | CGRect rect = CGRectMake(10, 20, 30, 40); 16 | CGPoint point = CGPointMake(100, 200); 17 | CGSize size = CGSizeMake(300, 400); 18 | MEDEdgeInsets insets = MEDEdgeInsetsMake(1, 2, 3, 4); 19 | 20 | __block NSValue *rectValue; 21 | __block NSValue *pointValue; 22 | __block NSValue *sizeValue; 23 | __block NSValue *insetsValue; 24 | 25 | qck_beforeEach(^{ 26 | rectValue = [NSValue med_valueWithRect:rect]; 27 | expect(rectValue).notTo(beNil()); 28 | 29 | pointValue = [NSValue med_valueWithPoint:point]; 30 | expect(pointValue).notTo(beNil()); 31 | 32 | sizeValue = [NSValue med_valueWithSize:size]; 33 | expect(sizeValue).notTo(beNil()); 34 | 35 | insetsValue = [NSValue med_valueWithEdgeInsets:insets]; 36 | expect(insetsValue).notTo(beNil()); 37 | }); 38 | 39 | qck_it(@"should wrap a CGRect", ^{ 40 | expect(@(CGRectEqualToRect(rectValue.med_rectValue, rect))).to(beTruthy()); 41 | }); 42 | 43 | qck_it(@"should wrap a CGPoint", ^{ 44 | expect(@(CGPointEqualToPoint(pointValue.med_pointValue, point))).to(beTruthy()); 45 | }); 46 | 47 | qck_it(@"should wrap a CGSize", ^{ 48 | expect(@(CGSizeEqualToSize(sizeValue.med_sizeValue, size))).to(beTruthy()); 49 | }); 50 | 51 | qck_it(@"should wrap an MEDEdgeInsets", ^{ 52 | expect(@(MEDEdgeInsetsEqualToEdgeInsets(insetsValue.med_edgeInsetsValue, insets))).to(beTruthy()); 53 | }); 54 | 55 | qck_describe(@"MEDBox", ^{ 56 | qck_it(@"should wrap a CGRect", ^{ 57 | NSValue *value = MEDBox(rect); 58 | expect(value).to(equal(rectValue)); 59 | }); 60 | 61 | qck_it(@"should wrap a CGPoint", ^{ 62 | NSValue *value = MEDBox(point); 63 | expect(value).to(equal(pointValue)); 64 | }); 65 | 66 | qck_it(@"should wrap a CGSize", ^{ 67 | NSValue *value = MEDBox(size); 68 | expect(value).to(equal(sizeValue)); 69 | }); 70 | 71 | qck_it(@"should wrap a MEDEdgeInsets", ^{ 72 | NSValue *value = MEDBox(insets); 73 | expect(value).to(equal(insetsValue)); 74 | }); 75 | 76 | // Specifically used because we don't support it directly. 77 | qck_it(@"should wrap a CGAffineTransform", ^{ 78 | CGAffineTransform transform = CGAffineTransformMake(1, 2, 5, 8, 13, 21); 79 | 80 | NSValue *value = MEDBox(transform); 81 | expect(value).notTo(beNil()); 82 | 83 | CGAffineTransform readTransform; 84 | [value getValue:&readTransform]; 85 | 86 | expect(@(CGAffineTransformEqualToTransform(transform, readTransform))).to(beTruthy()); 87 | }); 88 | }); 89 | 90 | qck_describe(@"med_geometryStructType", ^{ 91 | qck_it(@"should identify a CGRect", ^{ 92 | expect(@(rectValue.med_geometryStructType)).to(equal(@(MEDGeometryStructTypeRect))); 93 | }); 94 | 95 | qck_it(@"should identify a CGPoint", ^{ 96 | expect(@(pointValue.med_geometryStructType)).to(equal(@(MEDGeometryStructTypePoint))); 97 | }); 98 | 99 | qck_it(@"should identify a CGSize", ^{ 100 | expect(@(sizeValue.med_geometryStructType)).to(equal(@(MEDGeometryStructTypeSize))); 101 | }); 102 | 103 | qck_it(@"should identify an MEDEdgeInsets", ^{ 104 | expect(@(insetsValue.med_geometryStructType)).to(equal(@(MEDGeometryStructTypeEdgeInsets))); 105 | }); 106 | 107 | qck_it(@"should return MEDGeometryStructTypeUnknown for unknown types", ^{ 108 | NSNumber *num = @5; 109 | expect(@(num.med_geometryStructType)).to(equal(@(MEDGeometryStructTypeUnknown))); 110 | }); 111 | }); 112 | 113 | QuickSpecEnd 114 | -------------------------------------------------------------------------------- /script/cibuild: -------------------------------------------------------------------------------- 1 | #!/bin/bash 2 | 3 | export SCRIPT_DIR=$(dirname "$0") 4 | 5 | ## 6 | ## Configuration Variables 7 | ## 8 | 9 | SCHEMES="$@" 10 | 11 | config () 12 | { 13 | # The workspace to build. 14 | # 15 | # If not set and no workspace is found, the -workspace flag will not be passed 16 | # to `xctool`. 17 | # 18 | # Only one of `XCWORKSPACE` and `XCODEPROJ` needs to be set. The former will 19 | # take precedence. 20 | : ${XCWORKSPACE=$(find_pattern "*.xcworkspace")} 21 | 22 | # The project to build. 23 | # 24 | # If not set and no project is found, the -project flag will not be passed 25 | # to `xctool`. 26 | # 27 | # Only one of `XCWORKSPACE` and `XCODEPROJ` needs to be set. The former will 28 | # take precedence. 29 | : ${XCODEPROJ=$(find_pattern "*.xcodeproj")} 30 | 31 | # A bootstrap script to run before building. 32 | # 33 | # If this file does not exist, it is not considered an error. 34 | : ${BOOTSTRAP="$SCRIPT_DIR/bootstrap"} 35 | 36 | # Extra options to pass to xctool. 37 | : ${XCTOOL_OPTIONS="RUN_CLANG_STATIC_ANALYZER=NO"} 38 | 39 | # A whitespace-separated list of default schemes to build. 40 | # 41 | # Individual names can be quoted to avoid word splitting. 42 | : ${SCHEMES:=$(xcodebuild -list -project "$XCODEPROJ" 2>/dev/null | awk -f "$SCRIPT_DIR/schemes.awk")} 43 | 44 | export XCWORKSPACE 45 | export XCODEPROJ 46 | export BOOTSTRAP 47 | export XCTOOL_OPTIONS 48 | export SCHEMES 49 | } 50 | 51 | ## 52 | ## Build Process 53 | ## 54 | 55 | main () 56 | { 57 | config 58 | 59 | if [ -f "$BOOTSTRAP" ] 60 | then 61 | echo "*** Bootstrapping..." 62 | "$BOOTSTRAP" || exit $? 63 | fi 64 | 65 | echo "*** The following schemes will be built:" 66 | echo "$SCHEMES" | xargs -n 1 echo " " 67 | echo 68 | 69 | echo "$SCHEMES" | xargs -n 1 | ( 70 | local status=0 71 | 72 | while read scheme 73 | do 74 | build_scheme "$scheme" || status=1 75 | done 76 | 77 | exit $status 78 | ) 79 | } 80 | 81 | find_pattern () 82 | { 83 | ls -d $1 2>/dev/null | head -n 1 84 | } 85 | 86 | run_xctool () 87 | { 88 | if [ -n "$XCWORKSPACE" ] 89 | then 90 | xctool -workspace "$XCWORKSPACE" $XCTOOL_OPTIONS "$@" 2>&1 91 | elif [ -n "$XCODEPROJ" ] 92 | then 93 | xctool -project "$XCODEPROJ" $XCTOOL_OPTIONS "$@" 2>&1 94 | else 95 | echo "*** No workspace or project file found." 96 | exit 1 97 | fi 98 | } 99 | 100 | parse_build () 101 | { 102 | awk -f "$SCRIPT_DIR/xctool.awk" 2>&1 >/dev/null 103 | } 104 | 105 | build_scheme () 106 | { 107 | local scheme=$1 108 | 109 | echo "*** Cleaning $scheme..." 110 | run_xctool -scheme "$scheme" clean >/dev/null || exit $? 111 | 112 | echo "*** Building and testing $scheme..." 113 | echo 114 | 115 | local sdkflag= 116 | local action=test 117 | 118 | # Determine whether we can run unit tests for this target. 119 | run_xctool -scheme "$scheme" run-tests | parse_build 120 | 121 | local awkstatus=$? 122 | 123 | if [ "$awkstatus" -eq "1" ] 124 | then 125 | # SDK not found, try for iphonesimulator. 126 | sdkflag="-sdk iphonesimulator" 127 | 128 | # Determine whether the unit tests will run with iphonesimulator 129 | run_xctool $sdkflag -scheme "$scheme" run-tests | parse_build 130 | 131 | awkstatus=$? 132 | 133 | if [ "$awkstatus" -ne "0" ] 134 | then 135 | # Unit tests will not run on iphonesimulator. 136 | sdkflag="" 137 | fi 138 | fi 139 | 140 | if [ "$awkstatus" -ne "0" ] 141 | then 142 | # Unit tests aren't supported. 143 | action=build 144 | fi 145 | 146 | run_xctool $sdkflag -scheme "$scheme" $action 147 | } 148 | 149 | export -f build_scheme 150 | export -f run_xctool 151 | export -f parse_build 152 | 153 | main 154 | -------------------------------------------------------------------------------- /Archimedes.xcodeproj/xcshareddata/xcschemes/Archimedes Mac.xcscheme: -------------------------------------------------------------------------------- 1 | 2 | 5 | 8 | 9 | 15 | 21 | 22 | 23 | 29 | 35 | 36 | 37 | 38 | 39 | 44 | 45 | 47 | 53 | 54 | 55 | 56 | 57 | 63 | 64 | 65 | 66 | 67 | 68 | 78 | 79 | 85 | 86 | 87 | 88 | 89 | 90 | 96 | 97 | 103 | 104 | 105 | 106 | 108 | 109 | 112 | 113 | 114 | -------------------------------------------------------------------------------- /Archimedes.xcodeproj/xcshareddata/xcschemes/Archimedes iOS.xcscheme: -------------------------------------------------------------------------------- 1 | 2 | 5 | 8 | 9 | 15 | 21 | 22 | 23 | 29 | 35 | 36 | 37 | 38 | 39 | 44 | 45 | 47 | 53 | 54 | 55 | 56 | 57 | 63 | 64 | 65 | 66 | 67 | 68 | 78 | 79 | 85 | 86 | 87 | 88 | 89 | 90 | 96 | 97 | 103 | 104 | 105 | 106 | 108 | 109 | 112 | 113 | 114 | -------------------------------------------------------------------------------- /Archimedes/CGGeometry+MEDConvenienceAdditions.m: -------------------------------------------------------------------------------- 1 | // 2 | // CGGeometry+MEDConvenienceAdditions.m 3 | // Archimedes 4 | // 5 | // Created by Justin Spahr-Summers on 18.01.12. 6 | // Copyright 2012 GitHub. All rights reserved. 7 | // 8 | 9 | /* 10 | 11 | Portions copyright (c) 2012, Bitswift, Inc. 12 | All rights reserved. 13 | 14 | Redistribution and use in source and binary forms, with or without modification, are permitted provided that the following conditions are met: 15 | 16 | * Redistributions of source code must retain the above copyright notice, this list of conditions and the following disclaimer. 17 | * Neither the name of the Bitswift, Inc. nor the names of its contributors may be used to endorse or promote products derived from this software without specific prior written permission. 18 | 19 | THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT HOLDER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. 20 | 21 | */ 22 | 23 | #import 24 | #import "CGGeometry+MEDConvenienceAdditions.h" 25 | 26 | // Conditionalizes fmax() and similar floating-point functions based on argument 27 | // type, so they compile without casting on both OS X and iOS. 28 | #import 29 | 30 | // tgmath functions aren't used on iOS when modules are enabled. Work around 31 | // this by redeclaring things here. http://www.openradar.me/16744288 32 | #undef fmax 33 | #define fmax(__x, __y) __tg_fmax(__tg_promote2((__x), (__y))(__x), \ 34 | __tg_promote2((__x), (__y))(__y)) 35 | #undef floor 36 | #define floor(__x) __tg_floor(__tg_promote1((__x))(__x)) 37 | 38 | #undef cos 39 | #define cos(__x) __tg_cos(__tg_promote1((__x))(__x)) 40 | 41 | #undef sin 42 | #define sin(__x) __tg_sin(__tg_promote1((__x))(__x)) 43 | 44 | // Hide our crazy macros within the implementation. 45 | #undef MEDRectDivide 46 | #undef MEDRectDivideWithPadding 47 | 48 | CGPoint MEDRectCenterPoint(CGRect rect) { 49 | return CGPointMake(CGRectGetMinX(rect) + CGRectGetWidth(rect) / 2, CGRectGetMinY(rect) + CGRectGetHeight(rect) / 2); 50 | } 51 | 52 | CGRect MEDRectRemainder(CGRect rect, CGFloat amount, CGRectEdge edge) { 53 | CGRect slice, remainder; 54 | CGRectDivide(rect, &slice, &remainder, amount, edge); 55 | 56 | return remainder; 57 | } 58 | 59 | CGRect MEDRectSlice(CGRect rect, CGFloat amount, CGRectEdge edge) { 60 | CGRect slice, remainder; 61 | CGRectDivide(rect, &slice, &remainder, amount, edge); 62 | 63 | return slice; 64 | } 65 | 66 | CGRect MEDRectGrow(CGRect rect, CGFloat amount, CGRectEdge edge) { 67 | switch (edge) { 68 | case CGRectMinXEdge: 69 | return CGRectMake(CGRectGetMinX(rect) - amount, CGRectGetMinY(rect), CGRectGetWidth(rect) + amount, CGRectGetHeight(rect)); 70 | 71 | case CGRectMinYEdge: 72 | return CGRectMake(CGRectGetMinX(rect), CGRectGetMinY(rect) - amount, CGRectGetWidth(rect), CGRectGetHeight(rect) + amount); 73 | 74 | case CGRectMaxXEdge: 75 | return CGRectMake(CGRectGetMinX(rect), CGRectGetMinY(rect), CGRectGetWidth(rect) + amount, CGRectGetHeight(rect)); 76 | 77 | case CGRectMaxYEdge: 78 | return CGRectMake(CGRectGetMinX(rect), CGRectGetMinY(rect), CGRectGetWidth(rect), CGRectGetHeight(rect) + amount); 79 | 80 | default: 81 | NSCAssert(NO, @"Unrecognized CGRectEdge %i", (int)edge); 82 | return CGRectNull; 83 | } 84 | } 85 | 86 | void MEDRectDivideWithPadding(CGRect rect, CGRect *slicePtr, CGRect *remainderPtr, CGFloat sliceAmount, CGFloat padding, CGRectEdge edge) { 87 | CGRect slice; 88 | 89 | // slice 90 | CGRectDivide(rect, &slice, &rect, sliceAmount, edge); 91 | if (slicePtr) *slicePtr = slice; 92 | 93 | // padding / remainder 94 | CGRectDivide(rect, &slice, &rect, padding, edge); 95 | if (remainderPtr) *remainderPtr = rect; 96 | } 97 | 98 | CGRect MEDRectAlignWithRect(CGRect rect, CGRect referenceRect, CGRectEdge edge) { 99 | CGPoint origin; 100 | 101 | switch (edge) { 102 | case CGRectMinXEdge: 103 | origin = CGPointMake(CGRectGetMinX(referenceRect), CGRectGetMinY(rect)); 104 | break; 105 | 106 | case CGRectMinYEdge: 107 | origin = CGPointMake(CGRectGetMinX(rect), CGRectGetMinY(referenceRect)); 108 | break; 109 | 110 | case CGRectMaxXEdge: 111 | origin = CGPointMake(CGRectGetMaxX(referenceRect) - CGRectGetWidth(rect), CGRectGetMinY(rect)); 112 | break; 113 | 114 | case CGRectMaxYEdge: 115 | origin = CGPointMake(CGRectGetMinX(rect), CGRectGetMaxY(referenceRect) - CGRectGetHeight(rect)); 116 | break; 117 | 118 | default: 119 | NSCAssert(NO, @"Unrecognized CGRectEdge %i", (int)edge); 120 | return CGRectNull; 121 | } 122 | 123 | return (CGRect){ .origin = origin, .size = rect.size }; 124 | } 125 | 126 | CGRect MEDRectCenterInRect(CGRect inner, CGRect outer) 127 | { 128 | CGPoint origin = { 129 | .x = CGRectGetMidX(outer) - CGRectGetWidth(inner) / 2, 130 | .y = CGRectGetMidY(outer) - CGRectGetHeight(inner) / 2 131 | }; 132 | 133 | return (CGRect){ .origin = origin, .size = inner.size }; 134 | } 135 | 136 | CGRect MEDRectFloor(CGRect rect) { 137 | #ifdef __IPHONE_OS_VERSION_MIN_REQUIRED 138 | return CGRectMake(floor(rect.origin.x), floor(rect.origin.y), floor(rect.size.width), floor(rect.size.height)); 139 | #elif TARGET_OS_MAC 140 | return CGRectMake(floor(rect.origin.x), ceil(rect.origin.y), floor(rect.size.width), floor(rect.size.height)); 141 | #endif 142 | } 143 | 144 | CGRect MEDRectMakeInverted(CGRect containingRect, CGFloat x, CGFloat y, CGFloat width, CGFloat height) { 145 | CGRect rect = CGRectMake(x, y, width, height); 146 | return MEDRectInvert(containingRect, rect); 147 | } 148 | 149 | CGRect MEDRectInvert(CGRect containingRect, CGRect rect) { 150 | return CGRectMake(CGRectGetMinX(rect), CGRectGetHeight(containingRect) - CGRectGetMaxY(rect), CGRectGetWidth(rect), CGRectGetHeight(rect)); 151 | } 152 | 153 | bool MEDRectEqualToRectWithAccuracy(CGRect rect, CGRect rect2, CGFloat epsilon) { 154 | return MEDPointEqualToPointWithAccuracy(rect.origin, rect2.origin, epsilon) && MEDSizeEqualToSizeWithAccuracy(rect.size, rect2.size, epsilon); 155 | } 156 | 157 | CGRect MEDRectWithSize(CGSize size) { 158 | return CGRectMake(0, 0, size.width, size.height); 159 | } 160 | 161 | CGRect MEDRectConvertToUnitRect(CGRect rect) { 162 | CGAffineTransform unitTransform = CGAffineTransformMakeScale(1 / CGRectGetWidth(rect), 1 / CGRectGetHeight(rect)); 163 | return CGRectApplyAffineTransform(rect, unitTransform); 164 | } 165 | 166 | CGRect MEDRectConvertFromUnitRect(CGRect rect, CGRect destinationRect) { 167 | CGAffineTransform unitTransform = CGAffineTransformMakeScale(CGRectGetWidth(rect), CGRectGetHeight(rect)); 168 | return CGRectApplyAffineTransform(destinationRect, unitTransform); 169 | } 170 | 171 | bool MEDSizeEqualToSizeWithAccuracy(CGSize size, CGSize size2, CGFloat epsilon) { 172 | return (fabs(size.width - size2.width) <= epsilon) && (fabs(size.height - size2.height) <= epsilon); 173 | } 174 | 175 | CGSize MEDSizeScale(CGSize size, CGFloat scale) { 176 | return CGSizeMake(size.width * scale, size.height * scale); 177 | } 178 | 179 | CGSize MEDSizeScaleAspectFit(CGSize size, CGSize maxSize) { 180 | CGFloat originalAspectRatio = size.width / size.height; 181 | CGFloat maxAspectRatio = maxSize.width / maxSize.height; 182 | CGSize newSize = maxSize; 183 | // The largest dimension will be the `maxSize`, and then we need to scale 184 | // the other dimension down relative to it, while maintaining the aspect 185 | // ratio. 186 | if (originalAspectRatio > maxAspectRatio) { 187 | newSize.height = maxSize.width / originalAspectRatio; 188 | } else { 189 | newSize.width = maxSize.height * originalAspectRatio; 190 | } 191 | 192 | return newSize; 193 | } 194 | 195 | CGSize MEDSizeScaleAspectFill(CGSize size, CGSize minSize) { 196 | CGFloat scaleWidth = minSize.width / size.width; 197 | CGFloat scaleHeight = minSize.height / size.height; 198 | 199 | CGFloat scale = fmax(scaleWidth, scaleHeight); 200 | CGFloat newWidth = size.width * scale; 201 | CGFloat newHeight = size.height * scale; 202 | 203 | return CGSizeMake(newWidth, newHeight); 204 | } 205 | 206 | CGPoint MEDPointFloor(CGPoint point) { 207 | #ifdef __IPHONE_OS_VERSION_MIN_REQUIRED 208 | return CGPointMake(floor(point.x), floor(point.y)); 209 | #elif TARGET_OS_MAC 210 | return CGPointMake(floor(point.x), ceil(point.y)); 211 | #endif 212 | } 213 | 214 | bool MEDPointEqualToPointWithAccuracy(CGPoint p, CGPoint q, CGFloat epsilon) { 215 | return (fabs(p.x - q.x) <= epsilon) && (fabs(p.y - q.y) <= epsilon); 216 | } 217 | 218 | CGFloat MEDPointDotProduct(CGPoint point, CGPoint point2) { 219 | return (point.x * point2.x + point.y * point2.y); 220 | } 221 | 222 | CGPoint MEDPointScale(CGPoint point, CGFloat scale) { 223 | return CGPointMake(point.x * scale, point.y * scale); 224 | } 225 | 226 | CGFloat MEDPointLength(CGPoint point) { 227 | return (CGFloat)sqrt(MEDPointDotProduct(point, point)); 228 | } 229 | 230 | CGPoint MEDPointNormalize(CGPoint point) { 231 | CGFloat len = MEDPointLength(point); 232 | if (len > 0) return MEDPointScale(point, 1/len); 233 | 234 | return point; 235 | } 236 | 237 | CGPoint MEDPointProject(CGPoint point, CGPoint direction) { 238 | CGPoint normalizedDirection = MEDPointNormalize(direction); 239 | CGFloat distance = MEDPointDotProduct(point, normalizedDirection); 240 | 241 | return MEDPointScale(normalizedDirection, distance); 242 | } 243 | 244 | CGPoint MEDPointProjectAlongAngle(CGPoint point, CGFloat angleInDegrees) { 245 | CGFloat angleInRads = (CGFloat)(angleInDegrees * M_PI / 180); 246 | CGPoint direction = CGPointMake(cos(angleInRads), sin(angleInRads)); 247 | return MEDPointProject(point, direction); 248 | } 249 | 250 | CGFloat MEDPointAngleInDegrees(CGPoint point) { 251 | return (CGFloat)(atan2(point.y, point.x) * 180 / M_PI); 252 | } 253 | 254 | CGPoint MEDPointAdd(CGPoint p1, CGPoint p2) { 255 | return CGPointMake(p1.x + p2.x, p1.y + p2.y); 256 | } 257 | 258 | CGPoint MEDPointSubtract(CGPoint p1, CGPoint p2) { 259 | return CGPointMake(p1.x - p2.x, p1.y - p2.y); 260 | } 261 | -------------------------------------------------------------------------------- /Archimedes/CGGeometry+MEDConvenienceAdditions.h: -------------------------------------------------------------------------------- 1 | // 2 | // CGGeometry+MEDConvenienceAdditions.h 3 | // Archimedes 4 | // 5 | // Created by Justin Spahr-Summers on 18.01.12. 6 | // Copyright 2012 GitHub. All rights reserved. 7 | // 8 | 9 | /* 10 | 11 | Portions copyright (c) 2012, Bitswift, Inc. 12 | All rights reserved. 13 | 14 | Redistribution and use in source and binary forms, with or without modification, are permitted provided that the following conditions are met: 15 | 16 | * Redistributions of source code must retain the above copyright notice, this list of conditions and the following disclaimer. 17 | * Neither the name of the Bitswift, Inc. nor the names of its contributors may be used to endorse or promote products derived from this software without specific prior written permission. 18 | 19 | THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT HOLDER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. 20 | 21 | */ 22 | 23 | #import 24 | 25 | // Extends CGRectDivide() to accept the following additional types for the 26 | // `SLICE` and `REMAINDER` arguments: 27 | // 28 | // - A `CGRect` property 29 | // - A `CGRect` variable 30 | // - `NULL` 31 | #define MEDRectDivide(RECT, SLICE, REMAINDER, AMOUNT, EDGE) \ 32 | do { \ 33 | CGRect _slice, _remainder; \ 34 | CGRectDivide((RECT), &_slice, &_remainder, (AMOUNT), (EDGE)); \ 35 | \ 36 | _MEDAssignToRectByReference(SLICE, _slice); \ 37 | _MEDAssignToRectByReference(REMAINDER, _remainder); \ 38 | } while (0) 39 | 40 | // Returns the exact center point of the given rectangle. 41 | CGPoint MEDRectCenterPoint(CGRect rect); 42 | 43 | // Chops the given amount off of a rectangle's edge. 44 | // 45 | // Returns the remainder of the rectangle, or `CGRectZero` if `amount` is 46 | // greater than or equal to size of the rectangle along the axis being chopped. 47 | CGRect MEDRectRemainder(CGRect rect, CGFloat amount, CGRectEdge edge); 48 | 49 | // Returns a slice consisting of the given amount starting from a rectangle's 50 | // edge, or the entire rectangle if `amount` is greater than or equal to the 51 | // size of the rectangle along the axis being sliced. 52 | CGRect MEDRectSlice(CGRect rect, CGFloat amount, CGRectEdge edge); 53 | 54 | // Adds the given amount to a rectangle's edge. 55 | // 56 | // rect - The rectangle to grow. 57 | // amount - The amount of points to add. 58 | // edge - The edge from which to grow. Growing is always outward (i.e., using 59 | // `CGRectMaxXEdge` will increase the width of the rectangle and leave 60 | // the origin unmodified). 61 | CGRect MEDRectGrow(CGRect rect, CGFloat amount, CGRectEdge edge); 62 | 63 | // Divides a source rectangle into two component rectangles, skipping the given 64 | // amount of padding in between them. 65 | // 66 | // This functions like CGRectDivide(), but omits the specified amount of padding 67 | // between the two rectangles. This results in a remainder that is `padding` 68 | // points smaller from `edge` than it would be with CGRectDivide(). 69 | // 70 | // rect - The rectangle to divide. 71 | // slice - Upon return, the portion of `rect` starting from `edge` and 72 | // continuing for `sliceAmount` points. This argument may be NULL 73 | // to not return the slice. 74 | // remainder - Upon return, the portion of `rect` beginning `padding` points 75 | // after the end of the `slice`. If `rect` is not large enough to 76 | // leave a remainder, this will be `CGRectZero`. This argument may 77 | // be NULL to not return the remainder. 78 | // sliceAmount - The number of points to include in `slice`, starting from the 79 | // given edge. 80 | // padding - The number of points of padding to omit between `slice` and 81 | // `remainder`. 82 | // edge - The edge from which division begins, proceeding toward the 83 | // opposite edge. 84 | void MEDRectDivideWithPadding(CGRect rect, CGRect *slice, CGRect *remainder, CGFloat sliceAmount, CGFloat padding, CGRectEdge edge); 85 | 86 | // Extends MEDRectDivideWithPadding() to accept the following additional types 87 | // for the `SLICE` and `REMAINDER` arguments: 88 | // 89 | // - A `CGRect` property 90 | // - A `CGRect` variable 91 | #define MEDRectDivideWithPadding(RECT, SLICE, REMAINDER, AMOUNT, PADDING, EDGE) \ 92 | do { \ 93 | CGRect _slice, _remainder; \ 94 | MEDRectDivideWithPadding((RECT), &_slice, &_remainder, (AMOUNT), (PADDING), (EDGE)); \ 95 | \ 96 | _MEDAssignToRectByReference(SLICE, _slice); \ 97 | _MEDAssignToRectByReference(REMAINDER, _remainder); \ 98 | } while (0) 99 | 100 | // Aligns a rectangle with on edge of another rectangle. 101 | // 102 | // rect - The rectangle that should be aligned. 103 | // referenceRect - The rectangle to align `rect` with. 104 | // edge - The edge that `rect` should share with `referenceRect`. 105 | // 106 | // Returns a rectangle with the dimensions of `rect` that shares the edge 107 | // specified by `edge` with `referenceRect`. The remaining coordinate of `rect` 108 | // is left unchanged. 109 | CGRect MEDRectAlignWithRect(CGRect rect, CGRect referenceRect, CGRectEdge edge); 110 | 111 | // Centers a rectangle in another rectangle. 112 | // 113 | // inner - The rectangle that will be centered. 114 | // outer - The rectangle in which to center `inner`. 115 | // 116 | // Returns a rectangle with the dimensions of `inner` centered in `outer`. 117 | CGRect MEDRectCenterInRect(CGRect inner, CGRect outer); 118 | 119 | // Round a rectangle to integral numbers. 120 | // 121 | // The rect will be moved up and left in native view coordinates (not accounting 122 | // for flippedness or transformed coordinate systems). To accomplish this: 123 | // 124 | // - On OS X, this function will round down fractional X origins and round up 125 | // fractional Y origins. 126 | // - On iOS, this function will round down fractional X origins and round down 127 | // fractional Y origins. 128 | // 129 | // On both platforms, this function will round down fractional sizes, such that 130 | // the size of the rectangle will never increase just from use of this method. 131 | // Among other things, this avoids stretching images that need a precise size. 132 | // 133 | // This function differs from CGRectIntegral() in that the resultant rectangle 134 | // may not completely encompass `rect`. CGRectIntegral() will ensure that its 135 | // resultant rectangle encompasses the original, but may increase the size of 136 | // the result to accomplish this. 137 | CGRect MEDRectFloor(CGRect rect); 138 | 139 | // Creates a rectangle for a coordinate system originating in the bottom-left. 140 | // 141 | // containingRect - The rectangle that will "contain" the created rectangle, 142 | // used as a reference to vertically flip the coordinate system. 143 | // x - The X origin of the rectangle, starting from the left. 144 | // y - The Y origin of the rectangle, starting from the top. 145 | // width - The width of the rectangle. 146 | // height - The height of the rectangle. 147 | CGRect MEDRectMakeInverted(CGRect containingRect, CGFloat x, CGFloat y, CGFloat width, CGFloat height); 148 | 149 | // Vertically inverts the coordinates of `rect` within `containingRect`. 150 | // 151 | // This can effectively be used to change the coordinate system of a rectangle. 152 | // For example, if `rect` is defined for a coordinate system starting at the 153 | // top-left, the result will be a rectangle relative to the bottom-left. 154 | // 155 | // containingRect - The rectangle that will "contain" the created rectangle, 156 | // used as a reference to vertically flip the coordinate system. 157 | // rect - The rectangle to vertically flip within `containingRect`. 158 | CGRect MEDRectInvert(CGRect containingRect, CGRect rect); 159 | 160 | // Returns a rectangle with an origin of `CGPointZero` and the given size. 161 | CGRect MEDRectWithSize(CGSize size); 162 | 163 | // Converts a rectangle to one in the unit coordinate space. 164 | // 165 | // Unit rectangles are an abstraction from screen sizes that range from 0-1 166 | // along both axes. This function will attempt to find the nearest fractional 167 | // representation of the components of the given rectangle. 168 | CGRect MEDRectConvertToUnitRect(CGRect rect); 169 | 170 | // Converts a unit rectangle into the coordinate space of a destination 171 | // rectangle. 172 | // 173 | // This is the exact opposite of `MEDRectConvertToUnitRect`, however a 174 | // destination rect is required because unit coordinate systems are 175 | // size agnostic. 176 | // 177 | // rect - The rectangle, in unit coordinates, to be "converted" to 178 | // the destination rect's coordinate system. 179 | // destRect - The rectangle that represents the size of the screen the 180 | // unit rect will be converted to. 181 | CGRect MEDRectConvertFromUnitRect(CGRect rect, CGRect destRect); 182 | 183 | // Returns whether every side of `rect` is within `epsilon` distance of `rect2`. 184 | bool MEDRectEqualToRectWithAccuracy(CGRect rect, CGRect rect2, CGFloat epsilon); 185 | 186 | // Returns whether `size` is within `epsilon` points of `size2`. 187 | bool MEDSizeEqualToSizeWithAccuracy(CGSize size, CGSize size2, CGFloat epsilon); 188 | 189 | // Scales the components of `size` by `scale`. 190 | CGSize MEDSizeScale(CGSize size, CGFloat scale); 191 | 192 | // Scales a size a size to fit within a different size. 193 | // 194 | // size - The size to scale. 195 | // maxSize - The size to fit original size within. 196 | // 197 | // Returns a new CGSize that has the same aspect ratio as the provided size, but 198 | // is resized fit inside the maxSize. 199 | CGSize MEDSizeScaleAspectFit(CGSize size, CGSize maxSize); 200 | 201 | // Scales a size a size to fill (and possibly exceed) a different size. 202 | // 203 | // size - The size to scale. 204 | // minSize - The size to fill. 205 | // 206 | // Returns a new CGSize that has the same aspect ratio as the provided size, but 207 | // is resized to fill (and possibly exceed) the minSize. 208 | CGSize MEDSizeScaleAspectFill(CGSize size, CGSize minSize); 209 | 210 | // Round a point to integral numbers. 211 | // 212 | // The point will be moved up and left in native view coordinates (not 213 | // accounting for flippedness or transformed coordinate systems). To accomplish 214 | // this: 215 | // 216 | // - On OS X, this function will round down fractional X values and round up 217 | // fractional Y values. 218 | // - On iOS, this function will round down fractional X values and round down 219 | // fractional Y values. 220 | CGPoint MEDPointFloor(CGPoint point); 221 | 222 | // Returns whether `point` is within `epsilon` distance of `point2`. 223 | bool MEDPointEqualToPointWithAccuracy(CGPoint point, CGPoint point2, CGFloat epsilon); 224 | 225 | // Returns the dot product of two points. 226 | CGFloat MEDPointDotProduct(CGPoint point, CGPoint point2); 227 | 228 | // Returns `point` scaled by `scale`. 229 | CGPoint MEDPointScale(CGPoint point, CGFloat scale); 230 | 231 | // Returns the length of `point`. 232 | CGFloat MEDPointLength(CGPoint point); 233 | 234 | // Returns the unit vector of `point`. 235 | CGPoint MEDPointNormalize(CGPoint point); 236 | 237 | // Returns a projected point in the specified direction. 238 | CGPoint MEDPointProject(CGPoint point, CGPoint direction); 239 | 240 | // Returns the angle of a vector. 241 | CGFloat MEDPointAngleInDegrees(CGPoint point); 242 | 243 | // Projects a point along a specified angle. 244 | CGPoint MEDPointProjectAlongAngle(CGPoint point, CGFloat angleInDegrees); 245 | 246 | // Add `p1` and `p2`. 247 | CGPoint MEDPointAdd(CGPoint p1, CGPoint p2); 248 | 249 | // Subtracts `p2` from `p1`. 250 | CGPoint MEDPointSubtract(CGPoint p1, CGPoint p2); 251 | 252 | // For internal use only. 253 | // 254 | // Returns a pointer to a new empty rectangle, suitable for storing unused 255 | // values. 256 | #define _MEDEmptyRectPointer \ 257 | (&(CGRect){ .origin = CGPointZero, .size = CGSizeZero }) 258 | 259 | // For internal use only. 260 | // 261 | // Assigns `RECT` into the first argument, which may be a property, `CGRect` 262 | // variable, or a pointer to a `CGRect`. If the argument is a pointer and is 263 | // `NULL`, nothing happens. 264 | #define _MEDAssignToRectByReference(RECT_OR_PTR, RECT) \ 265 | /* Switches based on the type of the first argument. */ \ 266 | (_Generic((RECT_OR_PTR), \ 267 | CGRect *: *({ \ 268 | /* Copy the argument into a union so this code compiles even 269 | * when it's not a pointer. */ \ 270 | union { \ 271 | __typeof__(RECT_OR_PTR) copy; \ 272 | CGRect *ptr; \ 273 | } _u = { .copy = (RECT_OR_PTR) }; \ 274 | \ 275 | /* If the argument is NULL, assign into an empty rect instead. */ \ 276 | _u.ptr ?: _MEDEmptyRectPointer; \ 277 | }), \ 278 | \ 279 | /* void * should only occur for NULL. */ \ 280 | void *: *_MEDEmptyRectPointer, \ 281 | \ 282 | /* For all other cases, assign into the given variable or property 283 | * normally. */ \ 284 | default: RECT_OR_PTR \ 285 | ) = (RECT)) 286 | -------------------------------------------------------------------------------- /ArchimedesTests/MEDCGGeometryAdditionsSpec.m: -------------------------------------------------------------------------------- 1 | // 2 | // MEDCGGeometryAdditionsSpec.m 3 | // Archimedes 4 | // 5 | // Created by Justin Spahr-Summers on 18.01f.12. 6 | // Copyright 2012 GitHub. All rights reserved. 7 | // 8 | 9 | /* 10 | 11 | Portions copyright (c) 2012, Bitswift, Inc. 12 | All rights reserved. 13 | 14 | Redistribution and use in source and binary forms, With or Without modification, are permitted provided that the following conditions are met: 15 | 16 | * Redistributions of source code must retain the above copyright notice, this list of conditions and the following disclaimer. 17 | * Neither the name of the Bitswift, Inc. nor the names of its contributors may be used to endorse or promote products derived from this software Without specific prior written permission. 18 | 19 | THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT HOLDER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. 20 | 21 | */ 22 | 23 | #import 24 | #import 25 | #import 26 | 27 | #import "MEDGeometryTestObject.h" 28 | 29 | QuickSpecBegin(CGGeometryAdditions) 30 | 31 | qck_describe(@"MEDRectDivide macro", ^{ 32 | CGRect rect = CGRectMake(10, 20, 30, 40); 33 | 34 | qck_it(@"should accept NULLs", ^{ 35 | MEDRectDivide(rect, NULL, NULL, 10, CGRectMinXEdge); 36 | }); 37 | 38 | qck_it(@"should accept pointers", ^{ 39 | CGRect slice, remainder; 40 | MEDRectDivide(rect, &slice, &remainder, 10, CGRectMinXEdge); 41 | 42 | expect(MEDBox(slice)).to(equal(MEDBox(CGRectMake(10, 20, 10, 40)))); 43 | expect(MEDBox(remainder)).to(equal(MEDBox(CGRectMake(20, 20, 20, 40)))); 44 | }); 45 | 46 | qck_it(@"should accept raw variables", ^{ 47 | CGRect slice, remainder; 48 | MEDRectDivide(rect, slice, remainder, 10, CGRectMinXEdge); 49 | 50 | expect(MEDBox(slice)).to(equal(MEDBox(CGRectMake(10, 20, 10, 40)))); 51 | expect(MEDBox(remainder)).to(equal(MEDBox(CGRectMake(20, 20, 20, 40)))); 52 | }); 53 | 54 | qck_it(@"should accept properties", ^{ 55 | MEDGeometryTestObject *obj = [[MEDGeometryTestObject alloc] init]; 56 | expect(obj).notTo(beNil()); 57 | 58 | MEDRectDivide(rect, obj.slice, obj.remainder, 10, CGRectMinXEdge); 59 | 60 | expect(MEDBox(obj.slice)).to(equal(MEDBox(CGRectMake(10, 20, 10, 40)))); 61 | expect(MEDBox(obj.remainder)).to(equal(MEDBox(CGRectMake(20, 20, 20, 40)))); 62 | }); 63 | }); 64 | 65 | qck_describe(@"MEDRectCenterPoint", ^{ 66 | qck_it(@"should return the center of a valid rectangle", ^{ 67 | CGRect rect = CGRectMake(10, 20, 30, 40); 68 | expect(MEDBox(MEDRectCenterPoint(rect))).to(equal(MEDBox(CGPointMake(25, 40)))); 69 | }); 70 | 71 | qck_it(@"should return the center of an empty rectangle", ^{ 72 | CGRect rect = CGRectMake(10, 20, 0, 0); 73 | expect(MEDBox(MEDRectCenterPoint(rect))).to(equal(MEDBox(CGPointMake(10, 20)))); 74 | }); 75 | 76 | qck_it(@"should return non-integral center points", ^{ 77 | CGRect rect = CGRectMake(10, 20, 15, 7); 78 | expect(MEDBox(MEDRectCenterPoint(rect))).to(equal(MEDBox(CGPointMake(17.5f, 23.5f)))); 79 | }); 80 | }); 81 | 82 | qck_describe(@"MEDRectDivideWithPadding", ^{ 83 | CGRect rect = CGRectMake(50, 50, 100, 100); 84 | 85 | __block CGRect slice, remainder; 86 | qck_beforeEach(^{ 87 | slice = CGRectZero; 88 | remainder = CGRectZero; 89 | }); 90 | 91 | qck_it(@"should divide With padding", ^{ 92 | CGRect expectedSlice = CGRectMake(50, 50, 40, 100); 93 | CGRect expectedRemainder = CGRectMake(90 + 10, 50, 50, 100); 94 | 95 | MEDRectDivideWithPadding(rect, &slice, &remainder, 40, 10, CGRectMinXEdge); 96 | 97 | expect(MEDBox(slice)).to(equal(MEDBox(expectedSlice))); 98 | expect(MEDBox(remainder)).to(equal(MEDBox(expectedRemainder))); 99 | }); 100 | 101 | qck_it(@"should divide With a null slice", ^{ 102 | CGRect expectedRemainder = CGRectMake(90 + 10, 50, 50, 100); 103 | 104 | MEDRectDivideWithPadding(rect, NULL, &remainder, 40, 10, CGRectMinXEdge); 105 | expect(MEDBox(remainder)).to(equal(MEDBox(expectedRemainder))); 106 | }); 107 | 108 | qck_it(@"should divide With a null remainder", ^{ 109 | CGRect expectedSlice = CGRectMake(50, 50, 40, 100); 110 | MEDRectDivideWithPadding(rect, &slice, NULL, 40, 10, CGRectMinXEdge); 111 | expect(MEDBox(slice)).to(equal(MEDBox(expectedSlice))); 112 | }); 113 | 114 | qck_it(@"should divide With no space for remainder", ^{ 115 | CGRect expectedSlice = CGRectMake(50, 50, 95, 100); 116 | MEDRectDivideWithPadding(rect, &slice, &remainder, 95, 10, CGRectMinXEdge); 117 | expect(MEDBox(slice)).to(equal(MEDBox(expectedSlice))); 118 | expect(@(CGRectIsEmpty(remainder))).to(beTruthy()); 119 | }); 120 | 121 | qck_it(@"should accept raw variables", ^{ 122 | CGRect expectedSlice = CGRectMake(50, 50, 40, 100); 123 | CGRect expectedRemainder = CGRectMake(90 + 10, 50, 50, 100); 124 | 125 | MEDRectDivideWithPadding(rect, slice, remainder, 40, 10, CGRectMinXEdge); 126 | 127 | expect(MEDBox(slice)).to(equal(MEDBox(expectedSlice))); 128 | expect(MEDBox(remainder)).to(equal(MEDBox(expectedRemainder))); 129 | }); 130 | 131 | qck_it(@"should accept properties", ^{ 132 | MEDGeometryTestObject *obj = [[MEDGeometryTestObject alloc] init]; 133 | expect(MEDBox(obj)).notTo(beNil()); 134 | 135 | CGRect expectedSlice = CGRectMake(50, 50, 40, 100); 136 | CGRect expectedRemainder = CGRectMake(90 + 10, 50, 50, 100); 137 | 138 | MEDRectDivideWithPadding(rect, obj.slice, obj.remainder, 40, 10, CGRectMinXEdge); 139 | 140 | expect(MEDBox(obj.slice)).to(equal(MEDBox(expectedSlice))); 141 | expect(MEDBox(obj.remainder)).to(equal(MEDBox(expectedRemainder))); 142 | }); 143 | }); 144 | 145 | qck_describe(@"MEDRectAlignWithRect", ^{ 146 | CGRect rect = CGRectMake(0, 0, 10, 10); 147 | CGRect referenceRect = CGRectMake(10, 20, 30, 40); 148 | 149 | qck_describe(@"when aligning on the min x edge", ^{ 150 | qck_it(@"should return an aligned rectangle", ^{ 151 | CGRect aligned = MEDRectAlignWithRect(rect, referenceRect, CGRectMinXEdge); 152 | 153 | expect(MEDBox(aligned)).to(equal(MEDBox(CGRectMake(10, 0, 10, 10)))); 154 | }); 155 | }); 156 | 157 | qck_describe(@"when aligning on the min y edge", ^{ 158 | qck_it(@"should return an aligned rectangle", ^{ 159 | CGRect aligned = MEDRectAlignWithRect(rect, referenceRect, CGRectMinYEdge); 160 | 161 | expect(MEDBox(aligned)).to(equal(MEDBox(CGRectMake(0, 20, 10, 10)))); 162 | }); 163 | }); 164 | 165 | qck_describe(@"when aligning on the max x edge", ^{ 166 | qck_it(@"should return an aligned rectangle", ^{ 167 | CGRect aligned = MEDRectAlignWithRect(rect, referenceRect, CGRectMaxXEdge); 168 | 169 | expect(MEDBox(aligned)).to(equal(MEDBox(CGRectMake(30, 0, 10, 10)))); 170 | }); 171 | }); 172 | 173 | qck_describe(@"when aligning on the max y edge", ^{ 174 | qck_it(@"should return an aligned rectangle", ^{ 175 | CGRect aligned = MEDRectAlignWithRect(rect, referenceRect, CGRectMaxYEdge); 176 | 177 | expect(MEDBox(aligned)).to(equal(MEDBox(CGRectMake(0, 50, 10, 10)))); 178 | }); 179 | }); 180 | }); 181 | 182 | qck_describe(@"MEDRectCenterInRect", ^{ 183 | qck_it(@"should return a rectangle centered in another rectangle", ^{ 184 | CGRect inner = CGRectMake(0, 0, 10, 10); 185 | CGRect outer = CGRectMake(0, 0, 20, 20); 186 | 187 | expect(MEDBox(MEDRectCenterInRect(inner, outer))).to(equal(MEDBox(CGRectMake(5, 5, 10, 10)))); 188 | }); 189 | 190 | qck_it(@"should return a non-integral rectangle", ^{ 191 | CGRect inner = CGRectMake(0, 0, 10, 10); 192 | CGRect outer = CGRectMake(0, 0, 19, 19); 193 | 194 | expect(MEDBox(MEDRectCenterInRect(inner, outer))).to(equal(MEDBox(CGRectMake(4.5f, 4.5f, 10, 10)))); 195 | }); 196 | 197 | qck_describe(@"qck_it should handle centering bigger rectanlges in smaller ones", ^{ 198 | CGRect inner = CGRectMake(0, 0, 10, 10); 199 | CGRect outer = CGRectZero; 200 | 201 | expect(MEDBox(MEDRectCenterInRect(inner, outer))).to(equal(MEDBox(CGRectMake(-5, -5, 10, 10)))); 202 | }); 203 | }); 204 | 205 | qck_describe(@"MEDRectRemainder", ^{ 206 | qck_it(@"should return the rectangle's remainder", ^{ 207 | CGRect rect = CGRectMake(100, 100, 100, 100); 208 | 209 | CGRect result = MEDRectRemainder(rect, 25, CGRectMaxXEdge); 210 | CGRect expectedResult = CGRectMake(100, 100, 75, 100); 211 | 212 | expect(MEDBox(result)).to(equal(MEDBox(expectedResult))); 213 | }); 214 | }); 215 | 216 | qck_describe(@"MEDRectSlice", ^{ 217 | qck_it(@"should return the rectangle's slice", ^{ 218 | CGRect rect = CGRectMake(100, 100, 100, 100); 219 | 220 | CGRect result = MEDRectSlice(rect, 25, CGRectMaxXEdge); 221 | CGRect expectedResult = CGRectMake(175, 100, 25, 100); 222 | 223 | expect(MEDBox(result)).to(equal(MEDBox(expectedResult))); 224 | }); 225 | }); 226 | 227 | qck_describe(@"MEDRectGrow", ^{ 228 | qck_it(@"should return a larger rectangle", ^{ 229 | CGRect rect = CGRectMake(100, 100, 100, 100); 230 | 231 | CGRect result = MEDRectGrow(rect, 25, CGRectMinXEdge); 232 | CGRect expectedResult = CGRectMake(75, 100, 125, 100); 233 | expect(MEDBox(result)).to(equal(MEDBox(expectedResult))); 234 | }); 235 | }); 236 | 237 | qck_describe(@"MEDRectFloor", ^{ 238 | qck_it(@"leaves integers untouched", ^{ 239 | CGRect rect = CGRectMake(-10, 20, -30, 40); 240 | CGRect result = MEDRectFloor(rect); 241 | expect(MEDBox(result)).to(equal(MEDBox(rect))); 242 | }); 243 | 244 | #ifdef __IPHONE_OS_VERSION_MIN_REQUIRED 245 | qck_it(@"rounds down", ^{ 246 | CGRect rect = CGRectMake(10.1f, 1.1f, -3.4f, -4.7f); 247 | 248 | CGRect result = MEDRectFloor(rect); 249 | CGRect expectedResult = CGRectMake(10, 1, -4, -5); 250 | expect(MEDBox(result)).to(equal(MEDBox(expectedResult))); 251 | }); 252 | #elif TARGET_OS_MAC 253 | qck_it(@"rounds down, except in Y", ^{ 254 | CGRect rect = CGRectMake(10.1, 1.1, -3.4, -4.7); 255 | 256 | CGRect result = MEDRectFloor(rect); 257 | CGRect expectedResult = CGRectMake(10, 2, -4, -5); 258 | expect(MEDBox(result)).to(equal(MEDBox(expectedResult))); 259 | }); 260 | #endif 261 | 262 | qck_it(@"leaves CGRectNull untouched", ^{ 263 | CGRect rect = CGRectNull; 264 | CGRect result = MEDRectFloor(rect); 265 | expect(MEDBox(result)).to(equal(MEDBox(rect))); 266 | }); 267 | 268 | qck_it(@"leaves CGRectInfinite untouched", ^{ 269 | CGRect rect = CGRectInfinite; 270 | CGRect result = MEDRectFloor(rect); 271 | expect(MEDBox(result)).to(equal(MEDBox(rect))); 272 | }); 273 | }); 274 | 275 | qck_describe(@"inverted rectangles", ^{ 276 | qck_it(@"should create an inverted rectangle Within a containing rectangle", ^{ 277 | CGRect containingRect = CGRectMake(0, 0, 100, 100); 278 | 279 | // Bottom Left 280 | CGRect expectedResult = CGRectMake(0, CGRectGetHeight(containingRect) - 20 - 50, 50, 50); 281 | 282 | CGRect result = MEDRectMakeInverted(containingRect, 0, 20, 50, 50); 283 | expect(MEDBox(result)).to(equal(MEDBox(expectedResult))); 284 | }); 285 | 286 | qck_it(@"should invert a rectangle Within a containing rectangle", ^{ 287 | CGRect rect = CGRectMake(0, 20, 50, 50); 288 | CGRect containingRect = CGRectMake(0, 0, 100, 100); 289 | 290 | // Bottom Left 291 | CGRect expectedResult = CGRectMake(0, CGRectGetHeight(containingRect) - 20 - 50, 50, 50); 292 | 293 | CGRect result = MEDRectInvert(containingRect, rect); 294 | expect(MEDBox(result)).to(equal(MEDBox(expectedResult))); 295 | }); 296 | }); 297 | 298 | qck_describe(@"MEDRectWithSize", ^{ 299 | qck_it(@"should return a rectangle With a valid size", ^{ 300 | CGRect rect = MEDRectWithSize(CGSizeMake(20, 40)); 301 | expect(MEDBox(rect)).to(equal(MEDBox(CGRectMake(0, 0, 20, 40)))); 302 | }); 303 | 304 | qck_it(@"should return a rectangle With zero size", ^{ 305 | CGRect rect = MEDRectWithSize(CGSizeZero); 306 | expect(MEDBox(rect)).to(equal(MEDBox(CGRectZero))); 307 | }); 308 | }); 309 | 310 | qck_describe(@"MEDRectConvertToUnitRect", ^{ 311 | qck_it(@"should return a rectangle With unit coordinates", ^{ 312 | CGRect rect = MEDRectConvertToUnitRect(CGRectMake(0, 0, 100, 100)); 313 | expect(MEDBox(rect)).to(equal(MEDBox(CGRectMake(0, 0, 1, 1)))); 314 | }); 315 | }); 316 | 317 | qck_describe(@"MEDRectConvertFromUnitRect", ^{ 318 | qck_it(@"should return a rectangle With non-unit coordinates", ^{ 319 | CGRect viewRect = CGRectMake(0, 0, 100, 100); 320 | CGRect unitRect = CGRectMake(0, 0, 0.5, 0.5); 321 | CGRect rect = MEDRectConvertFromUnitRect(unitRect, viewRect); 322 | expect(MEDBox(rect)).to(equal(MEDBox(CGRectMake(0, 0, 50, 50)))); 323 | }); 324 | }); 325 | 326 | qck_describe(@"MEDPointFloor", ^{ 327 | #ifdef __IPHONE_OS_VERSION_MIN_REQUIRED 328 | qck_it(@"rounds components up and left", ^{ 329 | CGPoint point = CGPointMake(0.5f, 0.49f); 330 | CGPoint point2 = CGPointMake(-0.5f, -0.49f); 331 | expect(@(CGPointEqualToPoint(MEDPointFloor(point), CGPointMake(0, 0)))).to(beTruthy()); 332 | expect(@(CGPointEqualToPoint(MEDPointFloor(point2), CGPointMake(-1, -1)))).to(beTruthy()); 333 | }); 334 | #elif TARGET_OS_MAC 335 | qck_it(@"rounds components up and left", ^{ 336 | CGPoint point = CGPointMake(0.5, 0.49); 337 | CGPoint point2 = CGPointMake(-0.5, -0.49); 338 | expect(@(CGPointEqualToPoint(MEDPointFloor(point), CGPointMake(0, 1)))).to(beTruthy()); 339 | expect(@(CGPointEqualToPoint(MEDPointFloor(point2), CGPointMake(-1, 0)))).to(beTruthy()); 340 | }); 341 | #endif 342 | }); 343 | 344 | qck_describe(@"equality With accuracy", ^{ 345 | CGRect rect = CGRectMake(0.5f, 1.5f, 15, 20); 346 | CGFloat epsilon = 0.6f; 347 | 348 | CGRect closeRect = CGRectMake(1, 1, 15.5f, 19.75f); 349 | CGRect farRect = CGRectMake(1.5f, 11.5f, 20, 20); 350 | 351 | qck_it(@"compares two points that are close enough", ^{ 352 | expect(@(MEDPointEqualToPointWithAccuracy(rect.origin, closeRect.origin, epsilon))).to(beTruthy()); 353 | }); 354 | 355 | qck_it(@"compares two points that are too far from each other", ^{ 356 | expect(@(MEDPointEqualToPointWithAccuracy(rect.origin, farRect.origin, epsilon))).to(beFalsy()); 357 | }); 358 | 359 | qck_it(@"compares two rectangles that are close enough", ^{ 360 | expect(@(MEDRectEqualToRectWithAccuracy(rect, closeRect, epsilon))).to(beTruthy()); 361 | }); 362 | 363 | qck_it(@"compares two rectangles that are too far from each other", ^{ 364 | expect(@(MEDRectEqualToRectWithAccuracy(rect, farRect, epsilon))).to(beFalsy()); 365 | }); 366 | 367 | qck_it(@"compares two sizes that are close enough", ^{ 368 | expect(@(MEDSizeEqualToSizeWithAccuracy(rect.size, closeRect.size, epsilon))).to(beTruthy()); 369 | }); 370 | 371 | qck_it(@"compares two sizes that are too far from each other", ^{ 372 | expect(@(MEDSizeEqualToSizeWithAccuracy(rect.size, farRect.size, epsilon))).to(beFalsy()); 373 | }); 374 | }); 375 | 376 | qck_describe(@"MEDSizeScale", ^{ 377 | qck_it(@"should scale each component", ^{ 378 | CGSize original = CGSizeMake(-5, 3.4f); 379 | CGFloat scale = -3.5f; 380 | 381 | CGSize scaledSize = MEDSizeScale(original, scale); 382 | CGSize expected = CGSizeMake(17.5f, -11.9f); 383 | 384 | expect(@(scaledSize.width)).to(beCloseTo(@(expected.width))); 385 | expect(@(scaledSize.height)).to(beCloseTo(@(expected.height))); 386 | }); 387 | }); 388 | 389 | qck_describe(@"MEDSizeScaleAspectFqck_it", ^{ 390 | CGSize containingSize = CGSizeMake(75, 75); 391 | 392 | qck_it(@"should return a size which fits inside the given size when the width is bigger", ^{ 393 | CGSize sizeToScale = CGSizeMake(100, 75); 394 | CGSize size = MEDSizeScaleAspectFit(sizeToScale, containingSize); 395 | expect(MEDBox(size)).to(equal(MEDBox(CGSizeMake(75, 56.25)))); 396 | }); 397 | 398 | qck_it(@"should return a size which fits inside the given size when the height is bigger", ^{ 399 | CGSize sizeToScale = CGSizeMake(75, 100); 400 | CGSize size = MEDSizeScaleAspectFit(sizeToScale, containingSize); 401 | expect(MEDBox(size)).to(equal(MEDBox(CGSizeMake(56.25, 75)))); 402 | }); 403 | }); 404 | 405 | qck_describe(@"MEDSizeScaleAspectFill", ^{ 406 | CGSize containingSize = CGSizeMake(75, 75); 407 | 408 | qck_it(@"should return a size which fills the given size when the width is bigger", ^{ 409 | CGSize sizeToScale = CGSizeMake(100, 75); 410 | CGSize size = MEDSizeScaleAspectFill(sizeToScale, containingSize); 411 | expect(MEDBox(size)).to(equal(MEDBox(CGSizeMake(100, 75)))); 412 | }); 413 | 414 | qck_it(@"should return a size which fills the given size when the height is bigger", ^{ 415 | CGSize sizeToScale = CGSizeMake(75, 100); 416 | CGSize size = MEDSizeScaleAspectFill(sizeToScale, containingSize); 417 | expect(MEDBox(size)).to(equal(MEDBox(CGSizeMake(75, 100)))); 418 | }); 419 | }); 420 | 421 | qck_describe(@"MEDPointAdd", ^{ 422 | qck_it(@"adds two points together, element-wise", ^{ 423 | CGPoint point1 = CGPointMake(-1, 5); 424 | CGPoint point2 = CGPointMake(10, 12); 425 | CGPoint sum = MEDPointAdd(point1, point2); 426 | expect(MEDBox(sum)).to(equal(MEDBox(CGPointMake(9, 17)))); 427 | }); 428 | }); 429 | 430 | qck_describe(@"MEDPointSubtract", ^{ 431 | qck_it(@"adds two points together, element-wise", ^{ 432 | CGPoint point1 = CGPointMake(-1, 5); 433 | CGPoint point2 = CGPointMake(10, 12); 434 | CGPoint diff = MEDPointSubtract(point1, point2); 435 | expect(MEDBox(diff)).to(equal(MEDBox(CGPointMake(-11, -7)))); 436 | }); 437 | }); 438 | 439 | QuickSpecEnd 440 | -------------------------------------------------------------------------------- /Archimedes.xcodeproj/project.pbxproj: -------------------------------------------------------------------------------- 1 | // !$*UTF8*$! 2 | { 3 | archiveVersion = 1; 4 | classes = { 5 | }; 6 | objectVersion = 46; 7 | objects = { 8 | 9 | /* Begin PBXBuildFile section */ 10 | D038E06619DDC7A300ABCE67 /* Archimedes.framework in Frameworks */ = {isa = PBXBuildFile; fileRef = D038E05B19DDC7A200ABCE67 /* Archimedes.framework */; }; 11 | D09C73FE19DDC8510067EB29 /* Archimedes.framework in Frameworks */ = {isa = PBXBuildFile; fileRef = D09C73F319DDC8500067EB29 /* Archimedes.framework */; }; 12 | D09C741019DDC9CA0067EB29 /* CGGeometry+MEDConvenienceAdditions.h in Headers */ = {isa = PBXBuildFile; fileRef = D02FAFDC1635E1E9008D42D9 /* CGGeometry+MEDConvenienceAdditions.h */; settings = {ATTRIBUTES = (Public, ); }; }; 13 | D09C741119DDC9CA0067EB29 /* CGGeometry+MEDConvenienceAdditions.m in Sources */ = {isa = PBXBuildFile; fileRef = D02FAFDD1635E1E9008D42D9 /* CGGeometry+MEDConvenienceAdditions.m */; }; 14 | D09C741219DDC9CA0067EB29 /* NSValue+MEDGeometryAdditions.h in Headers */ = {isa = PBXBuildFile; fileRef = D0626A9B1679506E00E951A5 /* NSValue+MEDGeometryAdditions.h */; settings = {ATTRIBUTES = (Public, ); }; }; 15 | D09C741319DDC9CA0067EB29 /* NSValue+MEDGeometryAdditions.m in Sources */ = {isa = PBXBuildFile; fileRef = D0626A9C1679506E00E951A5 /* NSValue+MEDGeometryAdditions.m */; }; 16 | D09C741419DDC9CA0067EB29 /* MEDEdgeInsets.h in Headers */ = {isa = PBXBuildFile; fileRef = 0378ABA517B16F980056C690 /* MEDEdgeInsets.h */; settings = {ATTRIBUTES = (Public, ); }; }; 17 | D09C741519DDC9CA0067EB29 /* MEDEdgeInsets.m in Sources */ = {isa = PBXBuildFile; fileRef = 0378ABA617B16F980056C690 /* MEDEdgeInsets.m */; }; 18 | D09C741619DDC9CB0067EB29 /* CGGeometry+MEDConvenienceAdditions.h in Headers */ = {isa = PBXBuildFile; fileRef = D02FAFDC1635E1E9008D42D9 /* CGGeometry+MEDConvenienceAdditions.h */; settings = {ATTRIBUTES = (Public, ); }; }; 19 | D09C741719DDC9CB0067EB29 /* CGGeometry+MEDConvenienceAdditions.m in Sources */ = {isa = PBXBuildFile; fileRef = D02FAFDD1635E1E9008D42D9 /* CGGeometry+MEDConvenienceAdditions.m */; }; 20 | D09C741819DDC9CB0067EB29 /* NSValue+MEDGeometryAdditions.h in Headers */ = {isa = PBXBuildFile; fileRef = D0626A9B1679506E00E951A5 /* NSValue+MEDGeometryAdditions.h */; settings = {ATTRIBUTES = (Public, ); }; }; 21 | D09C741919DDC9CB0067EB29 /* NSValue+MEDGeometryAdditions.m in Sources */ = {isa = PBXBuildFile; fileRef = D0626A9C1679506E00E951A5 /* NSValue+MEDGeometryAdditions.m */; }; 22 | D09C741A19DDC9CB0067EB29 /* MEDEdgeInsets.h in Headers */ = {isa = PBXBuildFile; fileRef = 0378ABA517B16F980056C690 /* MEDEdgeInsets.h */; settings = {ATTRIBUTES = (Public, ); }; }; 23 | D09C741B19DDC9CB0067EB29 /* MEDEdgeInsets.m in Sources */ = {isa = PBXBuildFile; fileRef = 0378ABA617B16F980056C690 /* MEDEdgeInsets.m */; }; 24 | D09C742119DDC9DC0067EB29 /* MEDCGGeometryAdditionsSpec.m in Sources */ = {isa = PBXBuildFile; fileRef = D02FAFD31635E1A8008D42D9 /* MEDCGGeometryAdditionsSpec.m */; }; 25 | D09C742219DDC9DC0067EB29 /* MEDNSValueAdditionsSpec.m in Sources */ = {isa = PBXBuildFile; fileRef = D0626AA0167950D200E951A5 /* MEDNSValueAdditionsSpec.m */; }; 26 | D09C742319DDC9DC0067EB29 /* MEDEdgeInsetsSpec.m in Sources */ = {isa = PBXBuildFile; fileRef = 0378ABC317B17A160056C690 /* MEDEdgeInsetsSpec.m */; }; 27 | D09C742419DDC9DC0067EB29 /* MEDGeometryTestObject.m in Sources */ = {isa = PBXBuildFile; fileRef = D02FAFD81635E1BF008D42D9 /* MEDGeometryTestObject.m */; }; 28 | D09C742519DDC9DD0067EB29 /* MEDCGGeometryAdditionsSpec.m in Sources */ = {isa = PBXBuildFile; fileRef = D02FAFD31635E1A8008D42D9 /* MEDCGGeometryAdditionsSpec.m */; }; 29 | D09C742619DDC9DD0067EB29 /* MEDNSValueAdditionsSpec.m in Sources */ = {isa = PBXBuildFile; fileRef = D0626AA0167950D200E951A5 /* MEDNSValueAdditionsSpec.m */; }; 30 | D09C742719DDC9DD0067EB29 /* MEDEdgeInsetsSpec.m in Sources */ = {isa = PBXBuildFile; fileRef = 0378ABC317B17A160056C690 /* MEDEdgeInsetsSpec.m */; }; 31 | D09C742819DDC9DD0067EB29 /* MEDGeometryTestObject.m in Sources */ = {isa = PBXBuildFile; fileRef = D02FAFD81635E1BF008D42D9 /* MEDGeometryTestObject.m */; }; 32 | D09C743119DDCB800067EB29 /* Archimedes.h in Headers */ = {isa = PBXBuildFile; fileRef = D02FAEE51635DDC0008D42D9 /* Archimedes.h */; settings = {ATTRIBUTES = (Public, ); }; }; 33 | D09C743219DDCB800067EB29 /* Archimedes.h in Headers */ = {isa = PBXBuildFile; fileRef = D02FAEE51635DDC0008D42D9 /* Archimedes.h */; settings = {ATTRIBUTES = (Public, ); }; }; 34 | D0BB439619DDD7B400A8243F /* SwiftSpec.swift in Sources */ = {isa = PBXBuildFile; fileRef = D0BB439519DDD7B400A8243F /* SwiftSpec.swift */; }; 35 | D0BB439719DDD7B400A8243F /* SwiftSpec.swift in Sources */ = {isa = PBXBuildFile; fileRef = D0BB439519DDD7B400A8243F /* SwiftSpec.swift */; }; 36 | D0BB439F19DDE84400A8243F /* UIKit.framework in Frameworks */ = {isa = PBXBuildFile; fileRef = D0BB439E19DDE84400A8243F /* UIKit.framework */; }; 37 | D4D8B80119DEF1C20043808D /* Nimble.framework in Frameworks */ = {isa = PBXBuildFile; fileRef = D09C742F19DDCA940067EB29 /* Nimble.framework */; }; 38 | D4D8B80719DF04E40043808D /* Nimble.framework in Frameworks */ = {isa = PBXBuildFile; fileRef = D4D8B80519DF04BE0043808D /* Nimble.framework */; }; 39 | D4D8B80819DF04E80043808D /* Nimble.framework in Copy Frameworks */ = {isa = PBXBuildFile; fileRef = D4D8B80519DF04BE0043808D /* Nimble.framework */; settings = {ATTRIBUTES = (CodeSignOnCopy, RemoveHeadersOnCopy, ); }; }; 40 | D4D8B81819DF07C20043808D /* Quick.framework in Frameworks */ = {isa = PBXBuildFile; fileRef = D4D8B81419DF07390043808D /* Quick.framework */; }; 41 | D4D8B81919DF07C60043808D /* Quick.framework in Copy Frameworks */ = {isa = PBXBuildFile; fileRef = D4D8B81419DF07390043808D /* Quick.framework */; settings = {ATTRIBUTES = (CodeSignOnCopy, RemoveHeadersOnCopy, ); }; }; 42 | D4D8B81C19DF07DC0043808D /* Quick.framework in Frameworks */ = {isa = PBXBuildFile; fileRef = D4D8B81A19DF07D40043808D /* Quick.framework */; }; 43 | D4D8B81D19DF08300043808D /* Archimedes.framework in Copy Frameworks */ = {isa = PBXBuildFile; fileRef = D09C73F319DDC8500067EB29 /* Archimedes.framework */; settings = {ATTRIBUTES = (CodeSignOnCopy, RemoveHeadersOnCopy, ); }; }; 44 | /* End PBXBuildFile section */ 45 | 46 | /* Begin PBXContainerItemProxy section */ 47 | D038E06719DDC7A300ABCE67 /* PBXContainerItemProxy */ = { 48 | isa = PBXContainerItemProxy; 49 | containerPortal = D02FAED01635DDC0008D42D9 /* Project object */; 50 | proxyType = 1; 51 | remoteGlobalIDString = D038E05A19DDC7A200ABCE67; 52 | remoteInfo = Archimedes; 53 | }; 54 | D09C73FF19DDC8510067EB29 /* PBXContainerItemProxy */ = { 55 | isa = PBXContainerItemProxy; 56 | containerPortal = D02FAED01635DDC0008D42D9 /* Project object */; 57 | proxyType = 1; 58 | remoteGlobalIDString = D09C73F219DDC8500067EB29; 59 | remoteInfo = Archimedes; 60 | }; 61 | /* End PBXContainerItemProxy section */ 62 | 63 | /* Begin PBXCopyFilesBuildPhase section */ 64 | D4D8B7FE19DEF0DB0043808D /* Copy Frameworks */ = { 65 | isa = PBXCopyFilesBuildPhase; 66 | buildActionMask = 2147483647; 67 | dstPath = ""; 68 | dstSubfolderSpec = 10; 69 | files = ( 70 | D4D8B80819DF04E80043808D /* Nimble.framework in Copy Frameworks */, 71 | D4D8B81919DF07C60043808D /* Quick.framework in Copy Frameworks */, 72 | D4D8B81D19DF08300043808D /* Archimedes.framework in Copy Frameworks */, 73 | ); 74 | name = "Copy Frameworks"; 75 | runOnlyForDeploymentPostprocessing = 0; 76 | }; 77 | /* End PBXCopyFilesBuildPhase section */ 78 | 79 | /* Begin PBXFileReference section */ 80 | 0378ABA517B16F980056C690 /* MEDEdgeInsets.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = MEDEdgeInsets.h; sourceTree = ""; }; 81 | 0378ABA617B16F980056C690 /* MEDEdgeInsets.m */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.objc; path = MEDEdgeInsets.m; sourceTree = ""; }; 82 | 0378ABC317B17A160056C690 /* MEDEdgeInsetsSpec.m */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.objc; path = MEDEdgeInsetsSpec.m; sourceTree = ""; }; 83 | D02FAEE11635DDC0008D42D9 /* Foundation.framework */ = {isa = PBXFileReference; lastKnownFileType = wrapper.framework; name = Foundation.framework; path = System/Library/Frameworks/Foundation.framework; sourceTree = SDKROOT; }; 84 | D02FAEE51635DDC0008D42D9 /* Archimedes.h */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.c.h; path = Archimedes.h; sourceTree = ""; }; 85 | D02FAEF61635DDC0008D42D9 /* ArchimedesTests-Info.plist */ = {isa = PBXFileReference; lastKnownFileType = text.plist.xml; path = "ArchimedesTests-Info.plist"; sourceTree = ""; }; 86 | D02FAEF81635DDC0008D42D9 /* en */ = {isa = PBXFileReference; lastKnownFileType = text.plist.strings; name = en; path = en.lproj/InfoPlist.strings; sourceTree = ""; }; 87 | D02FAFD31635E1A8008D42D9 /* MEDCGGeometryAdditionsSpec.m */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.objc; path = MEDCGGeometryAdditionsSpec.m; sourceTree = ""; }; 88 | D02FAFD71635E1BF008D42D9 /* MEDGeometryTestObject.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = MEDGeometryTestObject.h; sourceTree = ""; }; 89 | D02FAFD81635E1BF008D42D9 /* MEDGeometryTestObject.m */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.objc; path = MEDGeometryTestObject.m; sourceTree = ""; }; 90 | D02FAFDC1635E1E9008D42D9 /* CGGeometry+MEDConvenienceAdditions.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = "CGGeometry+MEDConvenienceAdditions.h"; sourceTree = ""; }; 91 | D02FAFDD1635E1E9008D42D9 /* CGGeometry+MEDConvenienceAdditions.m */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.objc; path = "CGGeometry+MEDConvenienceAdditions.m"; sourceTree = ""; }; 92 | D038E04019DDC74A00ABCE67 /* Common.xcconfig */ = {isa = PBXFileReference; lastKnownFileType = text.xcconfig; path = Common.xcconfig; sourceTree = ""; }; 93 | D038E04219DDC74A00ABCE67 /* Debug.xcconfig */ = {isa = PBXFileReference; lastKnownFileType = text.xcconfig; path = Debug.xcconfig; sourceTree = ""; }; 94 | D038E04319DDC74A00ABCE67 /* Profile.xcconfig */ = {isa = PBXFileReference; lastKnownFileType = text.xcconfig; path = Profile.xcconfig; sourceTree = ""; }; 95 | D038E04419DDC74A00ABCE67 /* Release.xcconfig */ = {isa = PBXFileReference; lastKnownFileType = text.xcconfig; path = Release.xcconfig; sourceTree = ""; }; 96 | D038E04519DDC74A00ABCE67 /* Test.xcconfig */ = {isa = PBXFileReference; lastKnownFileType = text.xcconfig; path = Test.xcconfig; sourceTree = ""; }; 97 | D038E04719DDC74A00ABCE67 /* Application.xcconfig */ = {isa = PBXFileReference; lastKnownFileType = text.xcconfig; path = Application.xcconfig; sourceTree = ""; }; 98 | D038E04819DDC74A00ABCE67 /* Framework.xcconfig */ = {isa = PBXFileReference; lastKnownFileType = text.xcconfig; path = Framework.xcconfig; sourceTree = ""; }; 99 | D038E04919DDC74A00ABCE67 /* StaticLibrary.xcconfig */ = {isa = PBXFileReference; lastKnownFileType = text.xcconfig; path = StaticLibrary.xcconfig; sourceTree = ""; }; 100 | D038E04B19DDC74A00ABCE67 /* iOS-Application.xcconfig */ = {isa = PBXFileReference; lastKnownFileType = text.xcconfig; path = "iOS-Application.xcconfig"; sourceTree = ""; }; 101 | D038E04C19DDC74A00ABCE67 /* iOS-Base.xcconfig */ = {isa = PBXFileReference; lastKnownFileType = text.xcconfig; path = "iOS-Base.xcconfig"; sourceTree = ""; }; 102 | D038E04D19DDC74A00ABCE67 /* iOS-Framework.xcconfig */ = {isa = PBXFileReference; lastKnownFileType = text.xcconfig; path = "iOS-Framework.xcconfig"; sourceTree = ""; }; 103 | D038E04E19DDC74A00ABCE67 /* iOS-StaticLibrary.xcconfig */ = {isa = PBXFileReference; lastKnownFileType = text.xcconfig; path = "iOS-StaticLibrary.xcconfig"; sourceTree = ""; }; 104 | D038E05019DDC74A00ABCE67 /* Mac-Application.xcconfig */ = {isa = PBXFileReference; lastKnownFileType = text.xcconfig; path = "Mac-Application.xcconfig"; sourceTree = ""; }; 105 | D038E05119DDC74A00ABCE67 /* Mac-Base.xcconfig */ = {isa = PBXFileReference; lastKnownFileType = text.xcconfig; path = "Mac-Base.xcconfig"; sourceTree = ""; }; 106 | D038E05219DDC74A00ABCE67 /* Mac-DynamicLibrary.xcconfig */ = {isa = PBXFileReference; lastKnownFileType = text.xcconfig; path = "Mac-DynamicLibrary.xcconfig"; sourceTree = ""; }; 107 | D038E05319DDC74A00ABCE67 /* Mac-Framework.xcconfig */ = {isa = PBXFileReference; lastKnownFileType = text.xcconfig; path = "Mac-Framework.xcconfig"; sourceTree = ""; }; 108 | D038E05419DDC74A00ABCE67 /* Mac-StaticLibrary.xcconfig */ = {isa = PBXFileReference; lastKnownFileType = text.xcconfig; path = "Mac-StaticLibrary.xcconfig"; sourceTree = ""; }; 109 | D038E05519DDC74A00ABCE67 /* README.md */ = {isa = PBXFileReference; lastKnownFileType = net.daringfireball.markdown; path = README.md; sourceTree = ""; }; 110 | D038E05B19DDC7A200ABCE67 /* Archimedes.framework */ = {isa = PBXFileReference; explicitFileType = wrapper.framework; includeInIndex = 0; path = Archimedes.framework; sourceTree = BUILT_PRODUCTS_DIR; }; 111 | D038E06519DDC7A200ABCE67 /* Archimedes-MacTests.xctest */ = {isa = PBXFileReference; explicitFileType = wrapper.cfbundle; includeInIndex = 0; path = "Archimedes-MacTests.xctest"; sourceTree = BUILT_PRODUCTS_DIR; }; 112 | D0626A9B1679506E00E951A5 /* NSValue+MEDGeometryAdditions.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = "NSValue+MEDGeometryAdditions.h"; sourceTree = ""; }; 113 | D0626A9C1679506E00E951A5 /* NSValue+MEDGeometryAdditions.m */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.objc; path = "NSValue+MEDGeometryAdditions.m"; sourceTree = ""; }; 114 | D0626AA0167950D200E951A5 /* MEDNSValueAdditionsSpec.m */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.objc; path = MEDNSValueAdditionsSpec.m; sourceTree = ""; }; 115 | D09C73F319DDC8500067EB29 /* Archimedes.framework */ = {isa = PBXFileReference; explicitFileType = wrapper.framework; includeInIndex = 0; path = Archimedes.framework; sourceTree = BUILT_PRODUCTS_DIR; }; 116 | D09C73FD19DDC8510067EB29 /* Archimedes-iOSTests.xctest */ = {isa = PBXFileReference; explicitFileType = wrapper.cfbundle; includeInIndex = 0; path = "Archimedes-iOSTests.xctest"; sourceTree = BUILT_PRODUCTS_DIR; }; 117 | D09C742F19DDCA940067EB29 /* Nimble.framework */ = {isa = PBXFileReference; lastKnownFileType = wrapper.framework; path = Nimble.framework; sourceTree = BUILT_PRODUCTS_DIR; }; 118 | D0BB439519DDD7B400A8243F /* SwiftSpec.swift */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.swift; path = SwiftSpec.swift; sourceTree = ""; }; 119 | D0BB439E19DDE84400A8243F /* UIKit.framework */ = {isa = PBXFileReference; lastKnownFileType = wrapper.framework; name = UIKit.framework; path = ../../../../iPhoneOS.platform/Developer/SDKs/iPhoneOS.sdk/System/Library/Frameworks/UIKit.framework; sourceTree = SDKROOT; }; 120 | D4D8B80519DF04BE0043808D /* Nimble.framework */ = {isa = PBXFileReference; lastKnownFileType = wrapper.framework; name = Nimble.framework; path = "../Debug-iphonesimulator/Nimble.framework"; sourceTree = BUILT_PRODUCTS_DIR; }; 121 | D4D8B81419DF07390043808D /* Quick.framework */ = {isa = PBXFileReference; lastKnownFileType = wrapper.framework; name = Quick.framework; path = "../Debug-iphonesimulator/Quick.framework"; sourceTree = BUILT_PRODUCTS_DIR; }; 122 | D4D8B81A19DF07D40043808D /* Quick.framework */ = {isa = PBXFileReference; lastKnownFileType = wrapper.framework; path = Quick.framework; sourceTree = BUILT_PRODUCTS_DIR; }; 123 | /* End PBXFileReference section */ 124 | 125 | /* Begin PBXFrameworksBuildPhase section */ 126 | D038E05719DDC7A200ABCE67 /* Frameworks */ = { 127 | isa = PBXFrameworksBuildPhase; 128 | buildActionMask = 2147483647; 129 | files = ( 130 | ); 131 | runOnlyForDeploymentPostprocessing = 0; 132 | }; 133 | D038E06219DDC7A200ABCE67 /* Frameworks */ = { 134 | isa = PBXFrameworksBuildPhase; 135 | buildActionMask = 2147483647; 136 | files = ( 137 | D4D8B80119DEF1C20043808D /* Nimble.framework in Frameworks */, 138 | D4D8B81C19DF07DC0043808D /* Quick.framework in Frameworks */, 139 | D038E06619DDC7A300ABCE67 /* Archimedes.framework in Frameworks */, 140 | ); 141 | runOnlyForDeploymentPostprocessing = 0; 142 | }; 143 | D09C73EF19DDC8500067EB29 /* Frameworks */ = { 144 | isa = PBXFrameworksBuildPhase; 145 | buildActionMask = 2147483647; 146 | files = ( 147 | D0BB439F19DDE84400A8243F /* UIKit.framework in Frameworks */, 148 | ); 149 | runOnlyForDeploymentPostprocessing = 0; 150 | }; 151 | D09C73FA19DDC8510067EB29 /* Frameworks */ = { 152 | isa = PBXFrameworksBuildPhase; 153 | buildActionMask = 2147483647; 154 | files = ( 155 | D4D8B80719DF04E40043808D /* Nimble.framework in Frameworks */, 156 | D09C73FE19DDC8510067EB29 /* Archimedes.framework in Frameworks */, 157 | D4D8B81819DF07C20043808D /* Quick.framework in Frameworks */, 158 | ); 159 | runOnlyForDeploymentPostprocessing = 0; 160 | }; 161 | /* End PBXFrameworksBuildPhase section */ 162 | 163 | /* Begin PBXGroup section */ 164 | D02FAECE1635DDC0008D42D9 = { 165 | isa = PBXGroup; 166 | children = ( 167 | D02FAEE21635DDC0008D42D9 /* Archimedes */, 168 | D02FAEF41635DDC0008D42D9 /* ArchimedesTests */, 169 | D038E03E19DDC74A00ABCE67 /* Configuration */, 170 | D02FAEDB1635DDC0008D42D9 /* Frameworks */, 171 | D02FAEDA1635DDC0008D42D9 /* Products */, 172 | ); 173 | sourceTree = ""; 174 | usesTabs = 1; 175 | }; 176 | D02FAEDA1635DDC0008D42D9 /* Products */ = { 177 | isa = PBXGroup; 178 | children = ( 179 | D038E05B19DDC7A200ABCE67 /* Archimedes.framework */, 180 | D038E06519DDC7A200ABCE67 /* Archimedes-MacTests.xctest */, 181 | D09C73F319DDC8500067EB29 /* Archimedes.framework */, 182 | D09C73FD19DDC8510067EB29 /* Archimedes-iOSTests.xctest */, 183 | ); 184 | name = Products; 185 | sourceTree = ""; 186 | }; 187 | D02FAEDB1635DDC0008D42D9 /* Frameworks */ = { 188 | isa = PBXGroup; 189 | children = ( 190 | D02FAEE11635DDC0008D42D9 /* Foundation.framework */, 191 | D4D8B80419DF04960043808D /* iOS */, 192 | D4D8B80319DF048D0043808D /* Mac */, 193 | ); 194 | name = Frameworks; 195 | sourceTree = ""; 196 | }; 197 | D02FAEE21635DDC0008D42D9 /* Archimedes */ = { 198 | isa = PBXGroup; 199 | children = ( 200 | D02FAEE51635DDC0008D42D9 /* Archimedes.h */, 201 | D02FAFDB1635E1CD008D42D9 /* Extensions */, 202 | ); 203 | path = Archimedes; 204 | sourceTree = ""; 205 | }; 206 | D02FAEF41635DDC0008D42D9 /* ArchimedesTests */ = { 207 | isa = PBXGroup; 208 | children = ( 209 | D02FAFD61635E1AB008D42D9 /* Specs */, 210 | D02FAEF51635DDC0008D42D9 /* Supporting Files */, 211 | ); 212 | path = ArchimedesTests; 213 | sourceTree = ""; 214 | }; 215 | D02FAEF51635DDC0008D42D9 /* Supporting Files */ = { 216 | isa = PBXGroup; 217 | children = ( 218 | D02FAFD71635E1BF008D42D9 /* MEDGeometryTestObject.h */, 219 | D02FAFD81635E1BF008D42D9 /* MEDGeometryTestObject.m */, 220 | D02FAEF61635DDC0008D42D9 /* ArchimedesTests-Info.plist */, 221 | D02FAEF71635DDC0008D42D9 /* InfoPlist.strings */, 222 | ); 223 | name = "Supporting Files"; 224 | sourceTree = ""; 225 | }; 226 | D02FAFD61635E1AB008D42D9 /* Specs */ = { 227 | isa = PBXGroup; 228 | children = ( 229 | D02FAFD31635E1A8008D42D9 /* MEDCGGeometryAdditionsSpec.m */, 230 | D0626AA0167950D200E951A5 /* MEDNSValueAdditionsSpec.m */, 231 | 0378ABC317B17A160056C690 /* MEDEdgeInsetsSpec.m */, 232 | D0BB439519DDD7B400A8243F /* SwiftSpec.swift */, 233 | ); 234 | name = Specs; 235 | sourceTree = ""; 236 | }; 237 | D02FAFDB1635E1CD008D42D9 /* Extensions */ = { 238 | isa = PBXGroup; 239 | children = ( 240 | D02FAFDC1635E1E9008D42D9 /* CGGeometry+MEDConvenienceAdditions.h */, 241 | D02FAFDD1635E1E9008D42D9 /* CGGeometry+MEDConvenienceAdditions.m */, 242 | D0626A9B1679506E00E951A5 /* NSValue+MEDGeometryAdditions.h */, 243 | D0626A9C1679506E00E951A5 /* NSValue+MEDGeometryAdditions.m */, 244 | 0378ABA517B16F980056C690 /* MEDEdgeInsets.h */, 245 | 0378ABA617B16F980056C690 /* MEDEdgeInsets.m */, 246 | ); 247 | name = Extensions; 248 | sourceTree = ""; 249 | }; 250 | D038E03E19DDC74A00ABCE67 /* Configuration */ = { 251 | isa = PBXGroup; 252 | children = ( 253 | D038E03F19DDC74A00ABCE67 /* Base */, 254 | D038E04A19DDC74A00ABCE67 /* iOS */, 255 | D038E04F19DDC74A00ABCE67 /* Mac OS X */, 256 | D038E05519DDC74A00ABCE67 /* README.md */, 257 | ); 258 | name = Configuration; 259 | path = Carthage/Checkouts/xcconfigs; 260 | sourceTree = ""; 261 | }; 262 | D038E03F19DDC74A00ABCE67 /* Base */ = { 263 | isa = PBXGroup; 264 | children = ( 265 | D038E04019DDC74A00ABCE67 /* Common.xcconfig */, 266 | D038E04119DDC74A00ABCE67 /* Configurations */, 267 | D038E04619DDC74A00ABCE67 /* Targets */, 268 | ); 269 | path = Base; 270 | sourceTree = ""; 271 | }; 272 | D038E04119DDC74A00ABCE67 /* Configurations */ = { 273 | isa = PBXGroup; 274 | children = ( 275 | D038E04219DDC74A00ABCE67 /* Debug.xcconfig */, 276 | D038E04319DDC74A00ABCE67 /* Profile.xcconfig */, 277 | D038E04419DDC74A00ABCE67 /* Release.xcconfig */, 278 | D038E04519DDC74A00ABCE67 /* Test.xcconfig */, 279 | ); 280 | path = Configurations; 281 | sourceTree = ""; 282 | }; 283 | D038E04619DDC74A00ABCE67 /* Targets */ = { 284 | isa = PBXGroup; 285 | children = ( 286 | D038E04719DDC74A00ABCE67 /* Application.xcconfig */, 287 | D038E04819DDC74A00ABCE67 /* Framework.xcconfig */, 288 | D038E04919DDC74A00ABCE67 /* StaticLibrary.xcconfig */, 289 | ); 290 | path = Targets; 291 | sourceTree = ""; 292 | }; 293 | D038E04A19DDC74A00ABCE67 /* iOS */ = { 294 | isa = PBXGroup; 295 | children = ( 296 | D038E04B19DDC74A00ABCE67 /* iOS-Application.xcconfig */, 297 | D038E04C19DDC74A00ABCE67 /* iOS-Base.xcconfig */, 298 | D038E04D19DDC74A00ABCE67 /* iOS-Framework.xcconfig */, 299 | D038E04E19DDC74A00ABCE67 /* iOS-StaticLibrary.xcconfig */, 300 | ); 301 | path = iOS; 302 | sourceTree = ""; 303 | }; 304 | D038E04F19DDC74A00ABCE67 /* Mac OS X */ = { 305 | isa = PBXGroup; 306 | children = ( 307 | D038E05019DDC74A00ABCE67 /* Mac-Application.xcconfig */, 308 | D038E05119DDC74A00ABCE67 /* Mac-Base.xcconfig */, 309 | D038E05219DDC74A00ABCE67 /* Mac-DynamicLibrary.xcconfig */, 310 | D038E05319DDC74A00ABCE67 /* Mac-Framework.xcconfig */, 311 | D038E05419DDC74A00ABCE67 /* Mac-StaticLibrary.xcconfig */, 312 | ); 313 | path = "Mac OS X"; 314 | sourceTree = ""; 315 | }; 316 | D4D8B80319DF048D0043808D /* Mac */ = { 317 | isa = PBXGroup; 318 | children = ( 319 | D4D8B81A19DF07D40043808D /* Quick.framework */, 320 | D09C742F19DDCA940067EB29 /* Nimble.framework */, 321 | ); 322 | name = Mac; 323 | sourceTree = ""; 324 | }; 325 | D4D8B80419DF04960043808D /* iOS */ = { 326 | isa = PBXGroup; 327 | children = ( 328 | D4D8B80519DF04BE0043808D /* Nimble.framework */, 329 | D4D8B81419DF07390043808D /* Quick.framework */, 330 | D0BB439E19DDE84400A8243F /* UIKit.framework */, 331 | ); 332 | name = iOS; 333 | sourceTree = ""; 334 | }; 335 | /* End PBXGroup section */ 336 | 337 | /* Begin PBXHeadersBuildPhase section */ 338 | D038E05819DDC7A200ABCE67 /* Headers */ = { 339 | isa = PBXHeadersBuildPhase; 340 | buildActionMask = 2147483647; 341 | files = ( 342 | D09C741419DDC9CA0067EB29 /* MEDEdgeInsets.h in Headers */, 343 | D09C741219DDC9CA0067EB29 /* NSValue+MEDGeometryAdditions.h in Headers */, 344 | D09C741019DDC9CA0067EB29 /* CGGeometry+MEDConvenienceAdditions.h in Headers */, 345 | D09C743119DDCB800067EB29 /* Archimedes.h in Headers */, 346 | ); 347 | runOnlyForDeploymentPostprocessing = 0; 348 | }; 349 | D09C73F019DDC8500067EB29 /* Headers */ = { 350 | isa = PBXHeadersBuildPhase; 351 | buildActionMask = 2147483647; 352 | files = ( 353 | D09C741A19DDC9CB0067EB29 /* MEDEdgeInsets.h in Headers */, 354 | D09C741819DDC9CB0067EB29 /* NSValue+MEDGeometryAdditions.h in Headers */, 355 | D09C741619DDC9CB0067EB29 /* CGGeometry+MEDConvenienceAdditions.h in Headers */, 356 | D09C743219DDCB800067EB29 /* Archimedes.h in Headers */, 357 | ); 358 | runOnlyForDeploymentPostprocessing = 0; 359 | }; 360 | /* End PBXHeadersBuildPhase section */ 361 | 362 | /* Begin PBXNativeTarget section */ 363 | D038E05A19DDC7A200ABCE67 /* Archimedes-Mac */ = { 364 | isa = PBXNativeTarget; 365 | buildConfigurationList = D038E06E19DDC7A300ABCE67 /* Build configuration list for PBXNativeTarget "Archimedes-Mac" */; 366 | buildPhases = ( 367 | D038E05619DDC7A200ABCE67 /* Sources */, 368 | D038E05719DDC7A200ABCE67 /* Frameworks */, 369 | D038E05819DDC7A200ABCE67 /* Headers */, 370 | D038E05919DDC7A200ABCE67 /* Resources */, 371 | ); 372 | buildRules = ( 373 | ); 374 | dependencies = ( 375 | ); 376 | name = "Archimedes-Mac"; 377 | productName = Archimedes; 378 | productReference = D038E05B19DDC7A200ABCE67 /* Archimedes.framework */; 379 | productType = "com.apple.product-type.framework"; 380 | }; 381 | D038E06419DDC7A200ABCE67 /* Archimedes-MacTests */ = { 382 | isa = PBXNativeTarget; 383 | buildConfigurationList = D038E07319DDC7A300ABCE67 /* Build configuration list for PBXNativeTarget "Archimedes-MacTests" */; 384 | buildPhases = ( 385 | D038E06119DDC7A200ABCE67 /* Sources */, 386 | D038E06219DDC7A200ABCE67 /* Frameworks */, 387 | D038E06319DDC7A200ABCE67 /* Resources */, 388 | ); 389 | buildRules = ( 390 | ); 391 | dependencies = ( 392 | D038E06819DDC7A300ABCE67 /* PBXTargetDependency */, 393 | ); 394 | name = "Archimedes-MacTests"; 395 | productName = ArchimedesTests; 396 | productReference = D038E06519DDC7A200ABCE67 /* Archimedes-MacTests.xctest */; 397 | productType = "com.apple.product-type.bundle.unit-test"; 398 | }; 399 | D09C73F219DDC8500067EB29 /* Archimedes-iOS */ = { 400 | isa = PBXNativeTarget; 401 | buildConfigurationList = D09C740619DDC8510067EB29 /* Build configuration list for PBXNativeTarget "Archimedes-iOS" */; 402 | buildPhases = ( 403 | D09C73EE19DDC8500067EB29 /* Sources */, 404 | D09C73EF19DDC8500067EB29 /* Frameworks */, 405 | D09C73F019DDC8500067EB29 /* Headers */, 406 | D09C73F119DDC8500067EB29 /* Resources */, 407 | ); 408 | buildRules = ( 409 | ); 410 | dependencies = ( 411 | ); 412 | name = "Archimedes-iOS"; 413 | productName = Archimedes; 414 | productReference = D09C73F319DDC8500067EB29 /* Archimedes.framework */; 415 | productType = "com.apple.product-type.framework"; 416 | }; 417 | D09C73FC19DDC8510067EB29 /* Archimedes-iOSTests */ = { 418 | isa = PBXNativeTarget; 419 | buildConfigurationList = D09C740B19DDC8510067EB29 /* Build configuration list for PBXNativeTarget "Archimedes-iOSTests" */; 420 | buildPhases = ( 421 | D09C73F919DDC8510067EB29 /* Sources */, 422 | D09C73FA19DDC8510067EB29 /* Frameworks */, 423 | D09C73FB19DDC8510067EB29 /* Resources */, 424 | D4D8B7FE19DEF0DB0043808D /* Copy Frameworks */, 425 | ); 426 | buildRules = ( 427 | ); 428 | dependencies = ( 429 | D09C740019DDC8510067EB29 /* PBXTargetDependency */, 430 | ); 431 | name = "Archimedes-iOSTests"; 432 | productName = ArchimedesTests; 433 | productReference = D09C73FD19DDC8510067EB29 /* Archimedes-iOSTests.xctest */; 434 | productType = "com.apple.product-type.bundle.unit-test"; 435 | }; 436 | /* End PBXNativeTarget section */ 437 | 438 | /* Begin PBXProject section */ 439 | D02FAED01635DDC0008D42D9 /* Project object */ = { 440 | isa = PBXProject; 441 | attributes = { 442 | LastTestingUpgradeCheck = 0510; 443 | LastUpgradeCheck = 0700; 444 | ORGANIZATIONNAME = GitHub; 445 | TargetAttributes = { 446 | D038E05A19DDC7A200ABCE67 = { 447 | CreatedOnToolsVersion = 6.1; 448 | }; 449 | D038E06419DDC7A200ABCE67 = { 450 | CreatedOnToolsVersion = 6.1; 451 | }; 452 | D09C73F219DDC8500067EB29 = { 453 | CreatedOnToolsVersion = 6.1; 454 | }; 455 | D09C73FC19DDC8510067EB29 = { 456 | CreatedOnToolsVersion = 6.1; 457 | }; 458 | }; 459 | }; 460 | buildConfigurationList = D02FAED31635DDC0008D42D9 /* Build configuration list for PBXProject "Archimedes" */; 461 | compatibilityVersion = "Xcode 3.2"; 462 | developmentRegion = English; 463 | hasScannedForEncodings = 0; 464 | knownRegions = ( 465 | en, 466 | ); 467 | mainGroup = D02FAECE1635DDC0008D42D9; 468 | productRefGroup = D02FAEDA1635DDC0008D42D9 /* Products */; 469 | projectDirPath = ""; 470 | projectRoot = ""; 471 | targets = ( 472 | D038E05A19DDC7A200ABCE67 /* Archimedes-Mac */, 473 | D038E06419DDC7A200ABCE67 /* Archimedes-MacTests */, 474 | D09C73F219DDC8500067EB29 /* Archimedes-iOS */, 475 | D09C73FC19DDC8510067EB29 /* Archimedes-iOSTests */, 476 | ); 477 | }; 478 | /* End PBXProject section */ 479 | 480 | /* Begin PBXResourcesBuildPhase section */ 481 | D038E05919DDC7A200ABCE67 /* Resources */ = { 482 | isa = PBXResourcesBuildPhase; 483 | buildActionMask = 2147483647; 484 | files = ( 485 | ); 486 | runOnlyForDeploymentPostprocessing = 0; 487 | }; 488 | D038E06319DDC7A200ABCE67 /* Resources */ = { 489 | isa = PBXResourcesBuildPhase; 490 | buildActionMask = 2147483647; 491 | files = ( 492 | ); 493 | runOnlyForDeploymentPostprocessing = 0; 494 | }; 495 | D09C73F119DDC8500067EB29 /* Resources */ = { 496 | isa = PBXResourcesBuildPhase; 497 | buildActionMask = 2147483647; 498 | files = ( 499 | ); 500 | runOnlyForDeploymentPostprocessing = 0; 501 | }; 502 | D09C73FB19DDC8510067EB29 /* Resources */ = { 503 | isa = PBXResourcesBuildPhase; 504 | buildActionMask = 2147483647; 505 | files = ( 506 | ); 507 | runOnlyForDeploymentPostprocessing = 0; 508 | }; 509 | /* End PBXResourcesBuildPhase section */ 510 | 511 | /* Begin PBXSourcesBuildPhase section */ 512 | D038E05619DDC7A200ABCE67 /* Sources */ = { 513 | isa = PBXSourcesBuildPhase; 514 | buildActionMask = 2147483647; 515 | files = ( 516 | D09C741519DDC9CA0067EB29 /* MEDEdgeInsets.m in Sources */, 517 | D09C741119DDC9CA0067EB29 /* CGGeometry+MEDConvenienceAdditions.m in Sources */, 518 | D09C741319DDC9CA0067EB29 /* NSValue+MEDGeometryAdditions.m in Sources */, 519 | ); 520 | runOnlyForDeploymentPostprocessing = 0; 521 | }; 522 | D038E06119DDC7A200ABCE67 /* Sources */ = { 523 | isa = PBXSourcesBuildPhase; 524 | buildActionMask = 2147483647; 525 | files = ( 526 | D09C742219DDC9DC0067EB29 /* MEDNSValueAdditionsSpec.m in Sources */, 527 | D09C742319DDC9DC0067EB29 /* MEDEdgeInsetsSpec.m in Sources */, 528 | D09C742119DDC9DC0067EB29 /* MEDCGGeometryAdditionsSpec.m in Sources */, 529 | D09C742419DDC9DC0067EB29 /* MEDGeometryTestObject.m in Sources */, 530 | D0BB439619DDD7B400A8243F /* SwiftSpec.swift in Sources */, 531 | ); 532 | runOnlyForDeploymentPostprocessing = 0; 533 | }; 534 | D09C73EE19DDC8500067EB29 /* Sources */ = { 535 | isa = PBXSourcesBuildPhase; 536 | buildActionMask = 2147483647; 537 | files = ( 538 | D09C741B19DDC9CB0067EB29 /* MEDEdgeInsets.m in Sources */, 539 | D09C741719DDC9CB0067EB29 /* CGGeometry+MEDConvenienceAdditions.m in Sources */, 540 | D09C741919DDC9CB0067EB29 /* NSValue+MEDGeometryAdditions.m in Sources */, 541 | ); 542 | runOnlyForDeploymentPostprocessing = 0; 543 | }; 544 | D09C73F919DDC8510067EB29 /* Sources */ = { 545 | isa = PBXSourcesBuildPhase; 546 | buildActionMask = 2147483647; 547 | files = ( 548 | D09C742619DDC9DD0067EB29 /* MEDNSValueAdditionsSpec.m in Sources */, 549 | D09C742719DDC9DD0067EB29 /* MEDEdgeInsetsSpec.m in Sources */, 550 | D09C742519DDC9DD0067EB29 /* MEDCGGeometryAdditionsSpec.m in Sources */, 551 | D09C742819DDC9DD0067EB29 /* MEDGeometryTestObject.m in Sources */, 552 | D0BB439719DDD7B400A8243F /* SwiftSpec.swift in Sources */, 553 | ); 554 | runOnlyForDeploymentPostprocessing = 0; 555 | }; 556 | /* End PBXSourcesBuildPhase section */ 557 | 558 | /* Begin PBXTargetDependency section */ 559 | D038E06819DDC7A300ABCE67 /* PBXTargetDependency */ = { 560 | isa = PBXTargetDependency; 561 | target = D038E05A19DDC7A200ABCE67 /* Archimedes-Mac */; 562 | targetProxy = D038E06719DDC7A300ABCE67 /* PBXContainerItemProxy */; 563 | }; 564 | D09C740019DDC8510067EB29 /* PBXTargetDependency */ = { 565 | isa = PBXTargetDependency; 566 | target = D09C73F219DDC8500067EB29 /* Archimedes-iOS */; 567 | targetProxy = D09C73FF19DDC8510067EB29 /* PBXContainerItemProxy */; 568 | }; 569 | /* End PBXTargetDependency section */ 570 | 571 | /* Begin PBXVariantGroup section */ 572 | D02FAEF71635DDC0008D42D9 /* InfoPlist.strings */ = { 573 | isa = PBXVariantGroup; 574 | children = ( 575 | D02FAEF81635DDC0008D42D9 /* en */, 576 | ); 577 | name = InfoPlist.strings; 578 | sourceTree = ""; 579 | }; 580 | /* End PBXVariantGroup section */ 581 | 582 | /* Begin XCBuildConfiguration section */ 583 | D02FAEFD1635DDC1008D42D9 /* Debug */ = { 584 | isa = XCBuildConfiguration; 585 | baseConfigurationReference = D038E04219DDC74A00ABCE67 /* Debug.xcconfig */; 586 | buildSettings = { 587 | ENABLE_TESTABILITY = YES; 588 | GCC_NO_COMMON_BLOCKS = YES; 589 | IPHONEOS_DEPLOYMENT_TARGET = 8.0; 590 | MACOSX_DEPLOYMENT_TARGET = 10.8; 591 | ONLY_ACTIVE_ARCH = YES; 592 | TARGETED_DEVICE_FAMILY = "1,2"; 593 | }; 594 | name = Debug; 595 | }; 596 | D02FAEFE1635DDC1008D42D9 /* Release */ = { 597 | isa = XCBuildConfiguration; 598 | baseConfigurationReference = D038E04419DDC74A00ABCE67 /* Release.xcconfig */; 599 | buildSettings = { 600 | GCC_NO_COMMON_BLOCKS = YES; 601 | IPHONEOS_DEPLOYMENT_TARGET = 8.0; 602 | MACOSX_DEPLOYMENT_TARGET = 10.8; 603 | TARGETED_DEVICE_FAMILY = "1,2"; 604 | }; 605 | name = Release; 606 | }; 607 | D02FAFCE1635E0C3008D42D9 /* Profile */ = { 608 | isa = XCBuildConfiguration; 609 | baseConfigurationReference = D038E04319DDC74A00ABCE67 /* Profile.xcconfig */; 610 | buildSettings = { 611 | GCC_NO_COMMON_BLOCKS = YES; 612 | IPHONEOS_DEPLOYMENT_TARGET = 8.0; 613 | MACOSX_DEPLOYMENT_TARGET = 10.8; 614 | TARGETED_DEVICE_FAMILY = "1,2"; 615 | }; 616 | name = Profile; 617 | }; 618 | D038E06F19DDC7A300ABCE67 /* Debug */ = { 619 | isa = XCBuildConfiguration; 620 | baseConfigurationReference = D038E05319DDC74A00ABCE67 /* Mac-Framework.xcconfig */; 621 | buildSettings = { 622 | CURRENT_PROJECT_VERSION = 1; 623 | DYLIB_COMPATIBILITY_VERSION = 1; 624 | DYLIB_CURRENT_VERSION = 1; 625 | FRAMEWORK_VERSION = A; 626 | INFOPLIST_FILE = Archimedes/Info.plist; 627 | VERSIONING_SYSTEM = "apple-generic"; 628 | VERSION_INFO_PREFIX = ""; 629 | }; 630 | name = Debug; 631 | }; 632 | D038E07019DDC7A300ABCE67 /* Test */ = { 633 | isa = XCBuildConfiguration; 634 | baseConfigurationReference = D038E05319DDC74A00ABCE67 /* Mac-Framework.xcconfig */; 635 | buildSettings = { 636 | CURRENT_PROJECT_VERSION = 1; 637 | DYLIB_COMPATIBILITY_VERSION = 1; 638 | DYLIB_CURRENT_VERSION = 1; 639 | FRAMEWORK_VERSION = A; 640 | INFOPLIST_FILE = Archimedes/Info.plist; 641 | VERSIONING_SYSTEM = "apple-generic"; 642 | VERSION_INFO_PREFIX = ""; 643 | }; 644 | name = Test; 645 | }; 646 | D038E07119DDC7A300ABCE67 /* Release */ = { 647 | isa = XCBuildConfiguration; 648 | baseConfigurationReference = D038E05319DDC74A00ABCE67 /* Mac-Framework.xcconfig */; 649 | buildSettings = { 650 | CURRENT_PROJECT_VERSION = 1; 651 | DYLIB_COMPATIBILITY_VERSION = 1; 652 | DYLIB_CURRENT_VERSION = 1; 653 | FRAMEWORK_VERSION = A; 654 | INFOPLIST_FILE = Archimedes/Info.plist; 655 | VERSIONING_SYSTEM = "apple-generic"; 656 | VERSION_INFO_PREFIX = ""; 657 | }; 658 | name = Release; 659 | }; 660 | D038E07219DDC7A300ABCE67 /* Profile */ = { 661 | isa = XCBuildConfiguration; 662 | baseConfigurationReference = D038E05319DDC74A00ABCE67 /* Mac-Framework.xcconfig */; 663 | buildSettings = { 664 | CURRENT_PROJECT_VERSION = 1; 665 | DYLIB_COMPATIBILITY_VERSION = 1; 666 | DYLIB_CURRENT_VERSION = 1; 667 | FRAMEWORK_VERSION = A; 668 | INFOPLIST_FILE = Archimedes/Info.plist; 669 | VERSIONING_SYSTEM = "apple-generic"; 670 | VERSION_INFO_PREFIX = ""; 671 | }; 672 | name = Profile; 673 | }; 674 | D038E07419DDC7A300ABCE67 /* Debug */ = { 675 | isa = XCBuildConfiguration; 676 | baseConfigurationReference = D038E05019DDC74A00ABCE67 /* Mac-Application.xcconfig */; 677 | buildSettings = { 678 | FRAMEWORK_SEARCH_PATHS = ( 679 | "$(DEVELOPER_FRAMEWORKS_DIR)", 680 | "$(inherited)", 681 | ); 682 | INFOPLIST_FILE = ArchimedesTests/Info.plist; 683 | MACOSX_DEPLOYMENT_TARGET = 10.9; 684 | PRODUCT_NAME = "$(TARGET_NAME)"; 685 | }; 686 | name = Debug; 687 | }; 688 | D038E07519DDC7A300ABCE67 /* Test */ = { 689 | isa = XCBuildConfiguration; 690 | baseConfigurationReference = D038E05019DDC74A00ABCE67 /* Mac-Application.xcconfig */; 691 | buildSettings = { 692 | FRAMEWORK_SEARCH_PATHS = ( 693 | "$(DEVELOPER_FRAMEWORKS_DIR)", 694 | "$(inherited)", 695 | ); 696 | INFOPLIST_FILE = ArchimedesTests/Info.plist; 697 | MACOSX_DEPLOYMENT_TARGET = 10.9; 698 | PRODUCT_NAME = "$(TARGET_NAME)"; 699 | }; 700 | name = Test; 701 | }; 702 | D038E07619DDC7A300ABCE67 /* Release */ = { 703 | isa = XCBuildConfiguration; 704 | baseConfigurationReference = D038E05019DDC74A00ABCE67 /* Mac-Application.xcconfig */; 705 | buildSettings = { 706 | FRAMEWORK_SEARCH_PATHS = ( 707 | "$(DEVELOPER_FRAMEWORKS_DIR)", 708 | "$(inherited)", 709 | ); 710 | INFOPLIST_FILE = ArchimedesTests/Info.plist; 711 | MACOSX_DEPLOYMENT_TARGET = 10.9; 712 | PRODUCT_NAME = "$(TARGET_NAME)"; 713 | }; 714 | name = Release; 715 | }; 716 | D038E07719DDC7A300ABCE67 /* Profile */ = { 717 | isa = XCBuildConfiguration; 718 | baseConfigurationReference = D038E05019DDC74A00ABCE67 /* Mac-Application.xcconfig */; 719 | buildSettings = { 720 | FRAMEWORK_SEARCH_PATHS = ( 721 | "$(DEVELOPER_FRAMEWORKS_DIR)", 722 | "$(inherited)", 723 | ); 724 | INFOPLIST_FILE = ArchimedesTests/Info.plist; 725 | MACOSX_DEPLOYMENT_TARGET = 10.9; 726 | PRODUCT_NAME = "$(TARGET_NAME)"; 727 | }; 728 | name = Profile; 729 | }; 730 | D09C740719DDC8510067EB29 /* Debug */ = { 731 | isa = XCBuildConfiguration; 732 | baseConfigurationReference = D038E04D19DDC74A00ABCE67 /* iOS-Framework.xcconfig */; 733 | buildSettings = { 734 | "CODE_SIGN_IDENTITY[sdk=iphoneos*]" = "iPhone Developer"; 735 | CURRENT_PROJECT_VERSION = 1; 736 | DYLIB_COMPATIBILITY_VERSION = 1; 737 | DYLIB_CURRENT_VERSION = 1; 738 | INFOPLIST_FILE = Archimedes/Info.plist; 739 | VERSIONING_SYSTEM = "apple-generic"; 740 | VERSION_INFO_PREFIX = ""; 741 | }; 742 | name = Debug; 743 | }; 744 | D09C740819DDC8510067EB29 /* Test */ = { 745 | isa = XCBuildConfiguration; 746 | baseConfigurationReference = D038E04D19DDC74A00ABCE67 /* iOS-Framework.xcconfig */; 747 | buildSettings = { 748 | "CODE_SIGN_IDENTITY[sdk=iphoneos*]" = "iPhone Developer"; 749 | CURRENT_PROJECT_VERSION = 1; 750 | DYLIB_COMPATIBILITY_VERSION = 1; 751 | DYLIB_CURRENT_VERSION = 1; 752 | INFOPLIST_FILE = Archimedes/Info.plist; 753 | VERSIONING_SYSTEM = "apple-generic"; 754 | VERSION_INFO_PREFIX = ""; 755 | }; 756 | name = Test; 757 | }; 758 | D09C740919DDC8510067EB29 /* Release */ = { 759 | isa = XCBuildConfiguration; 760 | baseConfigurationReference = D038E04D19DDC74A00ABCE67 /* iOS-Framework.xcconfig */; 761 | buildSettings = { 762 | "CODE_SIGN_IDENTITY[sdk=iphoneos*]" = "iPhone Developer"; 763 | CURRENT_PROJECT_VERSION = 1; 764 | DYLIB_COMPATIBILITY_VERSION = 1; 765 | DYLIB_CURRENT_VERSION = 1; 766 | INFOPLIST_FILE = Archimedes/Info.plist; 767 | VERSIONING_SYSTEM = "apple-generic"; 768 | VERSION_INFO_PREFIX = ""; 769 | }; 770 | name = Release; 771 | }; 772 | D09C740A19DDC8510067EB29 /* Profile */ = { 773 | isa = XCBuildConfiguration; 774 | baseConfigurationReference = D038E04D19DDC74A00ABCE67 /* iOS-Framework.xcconfig */; 775 | buildSettings = { 776 | "CODE_SIGN_IDENTITY[sdk=iphoneos*]" = "iPhone Developer"; 777 | CURRENT_PROJECT_VERSION = 1; 778 | DYLIB_COMPATIBILITY_VERSION = 1; 779 | DYLIB_CURRENT_VERSION = 1; 780 | INFOPLIST_FILE = Archimedes/Info.plist; 781 | VERSIONING_SYSTEM = "apple-generic"; 782 | VERSION_INFO_PREFIX = ""; 783 | }; 784 | name = Profile; 785 | }; 786 | D09C740C19DDC8510067EB29 /* Debug */ = { 787 | isa = XCBuildConfiguration; 788 | baseConfigurationReference = D038E04B19DDC74A00ABCE67 /* iOS-Application.xcconfig */; 789 | buildSettings = { 790 | FRAMEWORK_SEARCH_PATHS = "$(DEVELOPER_DIR)/Platforms/iPhoneSimulator.platform/Developer/Library/Frameworks"; 791 | INFOPLIST_FILE = ArchimedesTests/Info.plist; 792 | PRODUCT_NAME = "$(TARGET_NAME)"; 793 | }; 794 | name = Debug; 795 | }; 796 | D09C740D19DDC8510067EB29 /* Test */ = { 797 | isa = XCBuildConfiguration; 798 | baseConfigurationReference = D038E04B19DDC74A00ABCE67 /* iOS-Application.xcconfig */; 799 | buildSettings = { 800 | FRAMEWORK_SEARCH_PATHS = "$(DEVELOPER_DIR)/Platforms/iPhoneSimulator.platform/Developer/Library/Frameworks"; 801 | INFOPLIST_FILE = ArchimedesTests/Info.plist; 802 | PRODUCT_NAME = "$(TARGET_NAME)"; 803 | }; 804 | name = Test; 805 | }; 806 | D09C740E19DDC8510067EB29 /* Release */ = { 807 | isa = XCBuildConfiguration; 808 | baseConfigurationReference = D038E04B19DDC74A00ABCE67 /* iOS-Application.xcconfig */; 809 | buildSettings = { 810 | FRAMEWORK_SEARCH_PATHS = "$(DEVELOPER_DIR)/Platforms/iPhoneSimulator.platform/Developer/Library/Frameworks"; 811 | INFOPLIST_FILE = ArchimedesTests/Info.plist; 812 | PRODUCT_NAME = "$(TARGET_NAME)"; 813 | }; 814 | name = Release; 815 | }; 816 | D09C740F19DDC8510067EB29 /* Profile */ = { 817 | isa = XCBuildConfiguration; 818 | baseConfigurationReference = D038E04B19DDC74A00ABCE67 /* iOS-Application.xcconfig */; 819 | buildSettings = { 820 | FRAMEWORK_SEARCH_PATHS = "$(DEVELOPER_DIR)/Platforms/iPhoneSimulator.platform/Developer/Library/Frameworks"; 821 | INFOPLIST_FILE = ArchimedesTests/Info.plist; 822 | PRODUCT_NAME = "$(TARGET_NAME)"; 823 | }; 824 | name = Profile; 825 | }; 826 | D499F09D18E0D4E600AA91F9 /* Test */ = { 827 | isa = XCBuildConfiguration; 828 | baseConfigurationReference = D038E04519DDC74A00ABCE67 /* Test.xcconfig */; 829 | buildSettings = { 830 | GCC_NO_COMMON_BLOCKS = YES; 831 | IPHONEOS_DEPLOYMENT_TARGET = 8.0; 832 | MACOSX_DEPLOYMENT_TARGET = 10.8; 833 | TARGETED_DEVICE_FAMILY = "1,2"; 834 | }; 835 | name = Test; 836 | }; 837 | /* End XCBuildConfiguration section */ 838 | 839 | /* Begin XCConfigurationList section */ 840 | D02FAED31635DDC0008D42D9 /* Build configuration list for PBXProject "Archimedes" */ = { 841 | isa = XCConfigurationList; 842 | buildConfigurations = ( 843 | D02FAEFD1635DDC1008D42D9 /* Debug */, 844 | D499F09D18E0D4E600AA91F9 /* Test */, 845 | D02FAEFE1635DDC1008D42D9 /* Release */, 846 | D02FAFCE1635E0C3008D42D9 /* Profile */, 847 | ); 848 | defaultConfigurationIsVisible = 0; 849 | defaultConfigurationName = Release; 850 | }; 851 | D038E06E19DDC7A300ABCE67 /* Build configuration list for PBXNativeTarget "Archimedes-Mac" */ = { 852 | isa = XCConfigurationList; 853 | buildConfigurations = ( 854 | D038E06F19DDC7A300ABCE67 /* Debug */, 855 | D038E07019DDC7A300ABCE67 /* Test */, 856 | D038E07119DDC7A300ABCE67 /* Release */, 857 | D038E07219DDC7A300ABCE67 /* Profile */, 858 | ); 859 | defaultConfigurationIsVisible = 0; 860 | defaultConfigurationName = Release; 861 | }; 862 | D038E07319DDC7A300ABCE67 /* Build configuration list for PBXNativeTarget "Archimedes-MacTests" */ = { 863 | isa = XCConfigurationList; 864 | buildConfigurations = ( 865 | D038E07419DDC7A300ABCE67 /* Debug */, 866 | D038E07519DDC7A300ABCE67 /* Test */, 867 | D038E07619DDC7A300ABCE67 /* Release */, 868 | D038E07719DDC7A300ABCE67 /* Profile */, 869 | ); 870 | defaultConfigurationIsVisible = 0; 871 | defaultConfigurationName = Release; 872 | }; 873 | D09C740619DDC8510067EB29 /* Build configuration list for PBXNativeTarget "Archimedes-iOS" */ = { 874 | isa = XCConfigurationList; 875 | buildConfigurations = ( 876 | D09C740719DDC8510067EB29 /* Debug */, 877 | D09C740819DDC8510067EB29 /* Test */, 878 | D09C740919DDC8510067EB29 /* Release */, 879 | D09C740A19DDC8510067EB29 /* Profile */, 880 | ); 881 | defaultConfigurationIsVisible = 0; 882 | defaultConfigurationName = Release; 883 | }; 884 | D09C740B19DDC8510067EB29 /* Build configuration list for PBXNativeTarget "Archimedes-iOSTests" */ = { 885 | isa = XCConfigurationList; 886 | buildConfigurations = ( 887 | D09C740C19DDC8510067EB29 /* Debug */, 888 | D09C740D19DDC8510067EB29 /* Test */, 889 | D09C740E19DDC8510067EB29 /* Release */, 890 | D09C740F19DDC8510067EB29 /* Profile */, 891 | ); 892 | defaultConfigurationIsVisible = 0; 893 | defaultConfigurationName = Release; 894 | }; 895 | /* End XCConfigurationList section */ 896 | }; 897 | rootObject = D02FAED01635DDC0008D42D9 /* Project object */; 898 | } 899 | --------------------------------------------------------------------------------