├── .gitignore ├── LICENSE ├── README.md └── Source ├── .swiftlint.yml ├── Documentation ├── features.md ├── history.md └── triangledraw_screenshots.png ├── Podfile ├── Podfile.lock ├── Pods ├── Local Podspecs │ ├── MBProgressHUD.podspec.json │ └── SwiftyBeaver.podspec.json ├── MBProgressHUD │ ├── LICENSE │ ├── MBProgressHUD.h │ ├── MBProgressHUD.m │ └── README.mdown ├── Manifest.lock ├── Pods.xcodeproj │ └── project.pbxproj ├── SwiftyBeaver │ ├── LICENSE │ ├── README.md │ └── Sources │ │ ├── AES256CBC.swift │ │ ├── Base64.swift │ │ ├── BaseDestination.swift │ │ ├── ConsoleDestination.swift │ │ ├── Extensions.swift │ │ ├── FileDestination.swift │ │ ├── Filter.swift │ │ ├── FilterValidator.swift │ │ ├── GoogleCloudDestination.swift │ │ ├── SBPlatformDestination.swift │ │ └── SwiftyBeaver.swift └── Target Support Files │ ├── MBProgressHUD │ ├── MBProgressHUD-Info.plist │ ├── MBProgressHUD-dummy.m │ ├── MBProgressHUD-prefix.pch │ ├── MBProgressHUD-umbrella.h │ ├── MBProgressHUD.debug.xcconfig │ ├── MBProgressHUD.modulemap │ ├── MBProgressHUD.release.xcconfig │ └── MBProgressHUD.xcconfig │ ├── Pods-BasePods-Tests │ ├── Pods-BasePods-Tests-Info.plist │ ├── Pods-BasePods-Tests-acknowledgements.markdown │ ├── Pods-BasePods-Tests-acknowledgements.plist │ ├── Pods-BasePods-Tests-dummy.m │ ├── Pods-BasePods-Tests-frameworks-Debug-input-files.xcfilelist │ ├── Pods-BasePods-Tests-frameworks-Debug-output-files.xcfilelist │ ├── Pods-BasePods-Tests-frameworks-Release-input-files.xcfilelist │ ├── Pods-BasePods-Tests-frameworks-Release-output-files.xcfilelist │ ├── Pods-BasePods-Tests-frameworks.sh │ ├── Pods-BasePods-Tests-umbrella.h │ ├── Pods-BasePods-Tests.debug.xcconfig │ ├── Pods-BasePods-Tests.modulemap │ └── Pods-BasePods-Tests.release.xcconfig │ ├── Pods-BasePods-TriangleDrawLibrary │ ├── Pods-BasePods-TriangleDrawLibrary-Info.plist │ ├── Pods-BasePods-TriangleDrawLibrary-acknowledgements.markdown │ ├── Pods-BasePods-TriangleDrawLibrary-acknowledgements.plist │ ├── Pods-BasePods-TriangleDrawLibrary-dummy.m │ ├── Pods-BasePods-TriangleDrawLibrary-umbrella.h │ ├── Pods-BasePods-TriangleDrawLibrary.debug.xcconfig │ ├── Pods-BasePods-TriangleDrawLibrary.modulemap │ └── Pods-BasePods-TriangleDrawLibrary.release.xcconfig │ ├── Pods-BasePods-TriangleDrawMain │ ├── Pods-BasePods-TriangleDrawMain-Info.plist │ ├── Pods-BasePods-TriangleDrawMain-acknowledgements.markdown │ ├── Pods-BasePods-TriangleDrawMain-acknowledgements.plist │ ├── Pods-BasePods-TriangleDrawMain-dummy.m │ ├── Pods-BasePods-TriangleDrawMain-frameworks-Debug-input-files.xcfilelist │ ├── Pods-BasePods-TriangleDrawMain-frameworks-Debug-output-files.xcfilelist │ ├── Pods-BasePods-TriangleDrawMain-frameworks-Release-input-files.xcfilelist │ ├── Pods-BasePods-TriangleDrawMain-frameworks-Release-output-files.xcfilelist │ ├── Pods-BasePods-TriangleDrawMain-frameworks.sh │ ├── Pods-BasePods-TriangleDrawMain-umbrella.h │ ├── Pods-BasePods-TriangleDrawMain.debug.xcconfig │ ├── Pods-BasePods-TriangleDrawMain.modulemap │ └── Pods-BasePods-TriangleDrawMain.release.xcconfig │ ├── Pods-BasePods-TriangleDrawThumbnail │ ├── Pods-BasePods-TriangleDrawThumbnail-Info.plist │ ├── Pods-BasePods-TriangleDrawThumbnail-acknowledgements.markdown │ ├── Pods-BasePods-TriangleDrawThumbnail-acknowledgements.plist │ ├── Pods-BasePods-TriangleDrawThumbnail-dummy.m │ ├── Pods-BasePods-TriangleDrawThumbnail-umbrella.h │ ├── Pods-BasePods-TriangleDrawThumbnail.debug.xcconfig │ ├── Pods-BasePods-TriangleDrawThumbnail.modulemap │ └── Pods-BasePods-TriangleDrawThumbnail.release.xcconfig │ └── SwiftyBeaver │ ├── SwiftyBeaver-Info.plist │ ├── SwiftyBeaver-dummy.m │ ├── SwiftyBeaver-prefix.pch │ ├── SwiftyBeaver-umbrella.h │ ├── SwiftyBeaver.debug.xcconfig │ ├── SwiftyBeaver.modulemap │ ├── SwiftyBeaver.release.xcconfig │ └── SwiftyBeaver.xcconfig ├── TriangleDraw.xcodeproj ├── project.pbxproj ├── project.xcworkspace │ └── contents.xcworkspacedata └── xcshareddata │ └── xcschemes │ └── TriangleDraw.xcscheme ├── TriangleDraw.xcworkspace ├── contents.xcworkspacedata └── xcshareddata │ ├── IDEWorkspaceChecks.plist │ ├── WorkspaceSettings.xcsettings │ └── swiftpm │ └── Package.resolved ├── TriangleDrawLibrary ├── Core │ ├── AppConstant.swift │ ├── Logging.swift │ ├── OSLogDestination.swift │ ├── TriangleDrawFrameworkMeta.swift │ ├── UserDefaults+AppGroup.swift │ └── VerboseInfoProvider.swift ├── Engine │ ├── CGFillTriangle.swift │ ├── CGSize+OptimalTileCount.swift │ ├── Document.swift │ ├── E2Canvas+Coordinates.swift │ ├── E2Canvas+CountDifferencies.swift │ ├── E2Canvas+Equatable.swift │ ├── E2Canvas+Flip.swift │ ├── E2Canvas+GameOfLife.swift │ ├── E2Canvas+GetPixel.swift │ ├── E2Canvas+Histogram.swift │ ├── E2Canvas+Line.swift │ ├── E2Canvas+Move.swift │ ├── E2Canvas+Rotate.swift │ ├── E2Canvas+SetPixel.swift │ ├── E2Canvas+SetSymmetricPixel.swift │ ├── E2Canvas+StringRepresentation.swift │ ├── E2Canvas+Subdivide.swift │ ├── E2Canvas+Triangles.swift │ ├── E2Canvas.swift │ ├── E2CanvasBoundingBox.swift │ ├── E2CanvasPoint+Orientation.swift │ ├── E2CanvasPoint.swift │ ├── E2CanvasSize.swift │ ├── E2CanvasTriangle.swift │ ├── E2Combiner.swift │ ├── E2TagPair.swift │ ├── E2TriangleCell.swift │ ├── TDRenderBitmap.swift │ ├── UIColor+Image.swift │ ├── UIImage+ScaleToSize.swift │ └── URL+DisplayName.swift ├── Foundation │ ├── CGPoint.swift │ ├── Date+iso8601.swift │ ├── String+Trim.swift │ └── TDFloat.swift ├── LiveIndicator │ └── TDLiveIndicator.swift ├── ParsePBM │ └── TDParsePBM.swift ├── ReadWrite │ ├── TDCanvasReader.swift │ └── TDCanvasWriter.swift ├── TriangleDrawLibrary.swift ├── UIKit │ └── UIDocument+HumanReadable.swift └── math │ ├── Clamp.swift │ ├── FloatFormatting.swift │ ├── IntVec2.swift │ └── Remap.swift ├── TriangleDrawMain ├── Browser │ ├── BrowserMenuView.swift │ ├── BrowserMenuViewController.swift │ ├── BrowserMenuViewModel.swift │ ├── BrowserViewController+ImportDocumentExamples.swift │ ├── BrowserViewController+PresentDocument.swift │ ├── BrowserViewController.storyboard │ ├── BrowserViewController.swift │ ├── DocumentNameGenerator.swift │ ├── MailButtonView.swift │ └── MailView.swift ├── Canvas │ ├── AAPLMathUtilities.h │ ├── AAPLMathUtilities.m │ ├── Assets │ │ ├── da.lproj │ │ │ └── CanvasVC.strings │ │ ├── de.lproj │ │ │ └── CanvasVC.strings │ │ ├── en.lproj │ │ │ └── CanvasVC.strings │ │ ├── es.lproj │ │ │ └── CanvasVC.strings │ │ ├── fr.lproj │ │ │ └── CanvasVC.strings │ │ ├── ja.lproj │ │ │ └── CanvasVC.strings │ │ ├── pt_PT.lproj │ │ │ └── CanvasVC.strings │ │ ├── ru.lproj │ │ │ └── CanvasVC.strings │ │ └── zh_CN.lproj │ │ │ └── CanvasVC.strings │ ├── CanvasNavigationController.swift │ ├── CanvasViewController+ConfigureHCView.swift │ ├── CanvasViewController+ConfigureLeaveFullscreenButton.swift │ ├── CanvasViewController+ConfigureNavigationBar.swift │ ├── CanvasViewController+ConfigureToolbar.swift │ ├── CanvasViewController+Operations.swift │ ├── CanvasViewController.storyboard │ ├── CanvasViewController.swift │ ├── HCBuildEdgeAroundHexagon.swift │ ├── HCBuildHexagonCanvas.swift │ ├── HCFilledCircle.metal │ ├── HCFilledTriangle.metal │ ├── HCGridView.swift │ ├── HCHexagonCorners.swift │ ├── HCInteractionView.swift │ ├── HCMetalView+Interaction.swift │ ├── HCMetalView.swift │ ├── HCRenderer.swift │ ├── HCSafeAreaView.swift │ ├── HCToolbar.swift │ ├── HCView.swift │ ├── HCZoomToFit.swift │ ├── Menu │ │ ├── CanvasGridMode.swift │ │ ├── HCMenuSubdivideView.swift │ │ ├── HCMenuView.swift │ │ ├── HCMenuViewController+SharePDF.swift │ │ ├── HCMenuViewController+SharePNG.swift │ │ ├── HCMenuViewController+ShareSVG.swift │ │ ├── HCMenuViewController.swift │ │ └── HCMenuViewModel.swift │ └── TDCanvasDrawingProtocol.swift ├── Export │ ├── PDFExporter.swift │ └── SVGExporter.swift ├── External │ └── gpc232-release │ │ ├── GPC-README.pdf │ │ ├── VERSIONS.TXT │ │ ├── gpc.c │ │ └── gpc.h ├── Main │ ├── AppDelegate.swift │ ├── DocumentExample.swift │ ├── EmailWithFeedback.swift │ ├── Image.swift │ ├── Platform.swift │ ├── SystemInfo.swift │ ├── TriangleDrawMain-Bridging-Header.h │ ├── UIApplication+Directories.swift │ └── UserDefaults+RunCount.swift ├── Resources │ ├── DocumentExample.bundle │ │ ├── Drawing.triangleDraw │ │ ├── Spiral.triangleDraw │ │ ├── bird.triangleDraw │ │ ├── developer_columns.triangleDraw │ │ ├── developer_rows.triangleDraw │ │ ├── hat.triangleDraw │ │ ├── hello.triangleDraw │ │ ├── illuminati.triangleDraw │ │ ├── impossible.triangleDraw │ │ ├── injection.triangleDraw │ │ ├── rex.triangleDraw │ │ ├── rune 1.triangleDraw │ │ ├── rune 2.triangleDraw │ │ ├── rune 3.triangleDraw │ │ ├── sierpinski.triangleDraw │ │ ├── star.triangleDraw │ │ ├── stay home.triangleDraw │ │ ├── symmetry glitch 1.triangleDraw │ │ ├── symmetry glitch 2.triangleDraw │ │ ├── symmetry glitch 3.triangleDraw │ │ └── triangledraw logo.triangleDraw │ ├── Images.xcassets │ │ ├── AppIcon.appiconset │ │ │ ├── Contents.json │ │ │ ├── Icon.png │ │ │ ├── icon_20pt.png │ │ │ ├── icon_20pt@2x-1.png │ │ │ ├── icon_20pt@2x.png │ │ │ ├── icon_20pt@3x.png │ │ │ ├── icon_29pt.png │ │ │ ├── icon_29pt@2x-1.png │ │ │ ├── icon_29pt@2x.png │ │ │ ├── icon_29pt@3x.png │ │ │ ├── icon_40pt.png │ │ │ ├── icon_40pt@2x-1.png │ │ │ ├── icon_40pt@2x.png │ │ │ ├── icon_40pt@3x.png │ │ │ ├── icon_60pt@2x.png │ │ │ ├── icon_60pt@3x.png │ │ │ ├── icon_76pt.png │ │ │ ├── icon_76pt@2x.png │ │ │ └── icon_83.5@2x.png │ │ ├── Browser │ │ │ ├── Contents.json │ │ │ └── browser_gear.imageset │ │ │ │ ├── Contents.json │ │ │ │ ├── browser_gear@2x.pdf │ │ │ │ └── browser_gear@3x.pdf │ │ ├── Canvas │ │ │ ├── Contents.json │ │ │ ├── canvas_enterFullscreen.imageset │ │ │ │ ├── Contents.json │ │ │ │ ├── canvas_enter_fullscreen.png │ │ │ │ ├── canvas_enter_fullscreen@2x.png │ │ │ │ └── canvas_enter_fullscreen@3x.png │ │ │ ├── canvas_flipX.imageset │ │ │ │ ├── Contents.json │ │ │ │ ├── canvas_flipX.png │ │ │ │ └── canvas_flipX@2x.png │ │ │ ├── canvas_flipY.imageset │ │ │ │ ├── Contents.json │ │ │ │ ├── canvas_flipY.png │ │ │ │ └── canvas_flipY@2x.png │ │ │ ├── canvas_moveDown.imageset │ │ │ │ ├── Contents.json │ │ │ │ ├── arrow_down.png │ │ │ │ ├── arrow_down2x.png │ │ │ │ └── arrow_down3x.png │ │ │ ├── canvas_moveLeft.imageset │ │ │ │ ├── Contents.json │ │ │ │ ├── arrow_left.png │ │ │ │ ├── arrow_left2x.png │ │ │ │ └── arrow_left3x.png │ │ │ ├── canvas_moveRight.imageset │ │ │ │ ├── Contents.json │ │ │ │ ├── arrow_right.png │ │ │ │ ├── arrow_right2x.png │ │ │ │ └── arrow_right3x.png │ │ │ ├── canvas_moveUp.imageset │ │ │ │ ├── Contents.json │ │ │ │ ├── arrow_up.png │ │ │ │ ├── arrow_up2x.png │ │ │ │ └── arrow_up3x.png │ │ │ ├── canvas_rotateCCW.imageset │ │ │ │ ├── Contents.json │ │ │ │ └── canvas_rotateCCW@2x.png │ │ │ └── canvas_rotateCW.imageset │ │ │ │ ├── Contents.json │ │ │ │ └── canvas_rotateCW@2x.png │ │ ├── Contents.json │ │ └── triangledraw_launchscreen.imageset │ │ │ ├── Contents.json │ │ │ └── triangledraw_launchscreen.pdf │ ├── Info.plist │ ├── LaunchScreen.storyboard │ ├── TriangleDrawMain.entitlements │ └── hexagon_mask.txt └── UIKit │ ├── BorderedButton.swift │ ├── CGRect+FitSizeInSize.swift │ ├── CGSize+Inset.swift │ ├── CGSize+MinMax.swift │ ├── SwiftBarButtonItem.swift │ ├── TDCalculateCubicBezier.swift │ ├── UIBarButtonItem+NegativeSpacer.swift │ ├── UIColorExtensions.swift │ ├── UIEdgeInsets+InsetsByAdding.swift │ ├── UILabel+TDAlign.swift │ ├── UINavigationItem+BarButtonItemWithTag.swift │ ├── UITextField+TDAlign.swift │ ├── UIView+CenterSubviewConstraints.swift │ ├── UIView+PinToInside.swift │ └── UIView+SuperviewEdgeConstraints.swift ├── TriangleDrawTests ├── Tests │ ├── CGPointTest.swift │ ├── CGRectFitSizeInSizeTests.swift │ ├── DocumentNameGeneratorTests.swift │ ├── E2CanvasBoundingBoxTests.swift │ ├── E2CanvasCopyTests.swift │ ├── E2CanvasCountDifferenciesTests.swift │ ├── E2CanvasFlipTests.swift │ ├── E2CanvasHistogramTests.swift │ ├── E2CanvasMoveTests.swift │ ├── E2CanvasPointOrientationTests.swift │ ├── E2CanvasRotateTests.swift │ ├── E2CanvasSubdivideTests.swift │ ├── E2CombinerTests.swift │ ├── E2TagPairTests.swift │ ├── Engine2Tests.swift │ ├── HCZoomToFitTests.swift │ ├── IntVec2Tests.swift │ ├── OptimalTileCountTests.swift │ ├── RemapTests.swift │ ├── SVGExporterTests.swift │ ├── StringTrimTests.swift │ ├── TDCanvasReadWriteTests.swift │ ├── TDLiveIndicatorTests.swift │ ├── TDParsePBMTests.swift │ ├── TestData_Engine │ │ ├── test_boundingbox0.txt │ │ ├── test_boundingbox1.txt │ │ ├── test_boundingbox10.txt │ │ ├── test_boundingbox11.txt │ │ ├── test_boundingbox12.txt │ │ ├── test_boundingbox13.txt │ │ ├── test_boundingbox2.txt │ │ ├── test_boundingbox3.txt │ │ ├── test_boundingbox4.txt │ │ ├── test_boundingbox5.txt │ │ ├── test_boundingbox6.txt │ │ ├── test_boundingbox7.txt │ │ ├── test_boundingbox8.txt │ │ ├── test_boundingbox9.txt │ │ ├── test_flipx_simple2_after.txt │ │ ├── test_flipx_simple2_before.txt │ │ ├── test_flipx_simple_after.txt │ │ ├── test_flipx_simple_before.txt │ │ ├── test_flipy_simple_after.txt │ │ ├── test_flipy_simple_before.txt │ │ ├── test_histogram0.txt │ │ ├── test_histogram1.txt │ │ ├── test_linedraw_logo_horizontal.txt │ │ ├── test_linedraw_logo_none.txt │ │ ├── test_linedraw_logo_vertical.txt │ │ ├── test_move_down_wrap1_after.txt │ │ ├── test_move_down_wrap1_before.txt │ │ ├── test_move_down_wrap2_after.txt │ │ ├── test_move_down_wrap2_before.txt │ │ ├── test_move_left_wrap0_after.txt │ │ ├── test_move_left_wrap0_before.txt │ │ ├── test_move_left_wrap1_after.txt │ │ ├── test_move_left_wrap1_before.txt │ │ ├── test_move_right_simple_after.txt │ │ ├── test_move_right_simple_before.txt │ │ ├── test_move_right_wrap0_after.txt │ │ ├── test_move_right_wrap0_before.txt │ │ ├── test_move_right_wrap1_after.txt │ │ ├── test_move_right_wrap1_before.txt │ │ ├── test_move_right_wrap2_after.txt │ │ ├── test_move_right_wrap2_before.txt │ │ ├── test_move_up_simple_after.txt │ │ ├── test_move_up_simple_before.txt │ │ ├── test_move_up_wrap0_after.txt │ │ ├── test_move_up_wrap0_before.txt │ │ ├── test_move_up_wrap1_after.txt │ │ ├── test_move_up_wrap1_before.txt │ │ ├── test_orientation_downward.pbm │ │ ├── test_orientation_upward.pbm │ │ ├── test_rotate_line2_minus60degree.txt │ │ ├── test_rotate_line2_none.txt │ │ ├── test_rotate_line_60degree.txt │ │ ├── test_rotate_line_none.txt │ │ ├── test_rotate_logo_60degree.txt │ │ ├── test_rotate_logo_none.txt │ │ ├── test_rotate_simple_60degree.txt │ │ └── test_rotate_simple_none.txt │ ├── TestData_ExportSVG │ │ ├── test_exportsvg_corners.pbm │ │ └── test_exportsvg_cube.pbm │ ├── TestData_ParsePBM │ │ ├── test_parsepbm_advanced1.pbm │ │ ├── test_parsepbm_comments3.pbm │ │ ├── test_parsepbm_illegal_cell_values.pbm │ │ ├── test_parsepbm_invalid1.pbm │ │ ├── test_parsepbm_negative_height.pbm │ │ ├── test_parsepbm_negative_width.pbm │ │ ├── test_parsepbm_simple1.pbm │ │ ├── test_parsepbm_simple2.pbm │ │ ├── test_parsepbm_spacing1.pbm │ │ ├── test_parsepbm_utf16be.pbm │ │ ├── test_parsepbm_utf16le.pbm │ │ └── test_parsepbm_utf8.pbm │ ├── TestData_ReadWrite │ │ └── test_readwrite_wrongdimensions1.pbm │ ├── TestData_Subdivide │ │ ├── test_subdivide0_in.pbm │ │ ├── test_subdivide0_out2.pbm │ │ ├── test_subdivide0_out3.pbm │ │ ├── test_subdivide0_out5.pbm │ │ ├── test_subdivide1_in.pbm │ │ ├── test_subdivide1_out2.pbm │ │ ├── test_subdivide1_out3.pbm │ │ ├── test_subdivide1_out5.pbm │ │ ├── test_subdivide2_in.pbm │ │ ├── test_subdivide2_out2.pbm │ │ ├── test_subdivide2_out3.pbm │ │ └── test_subdivide2_out5.pbm │ ├── Tests-Bridging-Header.h │ ├── Tests-Info.plist │ ├── URLDisplayNameTests.swift │ ├── XCTestCase+LoadCanvas.swift │ └── en.lproj │ │ └── InfoPlist.strings └── UITests │ ├── Info.plist │ ├── SnapshotHelper.swift │ └── UITests.swift ├── TriangleDrawThumbnail ├── Images.xcassets │ ├── Contents.json │ └── boom.imageset │ │ ├── Contents.json │ │ └── boom.png ├── Info.plist ├── ThumbnailProvider.swift ├── TriangleDrawThumbnail.entitlements └── hexagon_mask.txt └── fastlane ├── Fastfile ├── README.md ├── report.xml └── screenshots ├── en-US ├── iPad Pro (12.9-inch) (2nd generation)-0browser.png ├── iPad Pro (12.9-inch) (2nd generation)-1canvas.png ├── iPad Pro (12.9-inch) (2nd generation)-2canvas.png ├── iPad Pro (12.9-inch) (6th generation)-0browser.png ├── iPad Pro (12.9-inch) (6th generation)-1canvas.png ├── iPad Pro (12.9-inch) (6th generation)-2canvas.png ├── iPhone 14 Pro Max-0browser.png ├── iPhone 14 Pro Max-1canvas.png ├── iPhone 14 Pro Max-2canvas.png ├── iPhone 8 Plus-0browser.png ├── iPhone 8 Plus-1canvas.png ├── iPhone 8 Plus-2canvas.png ├── iPhone Xs Max-0browser.png ├── iPhone Xs Max-1canvas.png └── iPhone Xs Max-2canvas.png └── screenshots.html /.gitignore: -------------------------------------------------------------------------------- 1 | # This gitignore is based on: 2 | # https://github.com/github/gitignore/blob/master/Swift.gitignore 3 | 4 | # Mac 5 | .DS_Store 6 | 7 | ## Build generated 8 | build/ 9 | DerivedData/ 10 | 11 | ## Various settings 12 | *.pbxuser 13 | !default.pbxuser 14 | *.mode1v3 15 | !default.mode1v3 16 | *.mode2v3 17 | !default.mode2v3 18 | *.perspectivev3 19 | !default.perspectivev3 20 | xcuserdata/ 21 | 22 | ## Other 23 | *.moved-aside 24 | *.xccheckout 25 | *.xcscmblueprint 26 | 27 | ## Obj-C/Swift specific 28 | *.hmap 29 | *.ipa 30 | *.dSYM.zip 31 | *.dSYM 32 | 33 | ## Playgrounds 34 | timeline.xctimeline 35 | playground.xcworkspace 36 | 37 | # Swift Package Manager 38 | # 39 | # Add this line if you want to avoid checking in source code from Swift Package Manager dependencies. 40 | # Packages/ 41 | # Package.pins 42 | # Package.resolved 43 | .build/ 44 | 45 | # CocoaPods 46 | # 47 | # We recommend against adding the Pods directory to your .gitignore. However 48 | # you should judge for yourself, the pros and cons are mentioned at: 49 | # https://guides.cocoapods.org/using/using-cocoapods.html#should-i-check-the-pods-directory-into-source-control 50 | # 51 | # Pods/ 52 | # 53 | # Add this line if you want to avoid checking in source code from the Xcode workspace 54 | # *.xcworkspace 55 | 56 | # Carthage 57 | # 58 | # Add this line if you want to avoid checking in source code from Carthage dependencies. 59 | # Carthage/Checkouts 60 | 61 | Carthage/Build 62 | 63 | # Accio dependency management 64 | Dependencies/ 65 | .accio/ 66 | 67 | # fastlane 68 | # 69 | # It is recommended to not store the screenshots in the git repo. Instead, use fastlane to re-generate the 70 | # screenshots whenever they are needed. 71 | # For more information about the recommended setup visit: 72 | # https://docs.fastlane.tools/best-practices/source-control/#source-control 73 | 74 | # fastlane/report.xml 75 | # fastlane/Preview.html 76 | # fastlane/screenshots/**/*.png 77 | # fastlane/test_output 78 | 79 | # Code Injection 80 | # 81 | # After new code Injection tools there's a generated folder /iOSInjectionProject 82 | # https://github.com/johnno1962/injectionforxcode 83 | 84 | iOSInjectionProject/ -------------------------------------------------------------------------------- /LICENSE: -------------------------------------------------------------------------------- 1 | MIT License 2 | 3 | Copyright (c) 2020 TriangleDraw 4 | 5 | Permission is hereby granted, free of charge, to any person obtaining a copy 6 | of this software and associated documentation files (the "Software"), to deal 7 | in the Software without restriction, including without limitation the rights 8 | to use, copy, modify, merge, publish, distribute, sublicense, and/or sell 9 | copies of the Software, and to permit persons to whom the Software is 10 | furnished to do so, subject to the following conditions: 11 | 12 | The above copyright notice and this permission notice shall be included in all 13 | copies or substantial portions of the Software. 14 | 15 | THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR 16 | IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, 17 | FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE 18 | AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER 19 | LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, 20 | OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE 21 | SOFTWARE. 22 | -------------------------------------------------------------------------------- /README.md: -------------------------------------------------------------------------------- 1 |

2 | TriangleDraw screenshots 3 |

4 | 5 | --- 6 | 7 | # TriangleDraw 8 | 9 | TriangleDraw is a versatile sketching app that makes it easy to create logos and designs for branding purposes. Whether you're working on a letterhead or website, this app is a great tool for quickly putting together visually appealing designs. 10 | 11 | # Install 12 | 13 | TriangleDraw is available for iPad and iPhone. You can download it from the [App Store](https://apps.apple.com/app/id1453533043). 14 | 15 | # Inspiration 16 | 17 | To see what's possible with TriangleDraw, check out the [TriangleDraw Gallery](https://github.com/triangledraw/TriangleDraw-Gallery). Here you'll find a collection of designs created by users of the app, providing inspiration and ideas for your own creations. 18 | 19 | # Community 20 | 21 | Want to stay updated on the latest developments and share your own creations? Join the TriangleDraw community on Discord: http://triangledraw.com/discord 22 | 23 | # Contact 24 | 25 | If you have any questions or feedback, feel free to reach out to the developer, Simon Strandgaard, at [hello@triangledraw.com](mailto:hello@triangledraw.com). 26 | -------------------------------------------------------------------------------- /Source/.swiftlint.yml: -------------------------------------------------------------------------------- 1 | included: 2 | - TriangleDrawLibrary 3 | - TriangleDrawMain 4 | - TriangleDrawTests 5 | - TriangleDrawThumbnail 6 | 7 | identifier_name: 8 | min_length: 9 | error: 2 10 | excluded: 11 | - a 12 | - b 13 | - c 14 | - cw 15 | - cx 16 | - cy 17 | - dx 18 | - dy 19 | - e2 20 | - fm 21 | - g 22 | - h 23 | - h2 24 | - hh 25 | - i 26 | - i2 27 | - id 28 | - ii 29 | - j 30 | - j2 31 | - jj 32 | - m 33 | - n 34 | - nc 35 | - ok 36 | - ox 37 | - oy 38 | - px 39 | - py 40 | - r 41 | - s 42 | - sx 43 | - sy 44 | - t 45 | - t0 46 | - t1 47 | - up 48 | - v 49 | - vc 50 | - w 51 | - w1 52 | - x 53 | - xx 54 | - x0 55 | - x1 56 | - x2 57 | - x3 58 | - xy 59 | - y 60 | - yy 61 | - y0 62 | - y1 63 | - y2 64 | - y3 65 | 66 | line_length: 67 | warning: 200 68 | error: 400 69 | ignores_comments: true 70 | 71 | disabled_rules: 72 | - switch_case_alignment 73 | - no_space_in_method_call 74 | - shorthand_operator -------------------------------------------------------------------------------- /Source/Documentation/features.md: -------------------------------------------------------------------------------- 1 | # Features of TriangleDraw 2 | 3 | TriangleDraw is brilliant for sketching logos. You can quickly create designs 4 | that can be used for branding on letterheads or on your website. 5 | 6 | ## Primary Features 7 | 8 | - Draw: use one finger to draw black/white triangles. 9 | - Pinch: use two fingers to zoom. 10 | 11 | 12 | ## Secondary Features 13 | 14 | - iOS: Best experience on iPad. Also usable on an iPhone with a smaller screen. 15 | - Browser: Organize your drawing files in directories. Rename. Duplicate. 16 | - Canvas: There are 11616 triangles; you have plenty of space for all kinds of symbols/logos. 17 | - Rotate the canvas by 60 degrees. 18 | - Flip the canvas around the x axis or the y axis. 19 | - Invert, so white becomes black and black becomes white. 20 | - Move the canvas by one column/row. The triangles wraps around the canvas edge. 21 | - Symmetry modes: x, y, xy, 3 way, 6 way. 22 | - Subdivide: Split up all triangles into smaller triangles. 23 | - Undo: If something goes wrong, then you can roll back to the moment just before it went wrong. 24 | - Fullscreen: Hide the toolbars and work without noise. 25 | - Export to vector: Supports both PDF and SVG. 26 | - Export to bitmap: A 2048x2048 image that can be saved to the photo album or shared on social media. 27 | - Free: The app doesn't cost anything. 28 | - OpenSource: You can modify the code. 29 | 30 | -------------------------------------------------------------------------------- /Source/Documentation/history.md: -------------------------------------------------------------------------------- 1 | # History of TriangleDraw 2 | 3 | Greetings from Simon Strandgaard. I'm the developer of TriangleDraw. It has been my hobby project for many years. 4 | 5 | The story begin around year 2004, when I learn about a new visual programming language with the unorthodox name: [.werkkzeug](https://www.pouet.net/prod.php?which=12511), 6 | by the german demo group [Farbrausch](https://en.wikipedia.org/wiki/Farbrausch). 7 | A powerful tool for composing digital art, a demotool. 8 | With this approach it's possible to combine building blocks together in a few minutes, and see results immediately. 9 | Accomplishing the same, would otherwise take days of coding and without any realtime feedback. 10 | I was in love. 11 | 12 | I developed my own visual programming language for macOS, named GraphicDesignerToolbox (aka. GDT), that had building blocks 13 | that could be stacked the same way as in .werkkzeug. For GDT I made several building blocks for manipulating bitmap images and a few building blocks for manipulating vector paths. 14 | Around 2006, I made an "Align" building block for aligning any vector path to a grid system, such as triangular and square. 15 | I used C++ for the building blocks and ObjectiveC for the UI. I learned that undo is incredibly difficult to deal with. 16 | 17 | BOOM the iPad arrives around 2010, featuring a big touch screen. I developed the first version of TriangleDraw, that was 18 | inspired by the "Align" building block from GDT. I soon after released TriangleDraw version 1. It had a tiny tiny canvas. 19 | It only worked on iPad. No support for iPhone. I had no luck selling the app. Downloads were higher in Japan, than the rest of the world. 20 | 21 | Around year 2014 I had TriangleDraw version 2 ready. The canvas was much larger, and could be rotated by 60 degrees. 22 | It worked on iPhone+iPad. I experimented with In-app-purchases, but I still had no luck earning any money on version 2. 23 | 24 | Around year 2018/2019 I migrated all the TriangleDraw source code from ObjectiveC to Swift. The `UIDocumentBrowserViewController` is now being used, where in the past I used my own adhoc document browser. 25 | And best of all, it's free and open source. Please consider contributing to TriangleDraw. 26 | 27 | Feel free to write to me: [hello@triangledraw.com](mailto:hello@triangledraw.com). 28 | 29 | This is Simon Strandgaard, developer of TriangleDraw, signing off. 30 | -------------------------------------------------------------------------------- /Source/Documentation/triangledraw_screenshots.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/triangledraw/TriangleDraw-iOS/25bc87c479cd10b461a17834b67d99d911f7cc34/Source/Documentation/triangledraw_screenshots.png -------------------------------------------------------------------------------- /Source/Podfile: -------------------------------------------------------------------------------- 1 | source 'https://github.com/CocoaPods/Specs.git' 2 | swift_version = "5.0" 3 | platform :ios, '16' 4 | use_frameworks! 5 | 6 | def my_pod_mbprogresshud 7 | # https://github.com/jdg/MBProgressHUD/commits/master 8 | pod 'MBProgressHUD', :git => 'https://github.com/jdg/MBProgressHUD.git', :commit => 'c843e4c86d320a11552898646effa8000042ab16' 9 | end 10 | 11 | def my_pod_swiftybeaver 12 | # https://github.com/SwiftyBeaver/SwiftyBeaver/commits/master 13 | pod 'SwiftyBeaver', :git => 'https://github.com/SwiftyBeaver/SwiftyBeaver.git', :commit => 'dc3b9adf6c8faeb91a93b60993b5292d66b26c1c' 14 | end 15 | 16 | abstract_target 'BasePods' do 17 | my_pod_swiftybeaver 18 | 19 | target 'Tests' do 20 | end 21 | 22 | target 'TriangleDrawMain' do 23 | my_pod_mbprogresshud 24 | end 25 | 26 | target 'TriangleDrawThumbnail' do 27 | end 28 | 29 | target 'TriangleDrawLibrary' do 30 | end 31 | end 32 | 33 | 34 | # workaround: https://github.com/CocoaPods/CocoaPods/issues/7606 35 | post_install do |installer| 36 | installer.pods_project.build_configurations.each do |config| 37 | config.build_settings.delete('CODE_SIGNING_ALLOWED') 38 | config.build_settings.delete('CODE_SIGNING_REQUIRED') 39 | end 40 | end 41 | -------------------------------------------------------------------------------- /Source/Podfile.lock: -------------------------------------------------------------------------------- 1 | PODS: 2 | - MBProgressHUD (1.2.0) 3 | - SwiftyBeaver (1.9.6) 4 | 5 | DEPENDENCIES: 6 | - MBProgressHUD (from `https://github.com/jdg/MBProgressHUD.git`, commit `c843e4c86d320a11552898646effa8000042ab16`) 7 | - SwiftyBeaver (from `https://github.com/SwiftyBeaver/SwiftyBeaver.git`, commit `dc3b9adf6c8faeb91a93b60993b5292d66b26c1c`) 8 | 9 | EXTERNAL SOURCES: 10 | MBProgressHUD: 11 | :commit: c843e4c86d320a11552898646effa8000042ab16 12 | :git: https://github.com/jdg/MBProgressHUD.git 13 | SwiftyBeaver: 14 | :commit: dc3b9adf6c8faeb91a93b60993b5292d66b26c1c 15 | :git: https://github.com/SwiftyBeaver/SwiftyBeaver.git 16 | 17 | CHECKOUT OPTIONS: 18 | MBProgressHUD: 19 | :commit: c843e4c86d320a11552898646effa8000042ab16 20 | :git: https://github.com/jdg/MBProgressHUD.git 21 | SwiftyBeaver: 22 | :commit: dc3b9adf6c8faeb91a93b60993b5292d66b26c1c 23 | :git: https://github.com/SwiftyBeaver/SwiftyBeaver.git 24 | 25 | SPEC CHECKSUMS: 26 | MBProgressHUD: 81cfc510382828962d6fd893c003d1b2beee386c 27 | SwiftyBeaver: c8241b4745aa269a78ca5a022532c6915e948536 28 | 29 | PODFILE CHECKSUM: 632baee4cf71123d3a2a89e88a2c485537718a46 30 | 31 | COCOAPODS: 1.10.1 32 | -------------------------------------------------------------------------------- /Source/Pods/Local Podspecs/MBProgressHUD.podspec.json: -------------------------------------------------------------------------------- 1 | { 2 | "name": "MBProgressHUD", 3 | "version": "1.2.0", 4 | "summary": "An iOS activity indicator view.", 5 | "description": "MBProgressHUD is an iOS drop-in class that displays a translucent HUD\nwith an indicator and/or labels while work is being done in a background thread.\nThe HUD is meant as a replacement for the undocumented, private UIKit UIProgressHUD\nwith some additional features.", 6 | "homepage": "http://www.bukovinski.com", 7 | "license": { 8 | "type": "MIT", 9 | "file": "LICENSE" 10 | }, 11 | "authors": { 12 | "Matej Bukovinski": "matej@bukovinski.com" 13 | }, 14 | "source": { 15 | "git": "https://github.com/matej/MBProgressHUD.git", 16 | "tag": "1.2.0" 17 | }, 18 | "platforms": { 19 | "ios": "9.0", 20 | "tvos": "9.0" 21 | }, 22 | "source_files": "*.{h,m}", 23 | "frameworks": [ 24 | "CoreGraphics", 25 | "QuartzCore" 26 | ], 27 | "requires_arc": true 28 | } 29 | -------------------------------------------------------------------------------- /Source/Pods/Local Podspecs/SwiftyBeaver.podspec.json: -------------------------------------------------------------------------------- 1 | { 2 | "name": "SwiftyBeaver", 3 | "version": "1.9.6", 4 | "summary": "Convenient logging during development & release in Swift 4 & 5.", 5 | "description": "Easy-to-use, extensible & powerful logging & analytics for Swift 4 and Swift 5.\nGreat for development & release due to its support for many logging destinations & platforms.", 6 | "homepage": "https://github.com/SwiftyBeaver/SwiftyBeaver", 7 | "screenshots": [ 8 | "https://cloud.githubusercontent.com/assets/564725/11452558/17fd5f04-95ec-11e5-96d2-427f62ed4f05.jpg", 9 | "https://cloud.githubusercontent.com/assets/564725/11452560/33225d16-95ec-11e5-8461-78f50b9e8da7.jpg" 10 | ], 11 | "license": "MIT", 12 | "authors": { 13 | "Sebastian Kreutzberger": "s.kreutzberger@googlemail.com" 14 | }, 15 | "platforms": { 16 | "ios": "13.4", 17 | "watchos": "6.2", 18 | "tvos": "13.4", 19 | "osx": "10.15.4" 20 | }, 21 | "source": { 22 | "git": "https://github.com/SwiftyBeaver/SwiftyBeaver.git", 23 | "tag": "1.9.6" 24 | }, 25 | "source_files": "Sources", 26 | "swift_versions": [ 27 | "4.0", 28 | "4.2", 29 | "5.0", 30 | "5.1" 31 | ], 32 | "swift_version": "5.1" 33 | } 34 | -------------------------------------------------------------------------------- /Source/Pods/MBProgressHUD/LICENSE: -------------------------------------------------------------------------------- 1 | Copyright © 2009-2020 Matej Bukovinski 2 | 3 | Permission is hereby granted, free of charge, to any person obtaining a copy 4 | of this software and associated documentation files (the "Software"), to deal 5 | in the Software without restriction, including without limitation the rights 6 | to use, copy, modify, merge, publish, distribute, sublicense, and/or sell 7 | copies of the Software, and to permit persons to whom the Software is 8 | furnished to do so, subject to the following conditions: 9 | 10 | The above copyright notice and this permission notice shall be included in 11 | all 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, 15 | FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE 16 | AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER 17 | LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, 18 | OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN 19 | THE SOFTWARE. -------------------------------------------------------------------------------- /Source/Pods/Manifest.lock: -------------------------------------------------------------------------------- 1 | PODS: 2 | - MBProgressHUD (1.2.0) 3 | - SwiftyBeaver (1.9.6) 4 | 5 | DEPENDENCIES: 6 | - MBProgressHUD (from `https://github.com/jdg/MBProgressHUD.git`, commit `c843e4c86d320a11552898646effa8000042ab16`) 7 | - SwiftyBeaver (from `https://github.com/SwiftyBeaver/SwiftyBeaver.git`, commit `dc3b9adf6c8faeb91a93b60993b5292d66b26c1c`) 8 | 9 | EXTERNAL SOURCES: 10 | MBProgressHUD: 11 | :commit: c843e4c86d320a11552898646effa8000042ab16 12 | :git: https://github.com/jdg/MBProgressHUD.git 13 | SwiftyBeaver: 14 | :commit: dc3b9adf6c8faeb91a93b60993b5292d66b26c1c 15 | :git: https://github.com/SwiftyBeaver/SwiftyBeaver.git 16 | 17 | CHECKOUT OPTIONS: 18 | MBProgressHUD: 19 | :commit: c843e4c86d320a11552898646effa8000042ab16 20 | :git: https://github.com/jdg/MBProgressHUD.git 21 | SwiftyBeaver: 22 | :commit: dc3b9adf6c8faeb91a93b60993b5292d66b26c1c 23 | :git: https://github.com/SwiftyBeaver/SwiftyBeaver.git 24 | 25 | SPEC CHECKSUMS: 26 | MBProgressHUD: 81cfc510382828962d6fd893c003d1b2beee386c 27 | SwiftyBeaver: c8241b4745aa269a78ca5a022532c6915e948536 28 | 29 | PODFILE CHECKSUM: 632baee4cf71123d3a2a89e88a2c485537718a46 30 | 31 | COCOAPODS: 1.10.1 32 | -------------------------------------------------------------------------------- /Source/Pods/SwiftyBeaver/LICENSE: -------------------------------------------------------------------------------- 1 | The MIT License (MIT) 2 | 3 | Copyright (c) 2015 Sebastian Kreutzberger 4 | 5 | Permission is hereby granted, free of charge, to any person obtaining a copy 6 | of this software and associated documentation files (the "Software"), to deal 7 | in the Software without restriction, including without limitation the rights 8 | to use, copy, modify, merge, publish, distribute, sublicense, and/or sell 9 | copies of the Software, and to permit persons to whom the Software is 10 | furnished to do so, subject to the following conditions: 11 | 12 | The above copyright notice and this permission notice shall be included in all 13 | copies or substantial portions of the Software. 14 | 15 | THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR 16 | IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, 17 | FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE 18 | AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER 19 | LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, 20 | OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE 21 | SOFTWARE. 22 | -------------------------------------------------------------------------------- /Source/Pods/SwiftyBeaver/Sources/Extensions.swift: -------------------------------------------------------------------------------- 1 | // 2 | // Extensions.swift 3 | // SwiftyBeaver 4 | // 5 | // Created by Sebastian Kreutzberger on 13.12.17. 6 | // Copyright © 2017 Sebastian Kreutzberger. All rights reserved. 7 | // 8 | 9 | import Foundation 10 | 11 | extension String { 12 | /// cross-Swift compatible characters count 13 | var length: Int { 14 | return self.count 15 | } 16 | 17 | /// cross-Swift-compatible first character 18 | var firstChar: Character? { 19 | return self.first 20 | } 21 | 22 | /// cross-Swift-compatible last character 23 | var lastChar: Character? { 24 | return self.last 25 | } 26 | 27 | /// cross-Swift-compatible index 28 | func find(_ char: Character) -> Index? { 29 | #if swift(>=5) 30 | return self.firstIndex(of: char) 31 | #else 32 | return self.index(of: char) 33 | #endif 34 | } 35 | } 36 | -------------------------------------------------------------------------------- /Source/Pods/Target Support Files/MBProgressHUD/MBProgressHUD-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.2.0 19 | CFBundleSignature 20 | ???? 21 | CFBundleVersion 22 | ${CURRENT_PROJECT_VERSION} 23 | NSPrincipalClass 24 | 25 | 26 | 27 | -------------------------------------------------------------------------------- /Source/Pods/Target Support Files/MBProgressHUD/MBProgressHUD-dummy.m: -------------------------------------------------------------------------------- 1 | #import 2 | @interface PodsDummy_MBProgressHUD : NSObject 3 | @end 4 | @implementation PodsDummy_MBProgressHUD 5 | @end 6 | -------------------------------------------------------------------------------- /Source/Pods/Target Support Files/MBProgressHUD/MBProgressHUD-prefix.pch: -------------------------------------------------------------------------------- 1 | #ifdef __OBJC__ 2 | #import 3 | #else 4 | #ifndef FOUNDATION_EXPORT 5 | #if defined(__cplusplus) 6 | #define FOUNDATION_EXPORT extern "C" 7 | #else 8 | #define FOUNDATION_EXPORT extern 9 | #endif 10 | #endif 11 | #endif 12 | 13 | -------------------------------------------------------------------------------- /Source/Pods/Target Support Files/MBProgressHUD/MBProgressHUD-umbrella.h: -------------------------------------------------------------------------------- 1 | #ifdef __OBJC__ 2 | #import 3 | #else 4 | #ifndef FOUNDATION_EXPORT 5 | #if defined(__cplusplus) 6 | #define FOUNDATION_EXPORT extern "C" 7 | #else 8 | #define FOUNDATION_EXPORT extern 9 | #endif 10 | #endif 11 | #endif 12 | 13 | #import "MBProgressHUD.h" 14 | 15 | FOUNDATION_EXPORT double MBProgressHUDVersionNumber; 16 | FOUNDATION_EXPORT const unsigned char MBProgressHUDVersionString[]; 17 | 18 | -------------------------------------------------------------------------------- /Source/Pods/Target Support Files/MBProgressHUD/MBProgressHUD.debug.xcconfig: -------------------------------------------------------------------------------- 1 | CLANG_WARN_QUOTED_INCLUDE_IN_FRAMEWORK_HEADER = NO 2 | CONFIGURATION_BUILD_DIR = ${PODS_CONFIGURATION_BUILD_DIR}/MBProgressHUD 3 | GCC_PREPROCESSOR_DEFINITIONS = $(inherited) COCOAPODS=1 4 | OTHER_LDFLAGS = $(inherited) -framework "CoreGraphics" -framework "QuartzCore" 5 | PODS_BUILD_DIR = ${BUILD_DIR} 6 | PODS_CONFIGURATION_BUILD_DIR = ${PODS_BUILD_DIR}/$(CONFIGURATION)$(EFFECTIVE_PLATFORM_NAME) 7 | PODS_ROOT = ${SRCROOT} 8 | PODS_TARGET_SRCROOT = ${PODS_ROOT}/MBProgressHUD 9 | PODS_XCFRAMEWORKS_BUILD_DIR = $(PODS_CONFIGURATION_BUILD_DIR)/XCFrameworkIntermediates 10 | PRODUCT_BUNDLE_IDENTIFIER = org.cocoapods.${PRODUCT_NAME:rfc1034identifier} 11 | SKIP_INSTALL = YES 12 | USE_RECURSIVE_SCRIPT_INPUTS_IN_SCRIPT_PHASES = YES 13 | -------------------------------------------------------------------------------- /Source/Pods/Target Support Files/MBProgressHUD/MBProgressHUD.modulemap: -------------------------------------------------------------------------------- 1 | framework module MBProgressHUD { 2 | umbrella header "MBProgressHUD-umbrella.h" 3 | 4 | export * 5 | module * { export * } 6 | } 7 | -------------------------------------------------------------------------------- /Source/Pods/Target Support Files/MBProgressHUD/MBProgressHUD.release.xcconfig: -------------------------------------------------------------------------------- 1 | CLANG_WARN_QUOTED_INCLUDE_IN_FRAMEWORK_HEADER = NO 2 | CONFIGURATION_BUILD_DIR = ${PODS_CONFIGURATION_BUILD_DIR}/MBProgressHUD 3 | GCC_PREPROCESSOR_DEFINITIONS = $(inherited) COCOAPODS=1 4 | OTHER_LDFLAGS = $(inherited) -framework "CoreGraphics" -framework "QuartzCore" 5 | PODS_BUILD_DIR = ${BUILD_DIR} 6 | PODS_CONFIGURATION_BUILD_DIR = ${PODS_BUILD_DIR}/$(CONFIGURATION)$(EFFECTIVE_PLATFORM_NAME) 7 | PODS_ROOT = ${SRCROOT} 8 | PODS_TARGET_SRCROOT = ${PODS_ROOT}/MBProgressHUD 9 | PODS_XCFRAMEWORKS_BUILD_DIR = $(PODS_CONFIGURATION_BUILD_DIR)/XCFrameworkIntermediates 10 | PRODUCT_BUNDLE_IDENTIFIER = org.cocoapods.${PRODUCT_NAME:rfc1034identifier} 11 | SKIP_INSTALL = YES 12 | USE_RECURSIVE_SCRIPT_INPUTS_IN_SCRIPT_PHASES = YES 13 | -------------------------------------------------------------------------------- /Source/Pods/Target Support Files/MBProgressHUD/MBProgressHUD.xcconfig: -------------------------------------------------------------------------------- 1 | CONFIGURATION_BUILD_DIR = ${PODS_CONFIGURATION_BUILD_DIR}/MBProgressHUD 2 | GCC_PREPROCESSOR_DEFINITIONS = $(inherited) COCOAPODS=1 3 | OTHER_LDFLAGS = $(inherited) -framework "CoreGraphics" -framework "QuartzCore" 4 | PODS_BUILD_DIR = ${BUILD_DIR} 5 | PODS_CONFIGURATION_BUILD_DIR = ${PODS_BUILD_DIR}/$(CONFIGURATION)$(EFFECTIVE_PLATFORM_NAME) 6 | PODS_ROOT = ${SRCROOT} 7 | PODS_TARGET_SRCROOT = ${PODS_ROOT}/MBProgressHUD 8 | PRODUCT_BUNDLE_IDENTIFIER = org.cocoapods.${PRODUCT_NAME:rfc1034identifier} 9 | SKIP_INSTALL = YES 10 | USE_RECURSIVE_SCRIPT_INPUTS_IN_SCRIPT_PHASES = YES 11 | -------------------------------------------------------------------------------- /Source/Pods/Target Support Files/Pods-BasePods-Tests/Pods-BasePods-Tests-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.0 19 | CFBundleSignature 20 | ???? 21 | CFBundleVersion 22 | ${CURRENT_PROJECT_VERSION} 23 | NSPrincipalClass 24 | 25 | 26 | 27 | -------------------------------------------------------------------------------- /Source/Pods/Target Support Files/Pods-BasePods-Tests/Pods-BasePods-Tests-acknowledgements.markdown: -------------------------------------------------------------------------------- 1 | # Acknowledgements 2 | This application makes use of the following third party libraries: 3 | 4 | ## SwiftyBeaver 5 | 6 | The MIT License (MIT) 7 | 8 | Copyright (c) 2015 Sebastian Kreutzberger 9 | 10 | Permission is hereby granted, free of charge, to any person obtaining a copy 11 | of this software and associated documentation files (the "Software"), to deal 12 | in the Software without restriction, including without limitation the rights 13 | to use, copy, modify, merge, publish, distribute, sublicense, and/or sell 14 | copies of the Software, and to permit persons to whom the Software is 15 | furnished to do so, subject to the following conditions: 16 | 17 | The above copyright notice and this permission notice shall be included in all 18 | copies or substantial portions of the Software. 19 | 20 | THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR 21 | IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, 22 | FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE 23 | AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER 24 | LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, 25 | OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE 26 | SOFTWARE. 27 | 28 | Generated by CocoaPods - https://cocoapods.org 29 | -------------------------------------------------------------------------------- /Source/Pods/Target Support Files/Pods-BasePods-Tests/Pods-BasePods-Tests-acknowledgements.plist: -------------------------------------------------------------------------------- 1 | 2 | 3 | 4 | 5 | PreferenceSpecifiers 6 | 7 | 8 | FooterText 9 | This application makes use of the following third party libraries: 10 | Title 11 | Acknowledgements 12 | Type 13 | PSGroupSpecifier 14 | 15 | 16 | FooterText 17 | The MIT License (MIT) 18 | 19 | Copyright (c) 2015 Sebastian Kreutzberger 20 | 21 | Permission is hereby granted, free of charge, to any person obtaining a copy 22 | of this software and associated documentation files (the "Software"), to deal 23 | in the Software without restriction, including without limitation the rights 24 | to use, copy, modify, merge, publish, distribute, sublicense, and/or sell 25 | copies of the Software, and to permit persons to whom the Software is 26 | furnished to do so, subject to the following conditions: 27 | 28 | The above copyright notice and this permission notice shall be included in all 29 | copies or substantial portions of the Software. 30 | 31 | THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR 32 | IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, 33 | FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE 34 | AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER 35 | LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, 36 | OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE 37 | SOFTWARE. 38 | 39 | License 40 | MIT 41 | Title 42 | SwiftyBeaver 43 | Type 44 | PSGroupSpecifier 45 | 46 | 47 | FooterText 48 | Generated by CocoaPods - https://cocoapods.org 49 | Title 50 | 51 | Type 52 | PSGroupSpecifier 53 | 54 | 55 | StringsTable 56 | Acknowledgements 57 | Title 58 | Acknowledgements 59 | 60 | 61 | -------------------------------------------------------------------------------- /Source/Pods/Target Support Files/Pods-BasePods-Tests/Pods-BasePods-Tests-dummy.m: -------------------------------------------------------------------------------- 1 | #import 2 | @interface PodsDummy_Pods_BasePods_Tests : NSObject 3 | @end 4 | @implementation PodsDummy_Pods_BasePods_Tests 5 | @end 6 | -------------------------------------------------------------------------------- /Source/Pods/Target Support Files/Pods-BasePods-Tests/Pods-BasePods-Tests-frameworks-Debug-input-files.xcfilelist: -------------------------------------------------------------------------------- 1 | ${PODS_ROOT}/Target Support Files/Pods-BasePods-Tests/Pods-BasePods-Tests-frameworks.sh 2 | ${BUILT_PRODUCTS_DIR}/SwiftyBeaver/SwiftyBeaver.framework -------------------------------------------------------------------------------- /Source/Pods/Target Support Files/Pods-BasePods-Tests/Pods-BasePods-Tests-frameworks-Debug-output-files.xcfilelist: -------------------------------------------------------------------------------- 1 | ${TARGET_BUILD_DIR}/${FRAMEWORKS_FOLDER_PATH}/SwiftyBeaver.framework -------------------------------------------------------------------------------- /Source/Pods/Target Support Files/Pods-BasePods-Tests/Pods-BasePods-Tests-frameworks-Release-input-files.xcfilelist: -------------------------------------------------------------------------------- 1 | ${PODS_ROOT}/Target Support Files/Pods-BasePods-Tests/Pods-BasePods-Tests-frameworks.sh 2 | ${BUILT_PRODUCTS_DIR}/SwiftyBeaver/SwiftyBeaver.framework -------------------------------------------------------------------------------- /Source/Pods/Target Support Files/Pods-BasePods-Tests/Pods-BasePods-Tests-frameworks-Release-output-files.xcfilelist: -------------------------------------------------------------------------------- 1 | ${TARGET_BUILD_DIR}/${FRAMEWORKS_FOLDER_PATH}/SwiftyBeaver.framework -------------------------------------------------------------------------------- /Source/Pods/Target Support Files/Pods-BasePods-Tests/Pods-BasePods-Tests-umbrella.h: -------------------------------------------------------------------------------- 1 | #ifdef __OBJC__ 2 | #import 3 | #else 4 | #ifndef FOUNDATION_EXPORT 5 | #if defined(__cplusplus) 6 | #define FOUNDATION_EXPORT extern "C" 7 | #else 8 | #define FOUNDATION_EXPORT extern 9 | #endif 10 | #endif 11 | #endif 12 | 13 | 14 | FOUNDATION_EXPORT double Pods_BasePods_TestsVersionNumber; 15 | FOUNDATION_EXPORT const unsigned char Pods_BasePods_TestsVersionString[]; 16 | 17 | -------------------------------------------------------------------------------- /Source/Pods/Target Support Files/Pods-BasePods-Tests/Pods-BasePods-Tests.debug.xcconfig: -------------------------------------------------------------------------------- 1 | ALWAYS_EMBED_SWIFT_STANDARD_LIBRARIES = YES 2 | CLANG_WARN_QUOTED_INCLUDE_IN_FRAMEWORK_HEADER = NO 3 | FRAMEWORK_SEARCH_PATHS = $(inherited) "${PODS_CONFIGURATION_BUILD_DIR}/SwiftyBeaver" 4 | GCC_PREPROCESSOR_DEFINITIONS = $(inherited) COCOAPODS=1 5 | HEADER_SEARCH_PATHS = $(inherited) "${PODS_CONFIGURATION_BUILD_DIR}/SwiftyBeaver/SwiftyBeaver.framework/Headers" 6 | LD_RUNPATH_SEARCH_PATHS = $(inherited) '@executable_path/Frameworks' '@loader_path/Frameworks' 7 | OTHER_LDFLAGS = $(inherited) -framework "SwiftyBeaver" 8 | OTHER_SWIFT_FLAGS = $(inherited) -D COCOAPODS 9 | PODS_BUILD_DIR = ${BUILD_DIR} 10 | PODS_CONFIGURATION_BUILD_DIR = ${PODS_BUILD_DIR}/$(CONFIGURATION)$(EFFECTIVE_PLATFORM_NAME) 11 | PODS_PODFILE_DIR_PATH = ${SRCROOT}/. 12 | PODS_ROOT = ${SRCROOT}/Pods 13 | PODS_XCFRAMEWORKS_BUILD_DIR = $(PODS_CONFIGURATION_BUILD_DIR)/XCFrameworkIntermediates 14 | USE_RECURSIVE_SCRIPT_INPUTS_IN_SCRIPT_PHASES = YES 15 | -------------------------------------------------------------------------------- /Source/Pods/Target Support Files/Pods-BasePods-Tests/Pods-BasePods-Tests.modulemap: -------------------------------------------------------------------------------- 1 | framework module Pods_BasePods_Tests { 2 | umbrella header "Pods-BasePods-Tests-umbrella.h" 3 | 4 | export * 5 | module * { export * } 6 | } 7 | -------------------------------------------------------------------------------- /Source/Pods/Target Support Files/Pods-BasePods-Tests/Pods-BasePods-Tests.release.xcconfig: -------------------------------------------------------------------------------- 1 | ALWAYS_EMBED_SWIFT_STANDARD_LIBRARIES = YES 2 | CLANG_WARN_QUOTED_INCLUDE_IN_FRAMEWORK_HEADER = NO 3 | FRAMEWORK_SEARCH_PATHS = $(inherited) "${PODS_CONFIGURATION_BUILD_DIR}/SwiftyBeaver" 4 | GCC_PREPROCESSOR_DEFINITIONS = $(inherited) COCOAPODS=1 5 | HEADER_SEARCH_PATHS = $(inherited) "${PODS_CONFIGURATION_BUILD_DIR}/SwiftyBeaver/SwiftyBeaver.framework/Headers" 6 | LD_RUNPATH_SEARCH_PATHS = $(inherited) '@executable_path/Frameworks' '@loader_path/Frameworks' 7 | OTHER_LDFLAGS = $(inherited) -framework "SwiftyBeaver" 8 | OTHER_SWIFT_FLAGS = $(inherited) -D COCOAPODS 9 | PODS_BUILD_DIR = ${BUILD_DIR} 10 | PODS_CONFIGURATION_BUILD_DIR = ${PODS_BUILD_DIR}/$(CONFIGURATION)$(EFFECTIVE_PLATFORM_NAME) 11 | PODS_PODFILE_DIR_PATH = ${SRCROOT}/. 12 | PODS_ROOT = ${SRCROOT}/Pods 13 | PODS_XCFRAMEWORKS_BUILD_DIR = $(PODS_CONFIGURATION_BUILD_DIR)/XCFrameworkIntermediates 14 | USE_RECURSIVE_SCRIPT_INPUTS_IN_SCRIPT_PHASES = YES 15 | -------------------------------------------------------------------------------- /Source/Pods/Target Support Files/Pods-BasePods-TriangleDrawLibrary/Pods-BasePods-TriangleDrawLibrary-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.0 19 | CFBundleSignature 20 | ???? 21 | CFBundleVersion 22 | ${CURRENT_PROJECT_VERSION} 23 | NSPrincipalClass 24 | 25 | 26 | 27 | -------------------------------------------------------------------------------- /Source/Pods/Target Support Files/Pods-BasePods-TriangleDrawLibrary/Pods-BasePods-TriangleDrawLibrary-acknowledgements.markdown: -------------------------------------------------------------------------------- 1 | # Acknowledgements 2 | This application makes use of the following third party libraries: 3 | 4 | ## SwiftyBeaver 5 | 6 | The MIT License (MIT) 7 | 8 | Copyright (c) 2015 Sebastian Kreutzberger 9 | 10 | Permission is hereby granted, free of charge, to any person obtaining a copy 11 | of this software and associated documentation files (the "Software"), to deal 12 | in the Software without restriction, including without limitation the rights 13 | to use, copy, modify, merge, publish, distribute, sublicense, and/or sell 14 | copies of the Software, and to permit persons to whom the Software is 15 | furnished to do so, subject to the following conditions: 16 | 17 | The above copyright notice and this permission notice shall be included in all 18 | copies or substantial portions of the Software. 19 | 20 | THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR 21 | IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, 22 | FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE 23 | AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER 24 | LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, 25 | OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE 26 | SOFTWARE. 27 | 28 | Generated by CocoaPods - https://cocoapods.org 29 | -------------------------------------------------------------------------------- /Source/Pods/Target Support Files/Pods-BasePods-TriangleDrawLibrary/Pods-BasePods-TriangleDrawLibrary-dummy.m: -------------------------------------------------------------------------------- 1 | #import 2 | @interface PodsDummy_Pods_BasePods_TriangleDrawLibrary : NSObject 3 | @end 4 | @implementation PodsDummy_Pods_BasePods_TriangleDrawLibrary 5 | @end 6 | -------------------------------------------------------------------------------- /Source/Pods/Target Support Files/Pods-BasePods-TriangleDrawLibrary/Pods-BasePods-TriangleDrawLibrary-umbrella.h: -------------------------------------------------------------------------------- 1 | #ifdef __OBJC__ 2 | #import 3 | #else 4 | #ifndef FOUNDATION_EXPORT 5 | #if defined(__cplusplus) 6 | #define FOUNDATION_EXPORT extern "C" 7 | #else 8 | #define FOUNDATION_EXPORT extern 9 | #endif 10 | #endif 11 | #endif 12 | 13 | 14 | FOUNDATION_EXPORT double Pods_BasePods_TriangleDrawLibraryVersionNumber; 15 | FOUNDATION_EXPORT const unsigned char Pods_BasePods_TriangleDrawLibraryVersionString[]; 16 | 17 | -------------------------------------------------------------------------------- /Source/Pods/Target Support Files/Pods-BasePods-TriangleDrawLibrary/Pods-BasePods-TriangleDrawLibrary.debug.xcconfig: -------------------------------------------------------------------------------- 1 | CLANG_WARN_QUOTED_INCLUDE_IN_FRAMEWORK_HEADER = NO 2 | FRAMEWORK_SEARCH_PATHS = $(inherited) "${PODS_CONFIGURATION_BUILD_DIR}/SwiftyBeaver" 3 | GCC_PREPROCESSOR_DEFINITIONS = $(inherited) COCOAPODS=1 4 | HEADER_SEARCH_PATHS = $(inherited) "${PODS_CONFIGURATION_BUILD_DIR}/SwiftyBeaver/SwiftyBeaver.framework/Headers" 5 | LD_RUNPATH_SEARCH_PATHS = $(inherited) '@executable_path/Frameworks' '@loader_path/Frameworks' '@executable_path/../../Frameworks' 6 | OTHER_LDFLAGS = $(inherited) -framework "SwiftyBeaver" 7 | OTHER_SWIFT_FLAGS = $(inherited) -D COCOAPODS 8 | PODS_BUILD_DIR = ${BUILD_DIR} 9 | PODS_CONFIGURATION_BUILD_DIR = ${PODS_BUILD_DIR}/$(CONFIGURATION)$(EFFECTIVE_PLATFORM_NAME) 10 | PODS_PODFILE_DIR_PATH = ${SRCROOT}/. 11 | PODS_ROOT = ${SRCROOT}/Pods 12 | PODS_XCFRAMEWORKS_BUILD_DIR = $(PODS_CONFIGURATION_BUILD_DIR)/XCFrameworkIntermediates 13 | USE_RECURSIVE_SCRIPT_INPUTS_IN_SCRIPT_PHASES = YES 14 | -------------------------------------------------------------------------------- /Source/Pods/Target Support Files/Pods-BasePods-TriangleDrawLibrary/Pods-BasePods-TriangleDrawLibrary.modulemap: -------------------------------------------------------------------------------- 1 | framework module Pods_BasePods_TriangleDrawLibrary { 2 | umbrella header "Pods-BasePods-TriangleDrawLibrary-umbrella.h" 3 | 4 | export * 5 | module * { export * } 6 | } 7 | -------------------------------------------------------------------------------- /Source/Pods/Target Support Files/Pods-BasePods-TriangleDrawLibrary/Pods-BasePods-TriangleDrawLibrary.release.xcconfig: -------------------------------------------------------------------------------- 1 | CLANG_WARN_QUOTED_INCLUDE_IN_FRAMEWORK_HEADER = NO 2 | FRAMEWORK_SEARCH_PATHS = $(inherited) "${PODS_CONFIGURATION_BUILD_DIR}/SwiftyBeaver" 3 | GCC_PREPROCESSOR_DEFINITIONS = $(inherited) COCOAPODS=1 4 | HEADER_SEARCH_PATHS = $(inherited) "${PODS_CONFIGURATION_BUILD_DIR}/SwiftyBeaver/SwiftyBeaver.framework/Headers" 5 | LD_RUNPATH_SEARCH_PATHS = $(inherited) '@executable_path/Frameworks' '@loader_path/Frameworks' '@executable_path/../../Frameworks' 6 | OTHER_LDFLAGS = $(inherited) -framework "SwiftyBeaver" 7 | OTHER_SWIFT_FLAGS = $(inherited) -D COCOAPODS 8 | PODS_BUILD_DIR = ${BUILD_DIR} 9 | PODS_CONFIGURATION_BUILD_DIR = ${PODS_BUILD_DIR}/$(CONFIGURATION)$(EFFECTIVE_PLATFORM_NAME) 10 | PODS_PODFILE_DIR_PATH = ${SRCROOT}/. 11 | PODS_ROOT = ${SRCROOT}/Pods 12 | PODS_XCFRAMEWORKS_BUILD_DIR = $(PODS_CONFIGURATION_BUILD_DIR)/XCFrameworkIntermediates 13 | USE_RECURSIVE_SCRIPT_INPUTS_IN_SCRIPT_PHASES = YES 14 | -------------------------------------------------------------------------------- /Source/Pods/Target Support Files/Pods-BasePods-TriangleDrawMain/Pods-BasePods-TriangleDrawMain-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.0 19 | CFBundleSignature 20 | ???? 21 | CFBundleVersion 22 | ${CURRENT_PROJECT_VERSION} 23 | NSPrincipalClass 24 | 25 | 26 | 27 | -------------------------------------------------------------------------------- /Source/Pods/Target Support Files/Pods-BasePods-TriangleDrawMain/Pods-BasePods-TriangleDrawMain-dummy.m: -------------------------------------------------------------------------------- 1 | #import 2 | @interface PodsDummy_Pods_BasePods_TriangleDrawMain : NSObject 3 | @end 4 | @implementation PodsDummy_Pods_BasePods_TriangleDrawMain 5 | @end 6 | -------------------------------------------------------------------------------- /Source/Pods/Target Support Files/Pods-BasePods-TriangleDrawMain/Pods-BasePods-TriangleDrawMain-frameworks-Debug-input-files.xcfilelist: -------------------------------------------------------------------------------- 1 | ${PODS_ROOT}/Target Support Files/Pods-BasePods-TriangleDrawMain/Pods-BasePods-TriangleDrawMain-frameworks.sh 2 | ${BUILT_PRODUCTS_DIR}/SwiftyBeaver/SwiftyBeaver.framework 3 | ${BUILT_PRODUCTS_DIR}/MBProgressHUD/MBProgressHUD.framework -------------------------------------------------------------------------------- /Source/Pods/Target Support Files/Pods-BasePods-TriangleDrawMain/Pods-BasePods-TriangleDrawMain-frameworks-Debug-output-files.xcfilelist: -------------------------------------------------------------------------------- 1 | ${TARGET_BUILD_DIR}/${FRAMEWORKS_FOLDER_PATH}/SwiftyBeaver.framework 2 | ${TARGET_BUILD_DIR}/${FRAMEWORKS_FOLDER_PATH}/MBProgressHUD.framework -------------------------------------------------------------------------------- /Source/Pods/Target Support Files/Pods-BasePods-TriangleDrawMain/Pods-BasePods-TriangleDrawMain-frameworks-Release-input-files.xcfilelist: -------------------------------------------------------------------------------- 1 | ${PODS_ROOT}/Target Support Files/Pods-BasePods-TriangleDrawMain/Pods-BasePods-TriangleDrawMain-frameworks.sh 2 | ${BUILT_PRODUCTS_DIR}/SwiftyBeaver/SwiftyBeaver.framework 3 | ${BUILT_PRODUCTS_DIR}/MBProgressHUD/MBProgressHUD.framework -------------------------------------------------------------------------------- /Source/Pods/Target Support Files/Pods-BasePods-TriangleDrawMain/Pods-BasePods-TriangleDrawMain-frameworks-Release-output-files.xcfilelist: -------------------------------------------------------------------------------- 1 | ${TARGET_BUILD_DIR}/${FRAMEWORKS_FOLDER_PATH}/SwiftyBeaver.framework 2 | ${TARGET_BUILD_DIR}/${FRAMEWORKS_FOLDER_PATH}/MBProgressHUD.framework -------------------------------------------------------------------------------- /Source/Pods/Target Support Files/Pods-BasePods-TriangleDrawMain/Pods-BasePods-TriangleDrawMain-umbrella.h: -------------------------------------------------------------------------------- 1 | #ifdef __OBJC__ 2 | #import 3 | #else 4 | #ifndef FOUNDATION_EXPORT 5 | #if defined(__cplusplus) 6 | #define FOUNDATION_EXPORT extern "C" 7 | #else 8 | #define FOUNDATION_EXPORT extern 9 | #endif 10 | #endif 11 | #endif 12 | 13 | 14 | FOUNDATION_EXPORT double Pods_BasePods_TriangleDrawMainVersionNumber; 15 | FOUNDATION_EXPORT const unsigned char Pods_BasePods_TriangleDrawMainVersionString[]; 16 | 17 | -------------------------------------------------------------------------------- /Source/Pods/Target Support Files/Pods-BasePods-TriangleDrawMain/Pods-BasePods-TriangleDrawMain.debug.xcconfig: -------------------------------------------------------------------------------- 1 | ALWAYS_EMBED_SWIFT_STANDARD_LIBRARIES = YES 2 | CLANG_WARN_QUOTED_INCLUDE_IN_FRAMEWORK_HEADER = NO 3 | FRAMEWORK_SEARCH_PATHS = $(inherited) "${PODS_CONFIGURATION_BUILD_DIR}/MBProgressHUD" "${PODS_CONFIGURATION_BUILD_DIR}/SwiftyBeaver" 4 | GCC_PREPROCESSOR_DEFINITIONS = $(inherited) COCOAPODS=1 5 | HEADER_SEARCH_PATHS = $(inherited) "${PODS_CONFIGURATION_BUILD_DIR}/MBProgressHUD/MBProgressHUD.framework/Headers" "${PODS_CONFIGURATION_BUILD_DIR}/SwiftyBeaver/SwiftyBeaver.framework/Headers" 6 | LD_RUNPATH_SEARCH_PATHS = $(inherited) '@executable_path/Frameworks' '@loader_path/Frameworks' 7 | OTHER_LDFLAGS = $(inherited) -framework "CoreGraphics" -framework "MBProgressHUD" -framework "QuartzCore" -framework "SwiftyBeaver" 8 | OTHER_SWIFT_FLAGS = $(inherited) -D COCOAPODS 9 | PODS_BUILD_DIR = ${BUILD_DIR} 10 | PODS_CONFIGURATION_BUILD_DIR = ${PODS_BUILD_DIR}/$(CONFIGURATION)$(EFFECTIVE_PLATFORM_NAME) 11 | PODS_PODFILE_DIR_PATH = ${SRCROOT}/. 12 | PODS_ROOT = ${SRCROOT}/Pods 13 | PODS_XCFRAMEWORKS_BUILD_DIR = $(PODS_CONFIGURATION_BUILD_DIR)/XCFrameworkIntermediates 14 | USE_RECURSIVE_SCRIPT_INPUTS_IN_SCRIPT_PHASES = YES 15 | -------------------------------------------------------------------------------- /Source/Pods/Target Support Files/Pods-BasePods-TriangleDrawMain/Pods-BasePods-TriangleDrawMain.modulemap: -------------------------------------------------------------------------------- 1 | framework module Pods_BasePods_TriangleDrawMain { 2 | umbrella header "Pods-BasePods-TriangleDrawMain-umbrella.h" 3 | 4 | export * 5 | module * { export * } 6 | } 7 | -------------------------------------------------------------------------------- /Source/Pods/Target Support Files/Pods-BasePods-TriangleDrawMain/Pods-BasePods-TriangleDrawMain.release.xcconfig: -------------------------------------------------------------------------------- 1 | ALWAYS_EMBED_SWIFT_STANDARD_LIBRARIES = YES 2 | CLANG_WARN_QUOTED_INCLUDE_IN_FRAMEWORK_HEADER = NO 3 | FRAMEWORK_SEARCH_PATHS = $(inherited) "${PODS_CONFIGURATION_BUILD_DIR}/MBProgressHUD" "${PODS_CONFIGURATION_BUILD_DIR}/SwiftyBeaver" 4 | GCC_PREPROCESSOR_DEFINITIONS = $(inherited) COCOAPODS=1 5 | HEADER_SEARCH_PATHS = $(inherited) "${PODS_CONFIGURATION_BUILD_DIR}/MBProgressHUD/MBProgressHUD.framework/Headers" "${PODS_CONFIGURATION_BUILD_DIR}/SwiftyBeaver/SwiftyBeaver.framework/Headers" 6 | LD_RUNPATH_SEARCH_PATHS = $(inherited) '@executable_path/Frameworks' '@loader_path/Frameworks' 7 | OTHER_LDFLAGS = $(inherited) -framework "CoreGraphics" -framework "MBProgressHUD" -framework "QuartzCore" -framework "SwiftyBeaver" 8 | OTHER_SWIFT_FLAGS = $(inherited) -D COCOAPODS 9 | PODS_BUILD_DIR = ${BUILD_DIR} 10 | PODS_CONFIGURATION_BUILD_DIR = ${PODS_BUILD_DIR}/$(CONFIGURATION)$(EFFECTIVE_PLATFORM_NAME) 11 | PODS_PODFILE_DIR_PATH = ${SRCROOT}/. 12 | PODS_ROOT = ${SRCROOT}/Pods 13 | PODS_XCFRAMEWORKS_BUILD_DIR = $(PODS_CONFIGURATION_BUILD_DIR)/XCFrameworkIntermediates 14 | USE_RECURSIVE_SCRIPT_INPUTS_IN_SCRIPT_PHASES = YES 15 | -------------------------------------------------------------------------------- /Source/Pods/Target Support Files/Pods-BasePods-TriangleDrawThumbnail/Pods-BasePods-TriangleDrawThumbnail-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.0 19 | CFBundleSignature 20 | ???? 21 | CFBundleVersion 22 | ${CURRENT_PROJECT_VERSION} 23 | NSPrincipalClass 24 | 25 | 26 | 27 | -------------------------------------------------------------------------------- /Source/Pods/Target Support Files/Pods-BasePods-TriangleDrawThumbnail/Pods-BasePods-TriangleDrawThumbnail-acknowledgements.markdown: -------------------------------------------------------------------------------- 1 | # Acknowledgements 2 | This application makes use of the following third party libraries: 3 | 4 | ## SwiftyBeaver 5 | 6 | The MIT License (MIT) 7 | 8 | Copyright (c) 2015 Sebastian Kreutzberger 9 | 10 | Permission is hereby granted, free of charge, to any person obtaining a copy 11 | of this software and associated documentation files (the "Software"), to deal 12 | in the Software without restriction, including without limitation the rights 13 | to use, copy, modify, merge, publish, distribute, sublicense, and/or sell 14 | copies of the Software, and to permit persons to whom the Software is 15 | furnished to do so, subject to the following conditions: 16 | 17 | The above copyright notice and this permission notice shall be included in all 18 | copies or substantial portions of the Software. 19 | 20 | THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR 21 | IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, 22 | FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE 23 | AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER 24 | LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, 25 | OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE 26 | SOFTWARE. 27 | 28 | Generated by CocoaPods - https://cocoapods.org 29 | -------------------------------------------------------------------------------- /Source/Pods/Target Support Files/Pods-BasePods-TriangleDrawThumbnail/Pods-BasePods-TriangleDrawThumbnail-dummy.m: -------------------------------------------------------------------------------- 1 | #import 2 | @interface PodsDummy_Pods_BasePods_TriangleDrawThumbnail : NSObject 3 | @end 4 | @implementation PodsDummy_Pods_BasePods_TriangleDrawThumbnail 5 | @end 6 | -------------------------------------------------------------------------------- /Source/Pods/Target Support Files/Pods-BasePods-TriangleDrawThumbnail/Pods-BasePods-TriangleDrawThumbnail-umbrella.h: -------------------------------------------------------------------------------- 1 | #ifdef __OBJC__ 2 | #import 3 | #else 4 | #ifndef FOUNDATION_EXPORT 5 | #if defined(__cplusplus) 6 | #define FOUNDATION_EXPORT extern "C" 7 | #else 8 | #define FOUNDATION_EXPORT extern 9 | #endif 10 | #endif 11 | #endif 12 | 13 | 14 | FOUNDATION_EXPORT double Pods_BasePods_TriangleDrawThumbnailVersionNumber; 15 | FOUNDATION_EXPORT const unsigned char Pods_BasePods_TriangleDrawThumbnailVersionString[]; 16 | 17 | -------------------------------------------------------------------------------- /Source/Pods/Target Support Files/Pods-BasePods-TriangleDrawThumbnail/Pods-BasePods-TriangleDrawThumbnail.debug.xcconfig: -------------------------------------------------------------------------------- 1 | CLANG_WARN_QUOTED_INCLUDE_IN_FRAMEWORK_HEADER = NO 2 | FRAMEWORK_SEARCH_PATHS = $(inherited) "${PODS_CONFIGURATION_BUILD_DIR}/SwiftyBeaver" 3 | GCC_PREPROCESSOR_DEFINITIONS = $(inherited) COCOAPODS=1 4 | HEADER_SEARCH_PATHS = $(inherited) "${PODS_CONFIGURATION_BUILD_DIR}/SwiftyBeaver/SwiftyBeaver.framework/Headers" 5 | LD_RUNPATH_SEARCH_PATHS = $(inherited) '@executable_path/Frameworks' '@loader_path/Frameworks' '@executable_path/../../Frameworks' 6 | OTHER_LDFLAGS = $(inherited) -framework "SwiftyBeaver" 7 | OTHER_SWIFT_FLAGS = $(inherited) -D COCOAPODS 8 | PODS_BUILD_DIR = ${BUILD_DIR} 9 | PODS_CONFIGURATION_BUILD_DIR = ${PODS_BUILD_DIR}/$(CONFIGURATION)$(EFFECTIVE_PLATFORM_NAME) 10 | PODS_PODFILE_DIR_PATH = ${SRCROOT}/. 11 | PODS_ROOT = ${SRCROOT}/Pods 12 | PODS_XCFRAMEWORKS_BUILD_DIR = $(PODS_CONFIGURATION_BUILD_DIR)/XCFrameworkIntermediates 13 | USE_RECURSIVE_SCRIPT_INPUTS_IN_SCRIPT_PHASES = YES 14 | -------------------------------------------------------------------------------- /Source/Pods/Target Support Files/Pods-BasePods-TriangleDrawThumbnail/Pods-BasePods-TriangleDrawThumbnail.modulemap: -------------------------------------------------------------------------------- 1 | framework module Pods_BasePods_TriangleDrawThumbnail { 2 | umbrella header "Pods-BasePods-TriangleDrawThumbnail-umbrella.h" 3 | 4 | export * 5 | module * { export * } 6 | } 7 | -------------------------------------------------------------------------------- /Source/Pods/Target Support Files/Pods-BasePods-TriangleDrawThumbnail/Pods-BasePods-TriangleDrawThumbnail.release.xcconfig: -------------------------------------------------------------------------------- 1 | CLANG_WARN_QUOTED_INCLUDE_IN_FRAMEWORK_HEADER = NO 2 | FRAMEWORK_SEARCH_PATHS = $(inherited) "${PODS_CONFIGURATION_BUILD_DIR}/SwiftyBeaver" 3 | GCC_PREPROCESSOR_DEFINITIONS = $(inherited) COCOAPODS=1 4 | HEADER_SEARCH_PATHS = $(inherited) "${PODS_CONFIGURATION_BUILD_DIR}/SwiftyBeaver/SwiftyBeaver.framework/Headers" 5 | LD_RUNPATH_SEARCH_PATHS = $(inherited) '@executable_path/Frameworks' '@loader_path/Frameworks' '@executable_path/../../Frameworks' 6 | OTHER_LDFLAGS = $(inherited) -framework "SwiftyBeaver" 7 | OTHER_SWIFT_FLAGS = $(inherited) -D COCOAPODS 8 | PODS_BUILD_DIR = ${BUILD_DIR} 9 | PODS_CONFIGURATION_BUILD_DIR = ${PODS_BUILD_DIR}/$(CONFIGURATION)$(EFFECTIVE_PLATFORM_NAME) 10 | PODS_PODFILE_DIR_PATH = ${SRCROOT}/. 11 | PODS_ROOT = ${SRCROOT}/Pods 12 | PODS_XCFRAMEWORKS_BUILD_DIR = $(PODS_CONFIGURATION_BUILD_DIR)/XCFrameworkIntermediates 13 | USE_RECURSIVE_SCRIPT_INPUTS_IN_SCRIPT_PHASES = YES 14 | -------------------------------------------------------------------------------- /Source/Pods/Target Support Files/SwiftyBeaver/SwiftyBeaver-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.9.6 19 | CFBundleSignature 20 | ???? 21 | CFBundleVersion 22 | ${CURRENT_PROJECT_VERSION} 23 | NSPrincipalClass 24 | 25 | 26 | 27 | -------------------------------------------------------------------------------- /Source/Pods/Target Support Files/SwiftyBeaver/SwiftyBeaver-dummy.m: -------------------------------------------------------------------------------- 1 | #import 2 | @interface PodsDummy_SwiftyBeaver : NSObject 3 | @end 4 | @implementation PodsDummy_SwiftyBeaver 5 | @end 6 | -------------------------------------------------------------------------------- /Source/Pods/Target Support Files/SwiftyBeaver/SwiftyBeaver-prefix.pch: -------------------------------------------------------------------------------- 1 | #ifdef __OBJC__ 2 | #import 3 | #else 4 | #ifndef FOUNDATION_EXPORT 5 | #if defined(__cplusplus) 6 | #define FOUNDATION_EXPORT extern "C" 7 | #else 8 | #define FOUNDATION_EXPORT extern 9 | #endif 10 | #endif 11 | #endif 12 | 13 | -------------------------------------------------------------------------------- /Source/Pods/Target Support Files/SwiftyBeaver/SwiftyBeaver-umbrella.h: -------------------------------------------------------------------------------- 1 | #ifdef __OBJC__ 2 | #import 3 | #else 4 | #ifndef FOUNDATION_EXPORT 5 | #if defined(__cplusplus) 6 | #define FOUNDATION_EXPORT extern "C" 7 | #else 8 | #define FOUNDATION_EXPORT extern 9 | #endif 10 | #endif 11 | #endif 12 | 13 | 14 | FOUNDATION_EXPORT double SwiftyBeaverVersionNumber; 15 | FOUNDATION_EXPORT const unsigned char SwiftyBeaverVersionString[]; 16 | 17 | -------------------------------------------------------------------------------- /Source/Pods/Target Support Files/SwiftyBeaver/SwiftyBeaver.debug.xcconfig: -------------------------------------------------------------------------------- 1 | APPLICATION_EXTENSION_API_ONLY = YES 2 | CLANG_WARN_QUOTED_INCLUDE_IN_FRAMEWORK_HEADER = NO 3 | CONFIGURATION_BUILD_DIR = ${PODS_CONFIGURATION_BUILD_DIR}/SwiftyBeaver 4 | GCC_PREPROCESSOR_DEFINITIONS = $(inherited) COCOAPODS=1 5 | OTHER_SWIFT_FLAGS = $(inherited) -D COCOAPODS 6 | PODS_BUILD_DIR = ${BUILD_DIR} 7 | PODS_CONFIGURATION_BUILD_DIR = ${PODS_BUILD_DIR}/$(CONFIGURATION)$(EFFECTIVE_PLATFORM_NAME) 8 | PODS_ROOT = ${SRCROOT} 9 | PODS_TARGET_SRCROOT = ${PODS_ROOT}/SwiftyBeaver 10 | PODS_XCFRAMEWORKS_BUILD_DIR = $(PODS_CONFIGURATION_BUILD_DIR)/XCFrameworkIntermediates 11 | PRODUCT_BUNDLE_IDENTIFIER = org.cocoapods.${PRODUCT_NAME:rfc1034identifier} 12 | SKIP_INSTALL = YES 13 | USE_RECURSIVE_SCRIPT_INPUTS_IN_SCRIPT_PHASES = YES 14 | -------------------------------------------------------------------------------- /Source/Pods/Target Support Files/SwiftyBeaver/SwiftyBeaver.modulemap: -------------------------------------------------------------------------------- 1 | framework module SwiftyBeaver { 2 | umbrella header "SwiftyBeaver-umbrella.h" 3 | 4 | export * 5 | module * { export * } 6 | } 7 | -------------------------------------------------------------------------------- /Source/Pods/Target Support Files/SwiftyBeaver/SwiftyBeaver.release.xcconfig: -------------------------------------------------------------------------------- 1 | APPLICATION_EXTENSION_API_ONLY = YES 2 | CLANG_WARN_QUOTED_INCLUDE_IN_FRAMEWORK_HEADER = NO 3 | CONFIGURATION_BUILD_DIR = ${PODS_CONFIGURATION_BUILD_DIR}/SwiftyBeaver 4 | GCC_PREPROCESSOR_DEFINITIONS = $(inherited) COCOAPODS=1 5 | OTHER_SWIFT_FLAGS = $(inherited) -D COCOAPODS 6 | PODS_BUILD_DIR = ${BUILD_DIR} 7 | PODS_CONFIGURATION_BUILD_DIR = ${PODS_BUILD_DIR}/$(CONFIGURATION)$(EFFECTIVE_PLATFORM_NAME) 8 | PODS_ROOT = ${SRCROOT} 9 | PODS_TARGET_SRCROOT = ${PODS_ROOT}/SwiftyBeaver 10 | PODS_XCFRAMEWORKS_BUILD_DIR = $(PODS_CONFIGURATION_BUILD_DIR)/XCFrameworkIntermediates 11 | PRODUCT_BUNDLE_IDENTIFIER = org.cocoapods.${PRODUCT_NAME:rfc1034identifier} 12 | SKIP_INSTALL = YES 13 | USE_RECURSIVE_SCRIPT_INPUTS_IN_SCRIPT_PHASES = YES 14 | -------------------------------------------------------------------------------- /Source/Pods/Target Support Files/SwiftyBeaver/SwiftyBeaver.xcconfig: -------------------------------------------------------------------------------- 1 | APPLICATION_EXTENSION_API_ONLY = YES 2 | CONFIGURATION_BUILD_DIR = ${PODS_CONFIGURATION_BUILD_DIR}/SwiftyBeaver 3 | GCC_PREPROCESSOR_DEFINITIONS = $(inherited) COCOAPODS=1 4 | OTHER_SWIFT_FLAGS = $(inherited) -D COCOAPODS 5 | PODS_BUILD_DIR = ${BUILD_DIR} 6 | PODS_CONFIGURATION_BUILD_DIR = ${PODS_BUILD_DIR}/$(CONFIGURATION)$(EFFECTIVE_PLATFORM_NAME) 7 | PODS_ROOT = ${SRCROOT} 8 | PODS_TARGET_SRCROOT = ${PODS_ROOT}/SwiftyBeaver 9 | PRODUCT_BUNDLE_IDENTIFIER = org.cocoapods.${PRODUCT_NAME:rfc1034identifier} 10 | SKIP_INSTALL = YES 11 | USE_RECURSIVE_SCRIPT_INPUTS_IN_SCRIPT_PHASES = YES 12 | -------------------------------------------------------------------------------- /Source/TriangleDraw.xcodeproj/project.xcworkspace/contents.xcworkspacedata: -------------------------------------------------------------------------------- 1 | 2 | 4 | 6 | 7 | 8 | -------------------------------------------------------------------------------- /Source/TriangleDraw.xcworkspace/contents.xcworkspacedata: -------------------------------------------------------------------------------- 1 | 2 | 4 | 6 | 7 | 9 | 10 | 11 | -------------------------------------------------------------------------------- /Source/TriangleDraw.xcworkspace/xcshareddata/IDEWorkspaceChecks.plist: -------------------------------------------------------------------------------- 1 | 2 | 3 | 4 | 5 | IDEDidComputeMac32BitWarning 6 | 7 | 8 | 9 | -------------------------------------------------------------------------------- /Source/TriangleDraw.xcworkspace/xcshareddata/WorkspaceSettings.xcsettings: -------------------------------------------------------------------------------- 1 | 2 | 3 | 4 | 5 | PreviewsEnabled 6 | 7 | 8 | 9 | -------------------------------------------------------------------------------- /Source/TriangleDraw.xcworkspace/xcshareddata/swiftpm/Package.resolved: -------------------------------------------------------------------------------- 1 | { 2 | "pins" : [ 3 | { 4 | "identity" : "swiftui-visual-effects", 5 | "kind" : "remoteSourceControl", 6 | "location" : "https://github.com/lucasbrown/swiftui-visual-effects.git", 7 | "state" : { 8 | "revision" : "b26f8cebd55ff60ed8953768aa818dfb005b5838", 9 | "version" : "1.0.3" 10 | } 11 | }, 12 | { 13 | "identity" : "ttprogresshud", 14 | "kind" : "remoteSourceControl", 15 | "location" : "https://github.com/honkmaster/TTProgressHUD", 16 | "state" : { 17 | "revision" : "9059a560a66b6b8dc27a441af5831e51ce741f84" 18 | } 19 | } 20 | ], 21 | "version" : 2 22 | } 23 | -------------------------------------------------------------------------------- /Source/TriangleDrawLibrary/Core/TriangleDrawFrameworkMeta.swift: -------------------------------------------------------------------------------- 1 | // MIT license. Copyright (c) 2023 TriangleDraw. All rights reserved. 2 | import UIKit 3 | 4 | public class TriangleDrawFrameworkMeta { 5 | public let bundle: Bundle 6 | 7 | public init() { 8 | let bundleUrl: URL = Bundle.main.bundleURL 9 | let bundlePathExtension: String = bundleUrl.pathExtension 10 | // log.debug("bundleUrl: \(bundleUrl)\npathExtension: \(bundlePathExtension)") 11 | 12 | // `true` when invoked inside the `Thumbnail process` 13 | // `false` when invoked inside the `Main process` 14 | let isAppex: Bool = bundlePathExtension == "appex" 15 | 16 | if isAppex { 17 | self.bundle = Bundle.main 18 | return 19 | } 20 | 21 | self.bundle = Bundle.main 22 | } 23 | 24 | public var urlHexagonMask: URL { 25 | let resourceName = "hexagon_mask" 26 | guard let url: URL = self.bundle.url(forResource: resourceName, withExtension: "txt") else { 27 | log.error("no url for resource: \(resourceName)") 28 | fatalError("no url for resource: \(resourceName)") 29 | } 30 | return url 31 | } 32 | } 33 | -------------------------------------------------------------------------------- /Source/TriangleDrawLibrary/Core/UserDefaults+AppGroup.swift: -------------------------------------------------------------------------------- 1 | // MIT license. Copyright (c) 2023 TriangleDraw. All rights reserved. 2 | import Foundation 3 | 4 | extension UserDefaults { 5 | 6 | // swiftlint:disable:next identifier_name 7 | public static var td_appGroup: UserDefaults { 8 | guard let userDefault: UserDefaults = UserDefaults(suiteName: AppConstant.AppGroup.id) else { 9 | fatalError("Expected UserDefaults with suiteName for the AppGroup, but got nil") 10 | } 11 | return userDefault 12 | } 13 | 14 | } 15 | -------------------------------------------------------------------------------- /Source/TriangleDrawLibrary/Core/VerboseInfoProvider.swift: -------------------------------------------------------------------------------- 1 | // MIT license. Copyright (c) 2023 TriangleDraw. All rights reserved. 2 | 3 | public class VerboseInfoProvider { 4 | public typealias Pair = (String, String) 5 | public var pairs = [Pair]() 6 | 7 | public init() {} 8 | 9 | public func append(_ key: String, _ value: String) { 10 | pairs.append((key, value)) 11 | } 12 | } 13 | 14 | public protocol AcceptsVerboseInfoProvider { 15 | func verboseInfo(_ provider: VerboseInfoProvider) 16 | } 17 | -------------------------------------------------------------------------------- /Source/TriangleDrawLibrary/Engine/CGSize+OptimalTileCount.swift: -------------------------------------------------------------------------------- 1 | // MIT license. Copyright (c) 2023 TriangleDraw. All rights reserved. 2 | import Foundation 3 | import CoreGraphics 4 | 5 | extension CGSize { 6 | public func triangleDraw_findOptimalTileCount(clampN: UInt) -> UInt { 7 | var n: UInt = 1 8 | while true { 9 | let nextN = n * 2 10 | 11 | func tooSmallValue(_ value: CGFloat) -> Bool { 12 | let valueDividedByNextN: CGFloat = value / CGFloat(nextN) 13 | return valueDividedByNextN < 4.1 14 | } 15 | 16 | if tooSmallValue(self.width) || tooSmallValue(self.height) { 17 | return n 18 | } 19 | 20 | func hasRemainder(_ value: CGFloat) -> Bool { 21 | let valueDividedByNextN: CGFloat = value / CGFloat(nextN) 22 | let remainder: CGFloat = abs(fmod(valueDividedByNextN, 1.0)) 23 | return remainder > 0.00001 24 | } 25 | 26 | if hasRemainder(self.width) || hasRemainder(self.height) { 27 | return n 28 | } 29 | 30 | n = nextN 31 | guard n < clampN else { 32 | return clampN 33 | } 34 | } 35 | } 36 | } 37 | -------------------------------------------------------------------------------- /Source/TriangleDrawLibrary/Engine/E2Canvas+Coordinates.swift: -------------------------------------------------------------------------------- 1 | // MIT license. Copyright (c) 2023 TriangleDraw. All rights reserved. 2 | import CoreGraphics 3 | 4 | extension E2Canvas { 5 | public func coordinates() -> [CGPoint] { 6 | let w = self.size.width 7 | let h = self.size.height 8 | var points = [CGPoint]() 9 | for y in 0...h { 10 | for x in 0...w { 11 | var xx = CGFloat(x) 12 | xx -= (y & 1) != 0 ? 0.0 : 0.5 13 | xx += 0.5 14 | let px = (xx / CGFloat(w)) * 2.0 - 1.0 15 | let py = (CGFloat(h - y) / CGFloat(h)) * 2.0 - 1.0 16 | points.append(CGPoint(x: px, y: py)) 17 | } 18 | } 19 | return points 20 | } 21 | } 22 | -------------------------------------------------------------------------------- /Source/TriangleDrawLibrary/Engine/E2Canvas+CountDifferencies.swift: -------------------------------------------------------------------------------- 1 | // MIT license. Copyright (c) 2023 TriangleDraw. All rights reserved. 2 | extension E2Canvas { 3 | public func numberOfDifferences(from otherCanvas: E2Canvas) -> UInt { 4 | assert(otherCanvas.width == width) 5 | assert(otherCanvas.height == height) 6 | let cd0: E2Canvas = self 7 | let cd1: E2Canvas = otherCanvas 8 | assert(cd0.cellsPerColumn == cd1.cellsPerColumn) 9 | assert(cd0.cellsPerRow == cd1.cellsPerRow) 10 | var count: UInt = 0 11 | for j in 0.. Bool { 6 | if lhs === rhs { 7 | return true 8 | } 9 | guard lhs.size.width == rhs.size.width else { 10 | return false 11 | } 12 | guard lhs.size.height == rhs.size.height else { 13 | return false 14 | } 15 | guard lhs.cellsPerColumn == rhs.cellsPerColumn else { 16 | return false 17 | } 18 | guard lhs.cellsPerRow == rhs.cellsPerRow else { 19 | return false 20 | } 21 | guard lhs.cells == rhs.cells else { 22 | return false 23 | } 24 | return true 25 | } 26 | } 27 | -------------------------------------------------------------------------------- /Source/TriangleDrawLibrary/Engine/E2Canvas+GetPixel.swift: -------------------------------------------------------------------------------- 1 | // MIT license. Copyright (c) 2023 TriangleDraw. All rights reserved. 2 | import Foundation 3 | 4 | extension E2Canvas { 5 | public func getPixel(_ point: E2CanvasPoint) -> UInt8 { 6 | return self.inner_getPixel(point: point) 7 | } 8 | 9 | public func getPixelX(_ x: Int, y: Int) -> UInt8 { 10 | let point = E2CanvasPoint(x: x, y: y) 11 | return getPixel(point) 12 | } 13 | 14 | public func inner_getPixel(point: E2CanvasPoint) -> UInt8 { 15 | let x = point.x 16 | let y = point.y 17 | let x2: Int = x / 2 18 | let y2: Int = y / 2 19 | let w = Int(self.cellsPerRow) 20 | let h = Int(self.cellsPerColumn) 21 | if x2 < 0 || y2 < 0 { 22 | return 0 23 | } 24 | if x2 >= w || y2 >= h { 25 | return 0 26 | } 27 | let offset = y2 * w + x2 28 | let cell: E2TriangleCell = self.cells[offset] 29 | if y & 1 != 0 { 30 | if x & 1 != 0 { 31 | return cell.br 32 | } else { 33 | return cell.bl 34 | } 35 | } else { 36 | if x & 1 != 0 { 37 | return cell.tr 38 | } else { 39 | return cell.tl 40 | } 41 | } 42 | } 43 | } 44 | -------------------------------------------------------------------------------- /Source/TriangleDrawLibrary/Engine/E2Canvas+Histogram.swift: -------------------------------------------------------------------------------- 1 | // MIT license. Copyright (c) 2023 TriangleDraw. All rights reserved. 2 | 3 | extension E2Canvas { 4 | public typealias HistogramResult = [UInt8: UInt] 5 | 6 | /// Count the number of times a pixel value occurs inside the masked area 7 | public func histogram() -> HistogramResult { 8 | assert(self.size.width == AppConstant.CanvasFileFormat.width, "width") 9 | assert(self.size.height == AppConstant.CanvasFileFormat.height, "height") 10 | let mask: E2Canvas = E2Canvas.bigCanvasMask() 11 | var counters = [UInt](repeating: 0, count: 256) 12 | for j: UInt in 0.. 0 { 29 | result[key] = counterValue 30 | } 31 | } 32 | return result 33 | } 34 | } 35 | -------------------------------------------------------------------------------- /Source/TriangleDrawLibrary/Engine/E2Canvas+Line.swift: -------------------------------------------------------------------------------- 1 | // MIT license. Copyright (c) 2023 TriangleDraw. All rights reserved. 2 | import CoreGraphics 3 | 4 | extension E2Canvas { 5 | public func line(from point0: CGPoint, to point1: CGPoint, value: UInt8) { 6 | var x0 = Int(Double(point0.x) * Double(100000.0)) 7 | var y0 = Int(Double(point0.y) * Double(100000.0)) 8 | let x1 = Int(Double(point1.x) * Double(100000.0)) 9 | let y1 = Int(Double(point1.y) * Double(100000.0)) 10 | let dx: Int = abs(x1 - x0) 11 | let sx: Int = x0 < x1 ? 1 : -1 12 | let dy: Int = abs(y1 - y0) 13 | let sy: Int = y0 < y1 ? 1 : -1 14 | var err: Int = (dx > dy ? dx : -dy) / 2 15 | var lastPoint: E2CanvasPoint = self.E2CanvasPoint_from_CGPoint(CGPoint(x: Double(x0) * Double(0.00001), y: Double(y0) * Double(0.00001))) 16 | setSymmetricPixel(lastPoint, value: value, symmetryMode: globalSymmetryMode) 17 | 18 | while true { 19 | let point: E2CanvasPoint = self.E2CanvasPoint_from_CGPoint(CGPoint(x: Double(x0) * Double(0.00001), y: Double(y0) * Double(0.00001))) 20 | let same: Bool = (point.x == lastPoint.x) && (point.y == lastPoint.y) 21 | if !same { 22 | setSymmetricPixel(point, value: value, symmetryMode: globalSymmetryMode) 23 | } 24 | lastPoint = point 25 | if x0 == x1 && y0 == y1 { 26 | break 27 | } 28 | let e2: Int = err 29 | if e2 > -dx { 30 | err -= dy 31 | x0 += sx 32 | } 33 | if e2 < dy { 34 | err += dx 35 | y0 += sy 36 | } 37 | } 38 | } 39 | } 40 | -------------------------------------------------------------------------------- /Source/TriangleDrawLibrary/Engine/E2Canvas+Move.swift: -------------------------------------------------------------------------------- 1 | // MIT license. Copyright (c) 2023 TriangleDraw. All rights reserved. 2 | extension E2Canvas { 3 | public func moveRight() { 4 | moveOperation(.right) 5 | } 6 | 7 | public func moveLeft() { 8 | moveOperation(.left) 9 | } 10 | 11 | public func moveUp() { 12 | moveOperation(.up) 13 | } 14 | 15 | public func moveDown() { 16 | moveOperation(.down) 17 | } 18 | 19 | private func moveOperation(_ operation: E2CanvasMoveOperation) { 20 | let (ox, oy) = operation.offset 21 | let orig: E2Canvas = self.createCopy() 22 | let w = Int(self.cellsPerRow) 23 | let h = Int(self.cellsPerColumn) 24 | for j in 0..= w || y2 >= h { 31 | return 32 | } 33 | let offset = y2 * w + x2 34 | if y & 1 != 0 { 35 | if x & 1 != 0 { 36 | self.cells[offset].br = resultValue 37 | } else { 38 | self.cells[offset].bl = resultValue 39 | } 40 | } else { 41 | if x & 1 != 0 { 42 | self.cells[offset].tr = resultValue 43 | } else { 44 | self.cells[offset].tl = resultValue 45 | } 46 | } 47 | } 48 | } 49 | -------------------------------------------------------------------------------- /Source/TriangleDrawLibrary/Engine/E2Canvas+Triangles.swift: -------------------------------------------------------------------------------- 1 | // MIT license. Copyright (c) 2023 TriangleDraw. All rights reserved. 2 | import Foundation 3 | 4 | extension E2Canvas { 5 | public func convertToTriangles() -> [E2CanvasTriangle2] { 6 | // return _convertToTriangles(debug: true) 7 | return _convertToTriangles(debug: false) 8 | } 9 | 10 | // swiftlint:disable:next identifier_name 11 | public func _convertToTriangles(debug: Bool) -> [E2CanvasTriangle2] { 12 | var triangleArray = [E2CanvasTriangle2]() 13 | 14 | func append(value: UInt8, a: IntVec2, b: IntVec2, c: IntVec2) { 15 | var finalValue: UInt8 = value 16 | if debug { 17 | if (a.x + a.y) % 5 == 0 { 18 | finalValue = 2 19 | } 20 | } 21 | let triangle = E2CanvasTriangle2(value: finalValue, a: a, b: b, c: c) 22 | triangleArray.append(triangle) 23 | } 24 | 25 | // swiftlint:disable:next function_parameter_count 26 | func append(_ value: UInt8, _ xy: IntVec2, _ x0: Int32, _ y0: Int32, _ x1: Int32, _ y1: Int32, _ x2: Int32, _ y2: Int32) { 27 | append( 28 | value: value, 29 | a: xy.offsetBy(dx: x0, dy: y0), 30 | b: xy.offsetBy(dx: x1, dy: y1), 31 | c: xy.offsetBy(dx: x2, dy: y2) 32 | ) 33 | } 34 | 35 | let w: Int = Int(self.cellsPerRow) 36 | let h: Int = Int(self.cellsPerColumn) 37 | for j in 0.. E2CanvasPoint { 16 | return E2CanvasPoint(x: self.x + x, y: self.y + y) 17 | } 18 | } 19 | 20 | extension E2CanvasPoint: Equatable { 21 | public static func == (lhs: E2CanvasPoint, rhs: E2CanvasPoint) -> Bool { 22 | // swiftlint:disable:next identifier_name 23 | let same_x: Bool = lhs.x == rhs.x 24 | // swiftlint:disable:next identifier_name 25 | let same_y: Bool = lhs.y == rhs.y 26 | return same_x && same_y 27 | } 28 | } 29 | 30 | extension E2CanvasPoint { 31 | public func flipX(size: E2CanvasSize) -> E2CanvasPoint { 32 | return E2CanvasPoint(x: Int(size.width * 2 - 2) - self.x, y: self.y) 33 | } 34 | 35 | public func flipY(size: E2CanvasSize) -> E2CanvasPoint { 36 | return E2CanvasPoint(x: self.x, y: Int(size.height - 1) - self.y) 37 | } 38 | } 39 | -------------------------------------------------------------------------------- /Source/TriangleDrawLibrary/Engine/E2CanvasSize.swift: -------------------------------------------------------------------------------- 1 | // MIT license. Copyright (c) 2023 TriangleDraw. All rights reserved. 2 | import Foundation 3 | 4 | public struct E2CanvasSize { 5 | public let width: UInt 6 | public let height: UInt 7 | 8 | public init(width: UInt, height: UInt) { 9 | self.width = width 10 | self.height = height 11 | } 12 | } 13 | -------------------------------------------------------------------------------- /Source/TriangleDrawLibrary/Engine/E2CanvasTriangle.swift: -------------------------------------------------------------------------------- 1 | // MIT license. Copyright (c) 2023 TriangleDraw. All rights reserved. 2 | import Foundation 3 | 4 | public class E2CanvasTriangle { 5 | public let x0: Int 6 | public let y0: Int 7 | public let x1: Int 8 | public let y1: Int 9 | public let x2: Int 10 | public let y2: Int 11 | 12 | public init(x0: Int, y0: Int, x1: Int, y1: Int, x2: Int, y2: Int) { 13 | self.x0 = x0 14 | self.y0 = y0 15 | self.x1 = x1 16 | self.y1 = y1 17 | self.x2 = x2 18 | self.y2 = y2 19 | } 20 | } 21 | 22 | extension E2CanvasTriangle: CustomStringConvertible { 23 | public var description: String { 24 | return "E2CanvasTriangle(\(x0) \(y0), \(x1) \(y1), \(x2) \(y2))" 25 | } 26 | } 27 | 28 | public struct E2CanvasTriangle2 { 29 | public var value: UInt8 30 | public var a: IntVec2 31 | public var b: IntVec2 32 | public var c: IntVec2 33 | } 34 | 35 | extension E2CanvasTriangle2 { 36 | /// Remove all triangles that are outside the hexagon mask. 37 | /// 38 | /// The typical values are `0` and `1` and have been assigned by the user. 39 | /// 40 | /// However there is a special value of `255` indicates that it's a triangle outside the hexagon mask. 41 | public static func onlyTrianglesInsideTheHexagon(_ triangles: [E2CanvasTriangle2]) -> [E2CanvasTriangle2] { 42 | return triangles.filter { $0.value != 255 } 43 | } 44 | } 45 | -------------------------------------------------------------------------------- /Source/TriangleDrawLibrary/Engine/E2TriangleCell.swift: -------------------------------------------------------------------------------- 1 | // MIT license. Copyright (c) 2023 TriangleDraw. All rights reserved. 2 | import Foundation 3 | 4 | /* 5 | An E2TriangleCell represent 4 triangles. 6 | 7 | tl = top left 8 | tr = top right 9 | bl = bottom left 10 | br = bottom right 11 | 12 | ******************** 13 | * * * 14 | * tl * * 15 | * * tr * 16 | * * * 17 | ********************* 18 | * * br * 19 | * * * 20 | * bl * * 21 | * * * 22 | ******************** 23 | 24 | */ 25 | // swiftlint:disable identifier_name 26 | public struct E2TriangleCell { 27 | public var tl: UInt8 = 0 28 | public var tr: UInt8 = 0 29 | public var bl: UInt8 = 0 30 | public var br: UInt8 = 0 31 | } 32 | 33 | extension E2TriangleCell: Equatable { 34 | public static func == (lhs: E2TriangleCell, rhs: E2TriangleCell) -> Bool { 35 | let same_tl: Bool = lhs.tl == rhs.tl 36 | let same_tr: Bool = lhs.tr == rhs.tr 37 | let same_bl: Bool = lhs.bl == rhs.bl 38 | let same_br: Bool = lhs.br == rhs.br 39 | return same_tl && same_tr && same_bl && same_br 40 | } 41 | } 42 | -------------------------------------------------------------------------------- /Source/TriangleDrawLibrary/Engine/UIColor+Image.swift: -------------------------------------------------------------------------------- 1 | // MIT license. Copyright (c) 2023 TriangleDraw. All rights reserved. 2 | import UIKit 3 | 4 | extension UIColor { 5 | public func image(_ size: CGSize = CGSize(width: 1, height: 1)) -> UIImage { 6 | return UIGraphicsImageRenderer(size: size).image { rendererContext in 7 | self.setFill() 8 | rendererContext.fill(CGRect(origin: .zero, size: size)) 9 | } 10 | } 11 | } 12 | -------------------------------------------------------------------------------- /Source/TriangleDrawLibrary/Engine/UIImage+ScaleToSize.swift: -------------------------------------------------------------------------------- 1 | // MIT license. Copyright (c) 2023 TriangleDraw. All rights reserved. 2 | import UIKit 3 | 4 | extension UIImage { 5 | func imageScaled(toExactSize newSize: CGSize) -> UIImage? { 6 | UIGraphicsBeginImageContextWithOptions(newSize, false, 1.0) 7 | guard let context: CGContext = UIGraphicsGetCurrentContext() else { 8 | log.error("Expected UIGraphicsGetCurrentContext() to non-nil CGContext, but got nil") 9 | return nil 10 | } 11 | context.interpolationQuality = .medium 12 | draw(in: CGRect(x: 0, y: 0, width: newSize.width, height: newSize.height)) 13 | let newImage: UIImage? = UIGraphicsGetImageFromCurrentImageContext() 14 | UIGraphicsEndImageContext() 15 | return newImage 16 | } 17 | } 18 | -------------------------------------------------------------------------------- /Source/TriangleDrawLibrary/Engine/URL+DisplayName.swift: -------------------------------------------------------------------------------- 1 | // MIT license. Copyright (c) 2023 TriangleDraw. All rights reserved. 2 | import Foundation 3 | 4 | // swiftlint:disable identifier_name 5 | extension URL { 6 | /// From a long url like 7 | /// 8 | /// file:///var/mobile/Containers/Data/Application/1FB629DF-2E96-4047-BF06-373BB57A1965/Documents/Mona%20Lisa.triangleDraw/ 9 | /// 10 | /// It only returns the string `Mona Lisa` 11 | /// 12 | /// Nowadays it's common to use Emoji's inside filenames, like this: 13 | /// 14 | /// file:///var/mobile/Containers/Data/Application/1FB629DF-2E96-4047-BF06-373BB57A1965/Documents/%F0%9F%87%B0%F0%9F%87%AA.triangleDraw/ 15 | /// 16 | /// It only returns the string `🇰🇪` 17 | public var triangleDraw_displayName: String { 18 | let percentEncodedString: String = self.deletingPathExtension().lastPathComponent 19 | guard let decodedString: String = percentEncodedString.removingPercentEncoding else { 20 | log.error("Unable to removingPercentEncoding from string: '\(percentEncodedString)'") 21 | return percentEncodedString 22 | } 23 | return decodedString 24 | } 25 | } 26 | -------------------------------------------------------------------------------- /Source/TriangleDrawLibrary/Foundation/CGPoint.swift: -------------------------------------------------------------------------------- 1 | // MIT license. Copyright (c) 2023 TriangleDraw. All rights reserved. 2 | import CoreGraphics 3 | 4 | // swiftlint:disable identifier_name 5 | extension CGPoint { 6 | public var flip: CGPoint { 7 | return CGPoint(x: -x, y: -y) 8 | } 9 | 10 | public var flipY: CGPoint { 11 | return CGPoint(x: x, y: -y) 12 | } 13 | 14 | public func offset(_ x: CGFloat, _ y: CGFloat) -> CGPoint { 15 | return CGPoint(x: self.x + x, y: self.y + y) 16 | } 17 | 18 | public func offsetX(_ x: CGFloat) -> CGPoint { 19 | return CGPoint(x: self.x + x, y: self.y) 20 | } 21 | 22 | public func offsetY(_ y: CGFloat) -> CGPoint { 23 | return CGPoint(x: self.x, y: self.y + y) 24 | } 25 | 26 | public func offset(_ point: CGPoint) -> CGPoint { 27 | return CGPoint(x: self.x + point.x, y: self.y + point.y) 28 | } 29 | 30 | public func scaleBy(_ scale: CGFloat) -> CGPoint { 31 | return CGPoint(x: self.x * scale, y: self.y * scale) 32 | } 33 | 34 | public func divideBy(_ amount: CGFloat) -> CGPoint { 35 | return CGPoint(x: self.x / amount, y: self.y / amount) 36 | } 37 | 38 | public var rounded: CGPoint { 39 | return CGPoint(x: round(self.x), y: round(self.y)) 40 | } 41 | 42 | public var lengthSquared: CGFloat { 43 | return x * x + y * y 44 | } 45 | 46 | public func scaleBy(_ scale: CGFloat, aroundPoint center: CGPoint) -> CGPoint { 47 | let x0 = x - center.x 48 | let x1 = x0 * scale 49 | let x2 = x1 + center.x 50 | let y0 = y - center.y 51 | let y1 = y0 * scale 52 | let y2 = y1 + center.y 53 | return CGPoint(x: x2, y: y2) 54 | } 55 | 56 | /// Round to nearest pixel, eg. 1/1, 1/2, 1/3 depending on retina mode 57 | public func alignToNearestPixel(_ screenScale: Int) -> CGPoint { 58 | let scale = CGFloat(screenScale) 59 | let inv = 1 / scale 60 | 61 | let x = self.x * scale 62 | let rx = floor(x) 63 | let xx = rx * inv 64 | 65 | let y = self.y * scale 66 | let ry = floor(y) 67 | let yy = ry * inv 68 | return CGPoint(x: xx, y: yy) 69 | } 70 | } 71 | -------------------------------------------------------------------------------- /Source/TriangleDrawLibrary/Foundation/Date+iso8601.swift: -------------------------------------------------------------------------------- 1 | // MIT license. Copyright (c) 2023 TriangleDraw. All rights reserved. 2 | import Foundation 3 | 4 | extension Date { 5 | /// Returns strings like: `"1999-12-31T23:59:59Z"` 6 | public var iso8601: String { 7 | return ISO8601DateFormatter().string(from: self) 8 | } 9 | } 10 | -------------------------------------------------------------------------------- /Source/TriangleDrawLibrary/Foundation/String+Trim.swift: -------------------------------------------------------------------------------- 1 | // MIT license. Copyright (c) 2023 TriangleDraw. All rights reserved. 2 | import Foundation 3 | 4 | extension String { 5 | public func trim() -> String { 6 | return self.trimmingCharacters(in: CharacterSet.whitespacesAndNewlines) 7 | } 8 | } 9 | -------------------------------------------------------------------------------- /Source/TriangleDrawLibrary/Foundation/TDFloat.swift: -------------------------------------------------------------------------------- 1 | // MIT license. Copyright (c) 2023 TriangleDraw. All rights reserved. 2 | import simd 3 | 4 | #if swift(>=5.1) 5 | // Was introduced in Swift 5.1 and Xcode11.0 6 | public typealias TDFloat2 = SIMD2 7 | #else 8 | // Swift 5.0 and earlier 9 | public typealias TDFloat2 = float2 10 | #endif 11 | 12 | #if swift(>=5.1) 13 | // Was introduced in Swift 5.1 and Xcode11.0 14 | public typealias TDFloat3 = SIMD3 15 | #else 16 | // Swift 5.0 and earlier 17 | public typealias TDFloat3 = float3 18 | #endif 19 | 20 | #if swift(>=5.1) 21 | // Was introduced in Swift 5.1 and Xcode11.0 22 | public typealias TDFloat4 = SIMD4 23 | #else 24 | // Swift 5.0 and earlier 25 | public typealias TDFloat4 = float4 26 | #endif 27 | -------------------------------------------------------------------------------- /Source/TriangleDrawLibrary/ReadWrite/TDCanvasReader.swift: -------------------------------------------------------------------------------- 1 | // MIT license. Copyright (c) 2023 TriangleDraw. All rights reserved. 2 | import Foundation 3 | 4 | public class TDCanvasReader { 5 | public class func canvas(fromPBMRepresentation pbmRepresentation: Data?) throws -> E2Canvas { 6 | // Interpret the data as a .PBM file 7 | let model = try TDParsePBM.parse(pbmRepresentation) 8 | let width: Int = model.data.width 9 | let height: Int = model.data.height 10 | // Check that the dimensions corresponds to our canvas size 11 | let ok1: Bool = width == 180 12 | let ok2: Bool = height == 104 13 | // swiftlint:disable:next identifier_name 14 | let dimensions_ok: Bool = ok1 && ok2 15 | if !dimensions_ok { 16 | let messageFormat = NSLocalizedString("READ_FAILED_WRONG_DIMENSIONS_%d_%d", tableName: "ReadWrite", bundle: Bundle.main, value: "", comment: "Expected dimensions 180x104, but got {width}x{height}") 17 | let message = String(format: messageFormat, width, height) 18 | throw NSError(domain: "TDCanvasReader", code: 1, userInfo: [NSLocalizedDescriptionKey: message]) 19 | } 20 | // Transfer pixel data to canvas 21 | let canvas: E2Canvas = E2Canvas.createBigCanvas() 22 | for y in 0.. Data { 6 | let width: Int = Int(canvas.width) 7 | let height: Int = Int(canvas.height) 8 | var rows = [String]() 9 | rows.append("P1") 10 | rows.append("# {\"FileFormat\":3,\"ToolName\":\"TriangleDraw-iOS\",\"ToolVersion\":\"2023.11.1\"}") 11 | rows.append("\(width) \(height)") 12 | for y in 0..(_ value: T, _ minValue: T, _ maxValue: T) -> T { 4 | if value <= minValue { 5 | return minValue 6 | } 7 | if value >= maxValue { 8 | return maxValue 9 | } 10 | return value 11 | } 12 | -------------------------------------------------------------------------------- /Source/TriangleDrawLibrary/math/FloatFormatting.swift: -------------------------------------------------------------------------------- 1 | // MIT license. Copyright (c) 2023 TriangleDraw. All rights reserved. 2 | import Foundation 3 | import CoreGraphics 4 | 5 | extension CGFloat { 6 | public var string0: String { 7 | return String(format: "%.0f", self) 8 | } 9 | public var string1: String { 10 | return String(format: "%.1f", self) 11 | } 12 | public var string2: String { 13 | return String(format: "%.2f", self) 14 | } 15 | } 16 | 17 | extension Float { 18 | public var string0: String { 19 | return String(format: "%.0f", self) 20 | } 21 | public var string1: String { 22 | return String(format: "%.1f", self) 23 | } 24 | public var string2: String { 25 | return String(format: "%.2f", self) 26 | } 27 | } 28 | 29 | extension Double { 30 | public var string0: String { 31 | return String(format: "%.0f", self) 32 | } 33 | public var string1: String { 34 | return String(format: "%.1f", self) 35 | } 36 | public var string2: String { 37 | return String(format: "%.2f", self) 38 | } 39 | } 40 | 41 | extension CGPoint { 42 | public var string0: String { 43 | return "(\(self.x.string0), \(self.y.string0))" 44 | } 45 | public var string1: String { 46 | return "(\(self.x.string1), \(self.y.string1))" 47 | } 48 | public var string2: String { 49 | return "(\(self.x.string2), \(self.y.string2))" 50 | } 51 | } 52 | 53 | extension CGSize { 54 | public var string0: String { 55 | return "(\(self.width.string0), \(self.height.string0))" 56 | } 57 | public var string1: String { 58 | return "(\(self.width.string1), \(self.height.string1))" 59 | } 60 | public var string2: String { 61 | return "(\(self.width.string2), \(self.height.string2))" 62 | } 63 | } 64 | -------------------------------------------------------------------------------- /Source/TriangleDrawLibrary/math/Remap.swift: -------------------------------------------------------------------------------- 1 | // MIT license. Copyright (c) 2023 TriangleDraw. All rights reserved. 2 | 3 | // swiftlint:disable:next identifier_name 4 | public func remap(_ value: T, _ a: T, _ b: T, _ c: T, _ d: T) -> T { 5 | return c + (d - c) * (value - a) / (b - a) 6 | } 7 | -------------------------------------------------------------------------------- /Source/TriangleDrawMain/Browser/BrowserMenuViewController.swift: -------------------------------------------------------------------------------- 1 | // MIT license. Copyright (c) 2023 TriangleDraw. All rights reserved. 2 | import UIKit 3 | import SwiftUI 4 | 5 | struct BrowserMenuViewController { 6 | static func createInsideNavigationController() -> UIViewController { 7 | let model = BrowserMenuViewModel.create() 8 | return UIHostingController(rootView: BrowserMenuView(model: model)) 9 | } 10 | } 11 | -------------------------------------------------------------------------------- /Source/TriangleDrawMain/Browser/BrowserMenuViewModel.swift: -------------------------------------------------------------------------------- 1 | // MIT license. Copyright (c) 2023 TriangleDraw. All rights reserved. 2 | import Foundation 3 | import Combine 4 | import SwiftUI 5 | 6 | public class BrowserMenuViewModel: ObservableObject { 7 | @Published var appVersion: String = "x.y.z" 8 | @Published var appCreationDateString: String = "yyyy-mm-dd" 9 | @Published var appRunCount: String = "x" 10 | 11 | static func create() -> BrowserMenuViewModel { 12 | let runCount: Int = UserDefaults.standard.td_runCount() 13 | let instance = BrowserMenuViewModel() 14 | instance.appVersion = SystemInfo.appVersion 15 | instance.appCreationDateString = SystemInfo.creationDateStringShort 16 | instance.appRunCount = "\(runCount)" 17 | return instance 18 | } 19 | } 20 | -------------------------------------------------------------------------------- /Source/TriangleDrawMain/Browser/BrowserViewController+ImportDocumentExamples.swift: -------------------------------------------------------------------------------- 1 | // MIT license. Copyright (c) 2023 TriangleDraw. All rights reserved. 2 | import Foundation 3 | import TriangleDrawLibrary 4 | 5 | extension BrowserViewController { 6 | func importDocumentExamples() { 7 | func fileExist(_ url: URL) -> Bool { 8 | do { 9 | return try url.checkResourceIsReachable() 10 | } catch { 11 | return false 12 | } 13 | } 14 | 15 | let fm = FileManager.default 16 | guard let appUrl: URL = fm.urls(for: .documentDirectory, in: .userDomainMask).last else { 17 | log.error("Expected url to documentDirectory, but got nil.") 18 | return 19 | } 20 | 21 | func importDocument(documentExample: DocumentExample, displayName: String, documentDate: Date) { 22 | let source: URL = documentExample.url 23 | let dest: URL = appUrl.appendingPathComponent(displayName).appendingPathExtension("triangleDraw") 24 | do { 25 | if fileExist(dest) { 26 | try fm.removeItem(at: dest) 27 | } 28 | 29 | try fm.copyItem(at: source, to: dest) 30 | 31 | var attr = [FileAttributeKey: Any]() 32 | attr[FileAttributeKey.modificationDate] = documentDate 33 | try fm.setAttributes(attr, ofItemAtPath: dest.path) 34 | 35 | log.debug("successfully created file at: \(dest)") 36 | } catch { 37 | log.error("Failed to create file at: \(dest). Error: \(error)") 38 | } 39 | } 40 | 41 | let dateEinstein: Date = Date(timeIntervalSince1970: -2044742400) // 17mar1905 - Einstein 42 | let dateOrwell: Date = Date(timeIntervalSince1970: 441763200) // 01jan1984 - George Orwell 43 | let dateNow = Date() // Today 44 | 45 | importDocument( 46 | documentExample: DocumentExample.rune1, 47 | displayName: "Viking Symbol", 48 | documentDate: dateEinstein 49 | ) 50 | importDocument( 51 | documentExample: DocumentExample.injection, 52 | displayName: "Injection", 53 | documentDate: dateOrwell 54 | ) 55 | importDocument( 56 | documentExample: DocumentExample.triangledrawLogo, 57 | displayName: "Client Logo", 58 | documentDate: dateNow 59 | ) 60 | } 61 | } 62 | -------------------------------------------------------------------------------- /Source/TriangleDrawMain/Browser/BrowserViewController.storyboard: -------------------------------------------------------------------------------- 1 | 2 | 3 | 4 | 5 | 6 | 7 | 8 | 9 | 10 | 11 | 12 | 13 | 14 | 15 | 16 | 17 | 18 | 19 | 20 | 21 | 22 | 23 | 24 | 25 | 26 | 27 | 28 | -------------------------------------------------------------------------------- /Source/TriangleDrawMain/Browser/MailButtonView.swift: -------------------------------------------------------------------------------- 1 | // MIT license. Copyright (c) 2023 TriangleDraw. All rights reserved. 2 | import SwiftUI 3 | import MessageUI 4 | 5 | struct MailButtonView: View { 6 | let mailAttachmentData: Data? 7 | @State var result: Result? 8 | @State var isShowingMailView = false 9 | 10 | var body: some View { 11 | Button(action: { 12 | self.isShowingMailView.toggle() 13 | // swiftlint:disable:next multiple_closures_with_trailing_closure 14 | }) { 15 | Text("Email Developer") 16 | } 17 | .disabled(!MFMailComposeViewController.canSendMail()) 18 | .sheet(isPresented: $isShowingMailView) { 19 | MailView( 20 | result: self.$result, 21 | mailAttachmentData: self.mailAttachmentData 22 | ) 23 | } 24 | } 25 | } 26 | 27 | struct MailButtonView_Previews: PreviewProvider { 28 | static var previews: some View { 29 | MailButtonView( 30 | mailAttachmentData: nil 31 | ) 32 | } 33 | } 34 | -------------------------------------------------------------------------------- /Source/TriangleDrawMain/Canvas/Assets/da.lproj/CanvasVC.strings: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/triangledraw/TriangleDraw-iOS/25bc87c479cd10b461a17834b67d99d911f7cc34/Source/TriangleDrawMain/Canvas/Assets/da.lproj/CanvasVC.strings -------------------------------------------------------------------------------- /Source/TriangleDrawMain/Canvas/Assets/de.lproj/CanvasVC.strings: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/triangledraw/TriangleDraw-iOS/25bc87c479cd10b461a17834b67d99d911f7cc34/Source/TriangleDrawMain/Canvas/Assets/de.lproj/CanvasVC.strings -------------------------------------------------------------------------------- /Source/TriangleDrawMain/Canvas/Assets/en.lproj/CanvasVC.strings: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/triangledraw/TriangleDraw-iOS/25bc87c479cd10b461a17834b67d99d911f7cc34/Source/TriangleDrawMain/Canvas/Assets/en.lproj/CanvasVC.strings -------------------------------------------------------------------------------- /Source/TriangleDrawMain/Canvas/Assets/es.lproj/CanvasVC.strings: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/triangledraw/TriangleDraw-iOS/25bc87c479cd10b461a17834b67d99d911f7cc34/Source/TriangleDrawMain/Canvas/Assets/es.lproj/CanvasVC.strings -------------------------------------------------------------------------------- /Source/TriangleDrawMain/Canvas/Assets/fr.lproj/CanvasVC.strings: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/triangledraw/TriangleDraw-iOS/25bc87c479cd10b461a17834b67d99d911f7cc34/Source/TriangleDrawMain/Canvas/Assets/fr.lproj/CanvasVC.strings -------------------------------------------------------------------------------- /Source/TriangleDrawMain/Canvas/Assets/ja.lproj/CanvasVC.strings: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/triangledraw/TriangleDraw-iOS/25bc87c479cd10b461a17834b67d99d911f7cc34/Source/TriangleDrawMain/Canvas/Assets/ja.lproj/CanvasVC.strings -------------------------------------------------------------------------------- /Source/TriangleDrawMain/Canvas/Assets/pt_PT.lproj/CanvasVC.strings: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/triangledraw/TriangleDraw-iOS/25bc87c479cd10b461a17834b67d99d911f7cc34/Source/TriangleDrawMain/Canvas/Assets/pt_PT.lproj/CanvasVC.strings -------------------------------------------------------------------------------- /Source/TriangleDrawMain/Canvas/Assets/ru.lproj/CanvasVC.strings: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/triangledraw/TriangleDraw-iOS/25bc87c479cd10b461a17834b67d99d911f7cc34/Source/TriangleDrawMain/Canvas/Assets/ru.lproj/CanvasVC.strings -------------------------------------------------------------------------------- /Source/TriangleDrawMain/Canvas/Assets/zh_CN.lproj/CanvasVC.strings: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/triangledraw/TriangleDraw-iOS/25bc87c479cd10b461a17834b67d99d911f7cc34/Source/TriangleDrawMain/Canvas/Assets/zh_CN.lproj/CanvasVC.strings -------------------------------------------------------------------------------- /Source/TriangleDrawMain/Canvas/CanvasNavigationController.swift: -------------------------------------------------------------------------------- 1 | // MIT license. Copyright (c) 2023 TriangleDraw. All rights reserved. 2 | import UIKit 3 | 4 | /// Semitransparent with blurry background. 5 | class CanvasNavigationController: UINavigationController { 6 | 7 | func configure() { 8 | let appearance = UINavigationBarAppearance() 9 | appearance.configureWithTransparentBackground() 10 | appearance.backgroundColor = UIColor.clear 11 | appearance.backgroundEffect = UIBlurEffect(style: .dark) 12 | appearance.titleTextAttributes = [.foregroundColor: UIColor.white] 13 | appearance.largeTitleTextAttributes = [.foregroundColor: UIColor.white] 14 | self.navigationBar.standardAppearance = appearance 15 | self.navigationBar.scrollEdgeAppearance = appearance 16 | self.navigationBar.compactAppearance = appearance 17 | } 18 | 19 | override var preferredStatusBarStyle: UIStatusBarStyle { 20 | return .lightContent 21 | } 22 | } 23 | -------------------------------------------------------------------------------- /Source/TriangleDrawMain/Canvas/CanvasViewController+ConfigureHCView.swift: -------------------------------------------------------------------------------- 1 | // MIT license. Copyright (c) 2023 TriangleDraw. All rights reserved. 2 | import UIKit 3 | import TriangleDrawLibrary 4 | 5 | extension CanvasViewController { 6 | func configureHCView() { 7 | guard let view: TDCanvasDrawingView = self.hcView else { 8 | fatalError() 9 | } 10 | view.onTapBlock = { [weak self] canvasView, point in 11 | if let value = canvasView.canvas?.getPixel(point) { 12 | let toggledValue = (value > 0) ? 0 : 1 13 | self?.setPixel(point, value: UInt8(toggledValue)) 14 | } 15 | } 16 | view.onBeforeDrawBlock = { [weak self] in 17 | self?.beginDrawing() 18 | } 19 | view.onAfterDrawBlock = { [weak self] in 20 | self?.endDrawing() 21 | } 22 | // swiftlint:disable:next identifier_name 23 | var stroke_value: UInt8 = 0 24 | view.onDrawBlock = { [weak self] canvasView, cgPoint, point, gestureBegin in 25 | guard let strongSelf = self else { 26 | log.error("Expected self to be non-nil, but got nil") 27 | return 28 | } 29 | if gestureBegin { 30 | if let value = canvasView.canvas?.getPixel(point) { 31 | stroke_value = (value > 0) ? 0 : 1 32 | strongSelf.last_cgpoint = cgPoint 33 | } 34 | } 35 | strongSelf.line(from: cgPoint, to: strongSelf.last_cgpoint, value: stroke_value) 36 | strongSelf.last_cgpoint = cgPoint 37 | } 38 | 39 | self.drawingView = self.hcView 40 | } 41 | } 42 | -------------------------------------------------------------------------------- /Source/TriangleDrawMain/Canvas/CanvasViewController+ConfigureLeaveFullscreenButton.swift: -------------------------------------------------------------------------------- 1 | // MIT license. Copyright (c) 2023 TriangleDraw. All rights reserved. 2 | import UIKit 3 | 4 | extension CanvasViewController { 5 | func configureLeaveFullscreenButton() { 6 | leaveFullscreenButton.backgroundColor = self.view.tintColor 7 | leaveFullscreenButton.isHidden = true 8 | } 9 | } 10 | -------------------------------------------------------------------------------- /Source/TriangleDrawMain/Canvas/CanvasViewController+ConfigureToolbar.swift: -------------------------------------------------------------------------------- 1 | // MIT license. Copyright (c) 2023 TriangleDraw. All rights reserved. 2 | import UIKit 3 | 4 | extension CanvasViewController { 5 | func configureToolbar() { 6 | guard let toolbar: HCToolbar = self.hcToolbar else { 7 | fatalError() 8 | } 9 | let handlers = HCToolbarHandlers() 10 | handlers.onInvert = { [weak self] in 11 | self?.invertPixels() 12 | } 13 | handlers.onRotateCCW = { [weak self] in 14 | self?.rotateCCW() 15 | } 16 | handlers.onRotateCW = { [weak self] in 17 | self?.rotateCW() 18 | } 19 | handlers.onFlipX = { [weak self] in 20 | self?.flipX() 21 | } 22 | handlers.onFlipY = { [weak self] in 23 | self?.flipY() 24 | } 25 | handlers.onMoveLeft = { [weak self] in 26 | self?.moveLeft() 27 | } 28 | handlers.onMoveRight = { [weak self] in 29 | self?.moveRight() 30 | } 31 | handlers.onMoveUp = { [weak self] in 32 | self?.moveUp() 33 | } 34 | handlers.onMoveDown = { [weak self] in 35 | self?.moveDown() 36 | } 37 | toolbar.install(viewController: self, handlers: handlers) 38 | } 39 | } 40 | -------------------------------------------------------------------------------- /Source/TriangleDrawMain/Canvas/HCFilledCircle.metal: -------------------------------------------------------------------------------- 1 | // MIT license. Copyright (c) 2023 TriangleDraw. All rights reserved. 2 | #include 3 | using namespace metal; 4 | 5 | struct Constants { 6 | float pointSize; 7 | 8 | float4x4 modelViewProjectionMatrix; 9 | }; 10 | 11 | struct VertexIn { 12 | // Position in unit space 13 | // a value of 0 indicates center of the shape 14 | // a value of -1 indicates left edge of the shape 15 | // a value of 1 indicates right edge of the shape 16 | float2 position [[attribute(0)]]; 17 | }; 18 | 19 | struct VertexOut { 20 | // The [[position]] attribute of this member indicates that this value is the clip space 21 | // position of the vertex when this structure is returned from the vertex function 22 | float4 clipSpacePosition [[position]]; 23 | 24 | float pointsize [[point_size]]; 25 | }; 26 | 27 | 28 | vertex VertexOut filledcircle_vertex( 29 | VertexIn in [[stage_in]], 30 | constant Constants &uniforms [[buffer(1)]]) 31 | { 32 | VertexOut out; 33 | 34 | float2 modelPosition = in.position; 35 | 36 | // Multiplies by the model-view-projection matrix from the constant buffer 37 | // Transforms vertex positions from model-local space to clip space 38 | out.clipSpacePosition = uniforms.modelViewProjectionMatrix * float4(modelPosition, 0, 1); 39 | 40 | out.pointsize = uniforms.pointSize; 41 | 42 | return out; 43 | } 44 | 45 | fragment half4 filledcircle_variablesize_fragment( 46 | VertexOut in [[stage_in]], 47 | float2 pointCoord [[point_coord]]) 48 | { 49 | float2 cxy = 2.f * (pointCoord - 0.5f); 50 | float r = dot(cxy, cxy); 51 | 52 | // Antialiasing using `fwidth()` is described here 53 | // https://www.desultoryquest.com/blog/drawing-anti-aliased-circular-points-using-opengl-slash-webgl/ 54 | // https://metashapes.com/blog/anti-aliasing-shaders/ 55 | float delta = fwidth(r); 56 | 57 | float alpha = 1.f - smoothstep(1.f - delta, 1.f + delta, r); 58 | return half4(0.75h, 0.75h, 0.75h, 1.h) * half(alpha); 59 | } 60 | 61 | fragment half4 filledcircle_fixedsize_fragment( 62 | VertexOut in [[stage_in]], 63 | float2 pointCoord [[point_coord]]) 64 | { 65 | float2 cxy = 2.f * (pointCoord - 0.5f); 66 | float v = 1.f - length(cxy); 67 | float alpha = smoothstep(0.6f, 1.f, v) * 0.375f; 68 | return half(alpha); 69 | } 70 | -------------------------------------------------------------------------------- /Source/TriangleDrawMain/Canvas/HCFilledTriangle.metal: -------------------------------------------------------------------------------- 1 | // MIT license. Copyright (c) 2023 TriangleDraw. All rights reserved. 2 | #include 3 | using namespace metal; 4 | 5 | struct Constants { 6 | float4x4 modelViewProjectionMatrix; 7 | }; 8 | 9 | struct VertexIn { 10 | // Position in unit space 11 | // a value of 0 indicates center of the shape 12 | // a value of -1 indicates left edge of the shape 13 | // a value of 1 indicates right edge of the shape 14 | float2 position [[attribute(0)]]; 15 | 16 | // Floating-point RGBA colors 17 | float4 color [[attribute(1)]]; 18 | }; 19 | 20 | struct VertexOut { 21 | // The [[position]] attribute of this member indicates that this value is the clip space 22 | // position of the vertex when this structure is returned from the vertex function 23 | float4 clipSpacePosition [[position]]; 24 | 25 | // Since this member does not have a special attribute, the rasterizer interpolates 26 | // its value with the values of the other triangle vertices and then passes 27 | // the interpolated value to the fragment shader for each fragment in the triangle 28 | float4 color; 29 | }; 30 | 31 | vertex VertexOut filledtriangle_vertex( 32 | VertexIn in [[stage_in]], 33 | constant Constants &uniforms [[buffer(1)]]) 34 | { 35 | VertexOut out; 36 | 37 | float2 modelPosition = in.position; 38 | 39 | // Multiplies by the model-view-projection matrix from the constant buffer 40 | // Transforms vertex positions from model-local space to clip space 41 | out.clipSpacePosition = uniforms.modelViewProjectionMatrix * float4(modelPosition, 0, 1); 42 | 43 | // Pass our input color straight to our output color. This value will be interpolated 44 | // with the other color values of the vertices that make up the triangle to produce 45 | // the color value for each fragment in our fragment shader 46 | out.color = in.color; 47 | 48 | return out; 49 | } 50 | 51 | fragment half4 filledtriangle_fragment(VertexOut in [[stage_in]]) { 52 | return half4(in.color); 53 | } 54 | -------------------------------------------------------------------------------- /Source/TriangleDrawMain/Canvas/HCGridView.swift: -------------------------------------------------------------------------------- 1 | // MIT license. Copyright (c) 2023 TriangleDraw. All rights reserved. 2 | import UIKit 3 | import TriangleDrawLibrary 4 | 5 | class HCGridView: UIView { 6 | override init(frame: CGRect) { 7 | super.init(frame: frame) 8 | self.isOpaque = false 9 | self.isUserInteractionEnabled = false 10 | } 11 | 12 | required init?(coder aDecoder: NSCoder) { 13 | fatalError("init(coder:) has not been implemented") 14 | } 15 | 16 | override func draw(_ rect: CGRect) { 17 | UIColor.red.setStroke() 18 | let inset: CGFloat = 0.5 19 | let numberOfLines: Int = 4 20 | for i in 0...numberOfLines { 21 | let x = remap(CGFloat(i), 0, CGFloat(numberOfLines), bounds.minX + inset, bounds.maxX - inset) 22 | let point0 = CGPoint(x: x, y: bounds.minY) 23 | let point1 = CGPoint(x: x, y: bounds.maxY) 24 | let path = UIBezierPath() 25 | path.move(to: point0) 26 | path.addLine(to: point1) 27 | path.lineWidth = 1 28 | path.stroke() 29 | } 30 | for i in 0...numberOfLines { 31 | let y = remap(CGFloat(i), 0, CGFloat(numberOfLines), bounds.minY + inset, bounds.maxY - inset) 32 | let point0 = CGPoint(x: bounds.minX, y: y) 33 | let point1 = CGPoint(x: bounds.maxX, y: y) 34 | let path = UIBezierPath() 35 | path.move(to: point0) 36 | path.addLine(to: point1) 37 | path.lineWidth = 1 38 | path.stroke() 39 | } 40 | } 41 | } 42 | -------------------------------------------------------------------------------- /Source/TriangleDrawMain/Canvas/HCHexagonCorners.swift: -------------------------------------------------------------------------------- 1 | // MIT license. Copyright (c) 2023 TriangleDraw. All rights reserved. 2 | import CoreGraphics 3 | 4 | struct HCHexagonCorners { 5 | var topLeft = CGPoint.zero 6 | var topRight = CGPoint.zero 7 | var middleLeft = CGPoint.zero 8 | var middleRight = CGPoint.zero 9 | var bottomLeft = CGPoint.zero 10 | var bottomRight = CGPoint.zero 11 | } 12 | 13 | extension HCHexagonCorners: CustomStringConvertible { 14 | var description: String { 15 | return "\(topLeft.string2) \(topRight.string2) \(middleLeft.string2) \(middleRight.string2) \(bottomLeft.string2) \(bottomRight.string2)" 16 | } 17 | } 18 | -------------------------------------------------------------------------------- /Source/TriangleDrawMain/Canvas/HCSafeAreaView.swift: -------------------------------------------------------------------------------- 1 | // MIT license. Copyright (c) 2023 TriangleDraw. All rights reserved. 2 | import UIKit 3 | import TriangleDrawLibrary 4 | 5 | class HCSafeAreaView: UIView { 6 | var gridView: HCGridView? 7 | var interactionView: HCInteractionView? 8 | 9 | override func didMoveToWindow() { 10 | super.didMoveToWindow() 11 | if window != nil { 12 | addOurSubviews() 13 | } else { 14 | removeOurSubviews() 15 | } 16 | } 17 | 18 | func addOurSubviews() { 19 | let gridView = HCGridView() 20 | switch AppConstant.Canvas.mode { 21 | case .production: 22 | gridView.isHidden = true 23 | case .developer: 24 | gridView.isHidden = false 25 | } 26 | self.gridView = gridView 27 | self.addSubview(gridView) 28 | 29 | let interactionView = HCInteractionView(frame: CGRect.zero) 30 | interactionView.backgroundColor = UIColor.clear 31 | interactionView.isOpaque = false 32 | interactionView.installGestures() 33 | self.interactionView = interactionView 34 | self.addSubview(interactionView) 35 | } 36 | 37 | func removeOurSubviews() { 38 | if let view = gridView { 39 | view.removeFromSuperview() 40 | gridView = nil 41 | } 42 | if let view = interactionView { 43 | view.removeFromSuperview() 44 | interactionView = nil 45 | } 46 | } 47 | 48 | override func layoutSubviews() { 49 | super.layoutSubviews() 50 | gridView?.frame = bounds 51 | interactionView?.frame = bounds 52 | } 53 | } 54 | 55 | extension HCSafeAreaView: AcceptsVerboseInfoProvider { 56 | func verboseInfo(_ provider: VerboseInfoProvider) { 57 | let append = provider.append 58 | 59 | if gridView != nil { 60 | append("safeAreaView.gridView", "non-nil") 61 | } else { 62 | append("safeAreaView.gridView", "nil (This is possible an error state!)") 63 | } 64 | 65 | if let interactionView: HCInteractionView = interactionView { 66 | append("safeAreaView.interactionView", "non-nil") 67 | interactionView.verboseInfo(provider) 68 | } else { 69 | append("safeAreaView.interactionView", "nil (This is possible an error state!)") 70 | } 71 | } 72 | } 73 | -------------------------------------------------------------------------------- /Source/TriangleDrawMain/Canvas/Menu/CanvasGridMode.swift: -------------------------------------------------------------------------------- 1 | // MIT license. Copyright (c) 2023 TriangleDraw. All rights reserved. 2 | import Foundation 3 | 4 | public enum CanvasGridMode: String, CaseIterable { 5 | /// Tiny dots that are barely noticable with a size unaffected by the zoom level. 6 | case smallFixedSizeDots 7 | 8 | /// Big dots that changes size depending on the zoom level. 9 | case bigZoomableDots 10 | } 11 | 12 | extension CanvasGridMode { 13 | public var localizedDisplayName: String { 14 | switch self { 15 | case .smallFixedSizeDots: 16 | return "Small Dots" 17 | case .bigZoomableDots: 18 | return "Big Dots" 19 | } 20 | } 21 | } 22 | 23 | /// Keeps track of the users preferred `grid mode`. 24 | class CanvasGridModeController { 25 | private(set) lazy var currentCanvasGridMode = loadCanvasGridMode() 26 | private let defaults: UserDefaults 27 | private let defaultsKey = "TRIANGLEDRAW_CANVASGRIDMODE" 28 | 29 | init(defaults: UserDefaults = .standard) { 30 | self.defaults = defaults 31 | } 32 | 33 | func changeCanvasGridMode(to gridMode: CanvasGridMode) { 34 | currentCanvasGridMode = gridMode 35 | defaults.setValue(gridMode.rawValue, forKey: defaultsKey) 36 | } 37 | 38 | private func loadCanvasGridMode() -> CanvasGridMode { 39 | let rawValue: String? = defaults.string(forKey: defaultsKey) 40 | return rawValue.flatMap(CanvasGridMode.init) ?? .bigZoomableDots 41 | } 42 | } 43 | -------------------------------------------------------------------------------- /Source/TriangleDrawMain/Canvas/Menu/HCMenuSubdivideView.swift: -------------------------------------------------------------------------------- 1 | // MIT license. Copyright (c) 2023 TriangleDraw. All rights reserved. 2 | import SwiftUI 3 | 4 | struct HCMenuSubdivideView: View { 5 | let applySubdivide: (_ n: UInt8) -> Void 6 | @State private var divisionSize: UInt8 = 2 7 | let pickerValues: [UInt8] = [2, 3, 4, 5, 6, 7] 8 | 9 | var body: some View { 10 | Form { 11 | Section() { 12 | HStack { 13 | Spacer() 14 | Text("Split up all triangles\ninto smaller triangles") 15 | .multilineTextAlignment(.center) 16 | .font(.title2) 17 | Spacer() 18 | } 19 | } 20 | Section() { 21 | Text("Select number of divisions") 22 | 23 | Picker("Subdivide", selection: $divisionSize) { 24 | ForEach(pickerValues, id: \.self) { i in 25 | Text(String(i)) 26 | } 27 | } 28 | .id(pickerValues) 29 | .pickerStyle(.wheel) 30 | 31 | Button("Apply") { 32 | self.applySubdivide(divisionSize) 33 | } 34 | .fontWeight(.bold) 35 | .frame(maxWidth: .infinity, alignment: .center) 36 | } 37 | } 38 | .navigationTitle("Subdivide") 39 | .navigationBarTitleDisplayMode(.inline) 40 | } 41 | } 42 | 43 | struct HCMenuSubdivideView_Previews: PreviewProvider { 44 | static var previews: some View { 45 | HCMenuSubdivideView() { _ in } 46 | } 47 | } 48 | -------------------------------------------------------------------------------- /Source/TriangleDrawMain/Canvas/Menu/HCMenuViewController+SharePDF.swift: -------------------------------------------------------------------------------- 1 | // MIT license. Copyright (c) 2023 TriangleDraw. All rights reserved. 2 | import UIKit 3 | import TriangleDrawLibrary 4 | 5 | extension HCMenuViewController { 6 | static func createSharePDFActivityViewController(pdfData: Data, filename: String, triangleCount: UInt) -> UIActivityViewController { 7 | let filesize: Int = pdfData.count 8 | log.debug("Open share sheet. fileSize: \(filesize) filename: '\(filename)' triangleCount: \(triangleCount)") 9 | 10 | // There is not easy way to tell `UIActivityViewController` 11 | // that the data is a PDF file, and what the filename should be. 12 | // The easiest solution is to store the data in the temp dir 13 | // with the filename+extension that it should be treated as. 14 | let url: URL = URL(fileURLWithPath: NSTemporaryDirectory()).appendingPathComponent(filename).appendingPathExtension("pdf") 15 | do { 16 | try pdfData.write(to: url) 17 | } catch { 18 | log.error("failed to write: \(url) \(error)") 19 | fatalError() 20 | } 21 | 22 | // swiftlint:disable:next line_length 23 | let subjectFormat = NSLocalizedString("EMAIL_PDF_SUBJECT_%@", tableName: "CanvasVC", bundle: Bundle.main, value: "", comment: "TriangleDraw - {Drawing name}, a subject line for mails containing PDF attachments") 24 | let emailSubject = String(format: subjectFormat, filename) 25 | let avc = UIActivityViewController(activityItems: [url], applicationActivities: nil) 26 | avc.excludedActivityTypes = [ 27 | .postToFacebook, 28 | .postToTwitter, 29 | .postToWeibo, 30 | .assignToContact, 31 | .saveToCameraRoll, 32 | .addToReadingList, 33 | .postToFlickr, 34 | .postToVimeo, 35 | .postToTencentWeibo, 36 | .openInIBooks 37 | ] 38 | avc.setValue(emailSubject, forKey: "subject") 39 | avc.completionWithItemsHandler = { activityTypeOrNil, completed, returnedItems, activityError in 40 | guard let activityType: UIActivity.ActivityType = activityTypeOrNil else { 41 | log.debug("No activity was selected. (Cancel)") 42 | return 43 | } 44 | let completedString = completed ? "YES" : "NO" 45 | log.debug("activity: \(activityType) completed: \(completedString)") 46 | } 47 | return avc 48 | } 49 | } 50 | -------------------------------------------------------------------------------- /Source/TriangleDrawMain/Canvas/Menu/HCMenuViewController+SharePNG.swift: -------------------------------------------------------------------------------- 1 | // MIT license. Copyright (c) 2023 TriangleDraw. All rights reserved. 2 | import UIKit 3 | import TriangleDrawLibrary 4 | 5 | extension HCMenuViewController { 6 | static func createSharePNGActivityViewController(image imageToShare: UIImage, filename: String?, triangleCount: UInt) -> UIActivityViewController { 7 | let filenameDebugString: String = filename ?? "nil" 8 | let imageSize: CGSize = imageToShare.size 9 | log.debug("Open share sheet. imageSize: \(imageSize) filename: '\(filenameDebugString)' triangleCount: \(triangleCount)") 10 | 11 | // swiftlint:disable:next line_length 12 | let subjectFormat = NSLocalizedString("EMAIL_PNG_SUBJECT_%@", tableName: "CanvasVC", bundle: Bundle.main, value: "", comment: "TriangleDraw - {Drawing name}, a subject line for mails containing PNG attachments") 13 | let emailSubject = String(format: subjectFormat, filename ?? "") 14 | let avc = UIActivityViewController(activityItems: [imageToShare], applicationActivities: nil) 15 | avc.setValue(emailSubject, forKey: "subject") 16 | avc.completionWithItemsHandler = { activityTypeOrNil, completed, returnedItems, activityError in 17 | guard let activityType: UIActivity.ActivityType = activityTypeOrNil else { 18 | log.debug("No activity was selected. (Cancel)") 19 | return 20 | } 21 | let completedString = completed ? "YES" : "NO" 22 | log.debug("activity: \(activityType) completed: \(completedString)") 23 | } 24 | return avc 25 | } 26 | } 27 | -------------------------------------------------------------------------------- /Source/TriangleDrawMain/Canvas/Menu/HCMenuViewController+ShareSVG.swift: -------------------------------------------------------------------------------- 1 | // MIT license. Copyright (c) 2023 TriangleDraw. All rights reserved. 2 | import UIKit 3 | import TriangleDrawLibrary 4 | 5 | extension HCMenuViewController { 6 | static func createShareSVGActivityViewController(svgData: Data, filename: String, triangleCount: UInt) -> UIActivityViewController { 7 | let filesize: Int = svgData.count 8 | log.debug("Open share sheet. fileSize: \(filesize) filename: '\(filename)' triangleCount: \(triangleCount)") 9 | 10 | // There is not easy way to tell `UIActivityViewController` 11 | // that the data is a SVG file, and what the filename should be. 12 | // The easiest solution is to store the data in the temp dir 13 | // with the filename+extension that it should be treated as. 14 | let url: URL = URL(fileURLWithPath: NSTemporaryDirectory()).appendingPathComponent(filename).appendingPathExtension("svg") 15 | do { 16 | try svgData.write(to: url) 17 | } catch { 18 | log.error("failed to write: \(url) \(error)") 19 | fatalError() 20 | } 21 | 22 | let emailSubject = "TriangleDraw - \(filename)" 23 | let avc = UIActivityViewController(activityItems: [url], applicationActivities: nil) 24 | avc.excludedActivityTypes = [ 25 | .postToFacebook, 26 | .postToTwitter, 27 | .postToWeibo, 28 | .assignToContact, 29 | .saveToCameraRoll, 30 | .addToReadingList, 31 | .postToFlickr, 32 | .postToVimeo, 33 | .postToTencentWeibo, 34 | .openInIBooks 35 | ] 36 | avc.setValue(emailSubject, forKey: "subject") 37 | avc.completionWithItemsHandler = { activityTypeOrNil, completed, returnedItems, activityError in 38 | guard let activityType: UIActivity.ActivityType = activityTypeOrNil else { 39 | log.debug("No activity was selected. (Cancel)") 40 | return 41 | } 42 | let completedString = completed ? "YES" : "NO" 43 | log.debug("activity: \(activityType) completed: \(completedString)") 44 | } 45 | return avc 46 | } 47 | } 48 | -------------------------------------------------------------------------------- /Source/TriangleDrawMain/Canvas/Menu/HCMenuViewController.swift: -------------------------------------------------------------------------------- 1 | // MIT license. Copyright (c) 2023 TriangleDraw. All rights reserved. 2 | import UIKit 3 | import Foundation 4 | import TriangleDrawLibrary 5 | import MBProgressHUD 6 | import SwiftUI 7 | 8 | protocol HCMenuViewControllerDelegate: AnyObject { 9 | func hcMenuViewController_applySubdivide(n: UInt8) 10 | func hcMenuViewController_canvasGridModeDidChange(gridMode: CanvasGridMode) 11 | } 12 | 13 | enum HexagonCanvasMenuDocument { 14 | case document(document: Document) 15 | case mock 16 | } 17 | 18 | extension UIViewController { 19 | /// Open a menu with settings related to the canvas 20 | func td_presentHexagonCanvasMenu(document: HexagonCanvasMenuDocument = .mock, delegate: HCMenuViewControllerDelegate? = nil) { 21 | let nc = HCMenuViewController.create(document: document, delegate: delegate) 22 | self.present(nc, animated: true, completion: nil) 23 | } 24 | } 25 | 26 | struct HCMenuViewController { 27 | static func create(document: HexagonCanvasMenuDocument, delegate: HCMenuViewControllerDelegate?) -> UIViewController { 28 | let model = HCMenuViewModel.create() 29 | model.delegate = delegate 30 | 31 | switch document { 32 | case let .document(document): 33 | model.initialCanvas = document.canvas 34 | model.document_displayName = document.displayName 35 | case .mock: 36 | model.initialCanvas = DocumentExample.triangledrawLogo.canvas 37 | model.document_displayName = "Mock" 38 | } 39 | 40 | let rootView = HCMenuView(model: model) 41 | return UIHostingController(rootView: rootView) 42 | } 43 | } 44 | -------------------------------------------------------------------------------- /Source/TriangleDrawMain/Canvas/TDCanvasDrawingProtocol.swift: -------------------------------------------------------------------------------- 1 | // MIT license. Copyright (c) 2023 TriangleDraw. All rights reserved. 2 | import UIKit 3 | import TriangleDrawLibrary 4 | 5 | // swiftlint:disable type_name 6 | typealias TDCanvasDrawing_TapBlock = (TDCanvasDrawingProtocol, E2CanvasPoint) -> Void 7 | typealias TDCanvasDrawing_DrawBlock = (TDCanvasDrawingProtocol, CGPoint, E2CanvasPoint, Bool) -> Void 8 | typealias TDCanvasDrawing_BeforeDrawBlock = () -> Void 9 | typealias TDCanvasDrawing_AfterDrawBlock = () -> Void 10 | typealias TDCanvasDrawing_RotateCompletionBlock = () -> Void 11 | 12 | protocol TDCanvasDrawingProtocol: AnyObject { 13 | var onTapBlock: TDCanvasDrawing_TapBlock? { get set } 14 | var onBeforeDrawBlock: TDCanvasDrawing_BeforeDrawBlock? { get set } 15 | var onDrawBlock: TDCanvasDrawing_DrawBlock? { get set } 16 | var onAfterDrawBlock: TDCanvasDrawing_AfterDrawBlock? { get set } 17 | var hideLabels: Bool { get set } 18 | var canvas: E2Canvas? { get set } 19 | 20 | func rotateAnimation(degrees: Int, completionBlock: @escaping TDCanvasDrawing_RotateCompletionBlock) 21 | } 22 | 23 | typealias TDCanvasDrawingView = (UIView & TDCanvasDrawingProtocol) 24 | -------------------------------------------------------------------------------- /Source/TriangleDrawMain/External/gpc232-release/GPC-README.pdf: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/triangledraw/TriangleDraw-iOS/25bc87c479cd10b461a17834b67d99d911f7cc34/Source/TriangleDrawMain/External/gpc232-release/GPC-README.pdf -------------------------------------------------------------------------------- /Source/TriangleDrawMain/Main/DocumentExample.swift: -------------------------------------------------------------------------------- 1 | // MIT license. Copyright (c) 2023 TriangleDraw. All rights reserved. 2 | import Foundation 3 | import TriangleDrawLibrary 4 | 5 | enum DocumentExample: String { 6 | case blankFile = "Drawing" 7 | case triangledrawLogo = "triangledraw logo" 8 | // swiftlint:disable:next identifier_name 9 | case developer_rows 10 | // swiftlint:disable:next identifier_name 11 | case developer_columns 12 | case rune1 = "rune 1" 13 | case injection 14 | } 15 | 16 | extension DocumentExample { 17 | var overrideDisplayName: String? { 18 | switch self { 19 | case .triangledrawLogo: 20 | return "Client Logo" 21 | case .rune1: 22 | return "Viking Symbol" 23 | default: 24 | return nil 25 | } 26 | } 27 | } 28 | 29 | extension DocumentExample { 30 | var url: URL { 31 | return DocumentExample.bundleURL.appendingPathComponent(self.rawValue).appendingPathExtension("triangleDraw") 32 | } 33 | 34 | var canvas: E2Canvas { 35 | do { 36 | let data: Data = try Data(contentsOf: self.url) 37 | let canvas: E2Canvas = try TDCanvasReader.canvas(fromPBMRepresentation: data) 38 | return canvas 39 | } catch { 40 | log.error("The examples are supposed to be bundled with the app. \(error)") 41 | fatalError("The examples are supposed to be bundled with the app.") 42 | } 43 | } 44 | 45 | static var bundleURL: URL { 46 | return Bundle.main.url(forResource: "DocumentExample", withExtension: "bundle")! 47 | } 48 | } 49 | -------------------------------------------------------------------------------- /Source/TriangleDrawMain/Main/Image.swift: -------------------------------------------------------------------------------- 1 | // MIT license. Copyright (c) 2023 TriangleDraw. All rights reserved. 2 | import UIKit 3 | 4 | // swiftlint:disable identifier_name 5 | enum Image: String { 6 | case browser_gear 7 | case canvas_moveLeft 8 | case canvas_moveRight 9 | case canvas_moveUp 10 | case canvas_moveDown 11 | case canvas_flipX 12 | case canvas_flipY 13 | case canvas_rotateCCW 14 | case canvas_rotateCW 15 | case canvas_enterFullscreen 16 | } 17 | 18 | extension Image { 19 | var image: UIImage { 20 | guard let image: UIImage = UIImage(named: self.rawValue) else { 21 | fatalError("no image for \(self)") 22 | } 23 | return image 24 | } 25 | } 26 | -------------------------------------------------------------------------------- /Source/TriangleDrawMain/Main/Platform.swift: -------------------------------------------------------------------------------- 1 | // MIT license. Copyright (c) 2023 TriangleDraw. All rights reserved. 2 | import UIKit 3 | 4 | class Platform { 5 | // swiftlint:disable:next identifier_name 6 | static var is_ideom_ipad: Bool { 7 | return UIDevice.current.userInterfaceIdiom == .pad 8 | } 9 | } 10 | -------------------------------------------------------------------------------- /Source/TriangleDrawMain/Main/TriangleDrawMain-Bridging-Header.h: -------------------------------------------------------------------------------- 1 | // 2 | // Use this file to import your target's public headers that you would like to expose to Swift. 3 | // 4 | 5 | #import "AAPLMathUtilities.h" 6 | #include "gpc.h" 7 | -------------------------------------------------------------------------------- /Source/TriangleDrawMain/Main/UIApplication+Directories.swift: -------------------------------------------------------------------------------- 1 | // MIT license. Copyright (c) 2023 TriangleDraw. All rights reserved. 2 | import UIKit 3 | 4 | extension UIApplication { 5 | static func cacheDirectory() -> URL { 6 | guard let cacheURL = FileManager.default.urls(for: .cachesDirectory, in: .userDomainMask).first else { 7 | fatalError("unable to get system cache directory - serious problems") 8 | } 9 | return cacheURL 10 | } 11 | 12 | static func documentsDirectory() -> URL { 13 | guard let documentsURL = FileManager.default.urls(for: .documentDirectory, in: .userDomainMask).first else { 14 | fatalError("unable to get system docs directory - serious problems") 15 | } 16 | return documentsURL 17 | } 18 | } 19 | -------------------------------------------------------------------------------- /Source/TriangleDrawMain/Main/UserDefaults+RunCount.swift: -------------------------------------------------------------------------------- 1 | // MIT license. Copyright (c) 2023 TriangleDraw. All rights reserved. 2 | import Foundation 3 | 4 | // Keep track of how many times the app have been started 5 | extension UserDefaults { 6 | func td_incrementRunCount() { 7 | let runCount: Int = td_runCount() 8 | set(runCount + 1, forKey: TRIANGLEDRAW_RUN_COUNT) 9 | synchronize() 10 | } 11 | 12 | // Returns 0 the very first time the app is being started 13 | // This number is incremented on following starts 14 | func td_runCount() -> Int { 15 | return integer(forKey: TRIANGLEDRAW_RUN_COUNT) 16 | } 17 | } 18 | 19 | // swiftlint:disable:next identifier_name 20 | let TRIANGLEDRAW_RUN_COUNT = "TRIANGLEDRAW_RUN_COUNT" 21 | -------------------------------------------------------------------------------- /Source/TriangleDrawMain/Resources/Images.xcassets/AppIcon.appiconset/Icon.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/triangledraw/TriangleDraw-iOS/25bc87c479cd10b461a17834b67d99d911f7cc34/Source/TriangleDrawMain/Resources/Images.xcassets/AppIcon.appiconset/Icon.png -------------------------------------------------------------------------------- /Source/TriangleDrawMain/Resources/Images.xcassets/AppIcon.appiconset/icon_20pt.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/triangledraw/TriangleDraw-iOS/25bc87c479cd10b461a17834b67d99d911f7cc34/Source/TriangleDrawMain/Resources/Images.xcassets/AppIcon.appiconset/icon_20pt.png -------------------------------------------------------------------------------- /Source/TriangleDrawMain/Resources/Images.xcassets/AppIcon.appiconset/icon_20pt@2x-1.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/triangledraw/TriangleDraw-iOS/25bc87c479cd10b461a17834b67d99d911f7cc34/Source/TriangleDrawMain/Resources/Images.xcassets/AppIcon.appiconset/icon_20pt@2x-1.png -------------------------------------------------------------------------------- /Source/TriangleDrawMain/Resources/Images.xcassets/AppIcon.appiconset/icon_20pt@2x.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/triangledraw/TriangleDraw-iOS/25bc87c479cd10b461a17834b67d99d911f7cc34/Source/TriangleDrawMain/Resources/Images.xcassets/AppIcon.appiconset/icon_20pt@2x.png -------------------------------------------------------------------------------- /Source/TriangleDrawMain/Resources/Images.xcassets/AppIcon.appiconset/icon_20pt@3x.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/triangledraw/TriangleDraw-iOS/25bc87c479cd10b461a17834b67d99d911f7cc34/Source/TriangleDrawMain/Resources/Images.xcassets/AppIcon.appiconset/icon_20pt@3x.png -------------------------------------------------------------------------------- /Source/TriangleDrawMain/Resources/Images.xcassets/AppIcon.appiconset/icon_29pt.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/triangledraw/TriangleDraw-iOS/25bc87c479cd10b461a17834b67d99d911f7cc34/Source/TriangleDrawMain/Resources/Images.xcassets/AppIcon.appiconset/icon_29pt.png -------------------------------------------------------------------------------- /Source/TriangleDrawMain/Resources/Images.xcassets/AppIcon.appiconset/icon_29pt@2x-1.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/triangledraw/TriangleDraw-iOS/25bc87c479cd10b461a17834b67d99d911f7cc34/Source/TriangleDrawMain/Resources/Images.xcassets/AppIcon.appiconset/icon_29pt@2x-1.png -------------------------------------------------------------------------------- /Source/TriangleDrawMain/Resources/Images.xcassets/AppIcon.appiconset/icon_29pt@2x.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/triangledraw/TriangleDraw-iOS/25bc87c479cd10b461a17834b67d99d911f7cc34/Source/TriangleDrawMain/Resources/Images.xcassets/AppIcon.appiconset/icon_29pt@2x.png -------------------------------------------------------------------------------- /Source/TriangleDrawMain/Resources/Images.xcassets/AppIcon.appiconset/icon_29pt@3x.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/triangledraw/TriangleDraw-iOS/25bc87c479cd10b461a17834b67d99d911f7cc34/Source/TriangleDrawMain/Resources/Images.xcassets/AppIcon.appiconset/icon_29pt@3x.png -------------------------------------------------------------------------------- /Source/TriangleDrawMain/Resources/Images.xcassets/AppIcon.appiconset/icon_40pt.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/triangledraw/TriangleDraw-iOS/25bc87c479cd10b461a17834b67d99d911f7cc34/Source/TriangleDrawMain/Resources/Images.xcassets/AppIcon.appiconset/icon_40pt.png -------------------------------------------------------------------------------- /Source/TriangleDrawMain/Resources/Images.xcassets/AppIcon.appiconset/icon_40pt@2x-1.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/triangledraw/TriangleDraw-iOS/25bc87c479cd10b461a17834b67d99d911f7cc34/Source/TriangleDrawMain/Resources/Images.xcassets/AppIcon.appiconset/icon_40pt@2x-1.png -------------------------------------------------------------------------------- /Source/TriangleDrawMain/Resources/Images.xcassets/AppIcon.appiconset/icon_40pt@2x.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/triangledraw/TriangleDraw-iOS/25bc87c479cd10b461a17834b67d99d911f7cc34/Source/TriangleDrawMain/Resources/Images.xcassets/AppIcon.appiconset/icon_40pt@2x.png -------------------------------------------------------------------------------- /Source/TriangleDrawMain/Resources/Images.xcassets/AppIcon.appiconset/icon_40pt@3x.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/triangledraw/TriangleDraw-iOS/25bc87c479cd10b461a17834b67d99d911f7cc34/Source/TriangleDrawMain/Resources/Images.xcassets/AppIcon.appiconset/icon_40pt@3x.png -------------------------------------------------------------------------------- /Source/TriangleDrawMain/Resources/Images.xcassets/AppIcon.appiconset/icon_60pt@2x.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/triangledraw/TriangleDraw-iOS/25bc87c479cd10b461a17834b67d99d911f7cc34/Source/TriangleDrawMain/Resources/Images.xcassets/AppIcon.appiconset/icon_60pt@2x.png -------------------------------------------------------------------------------- /Source/TriangleDrawMain/Resources/Images.xcassets/AppIcon.appiconset/icon_60pt@3x.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/triangledraw/TriangleDraw-iOS/25bc87c479cd10b461a17834b67d99d911f7cc34/Source/TriangleDrawMain/Resources/Images.xcassets/AppIcon.appiconset/icon_60pt@3x.png -------------------------------------------------------------------------------- /Source/TriangleDrawMain/Resources/Images.xcassets/AppIcon.appiconset/icon_76pt.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/triangledraw/TriangleDraw-iOS/25bc87c479cd10b461a17834b67d99d911f7cc34/Source/TriangleDrawMain/Resources/Images.xcassets/AppIcon.appiconset/icon_76pt.png -------------------------------------------------------------------------------- /Source/TriangleDrawMain/Resources/Images.xcassets/AppIcon.appiconset/icon_76pt@2x.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/triangledraw/TriangleDraw-iOS/25bc87c479cd10b461a17834b67d99d911f7cc34/Source/TriangleDrawMain/Resources/Images.xcassets/AppIcon.appiconset/icon_76pt@2x.png -------------------------------------------------------------------------------- /Source/TriangleDrawMain/Resources/Images.xcassets/AppIcon.appiconset/icon_83.5@2x.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/triangledraw/TriangleDraw-iOS/25bc87c479cd10b461a17834b67d99d911f7cc34/Source/TriangleDrawMain/Resources/Images.xcassets/AppIcon.appiconset/icon_83.5@2x.png -------------------------------------------------------------------------------- /Source/TriangleDrawMain/Resources/Images.xcassets/Browser/Contents.json: -------------------------------------------------------------------------------- 1 | { 2 | "info" : { 3 | "version" : 1, 4 | "author" : "xcode" 5 | } 6 | } -------------------------------------------------------------------------------- /Source/TriangleDrawMain/Resources/Images.xcassets/Browser/browser_gear.imageset/Contents.json: -------------------------------------------------------------------------------- 1 | { 2 | "images" : [ 3 | { 4 | "idiom" : "universal", 5 | "scale" : "1x" 6 | }, 7 | { 8 | "idiom" : "universal", 9 | "filename" : "browser_gear@2x.pdf", 10 | "scale" : "2x" 11 | }, 12 | { 13 | "idiom" : "universal", 14 | "filename" : "browser_gear@3x.pdf", 15 | "scale" : "3x" 16 | } 17 | ], 18 | "info" : { 19 | "version" : 1, 20 | "author" : "xcode" 21 | } 22 | } -------------------------------------------------------------------------------- /Source/TriangleDrawMain/Resources/Images.xcassets/Browser/browser_gear.imageset/browser_gear@2x.pdf: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/triangledraw/TriangleDraw-iOS/25bc87c479cd10b461a17834b67d99d911f7cc34/Source/TriangleDrawMain/Resources/Images.xcassets/Browser/browser_gear.imageset/browser_gear@2x.pdf -------------------------------------------------------------------------------- /Source/TriangleDrawMain/Resources/Images.xcassets/Browser/browser_gear.imageset/browser_gear@3x.pdf: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/triangledraw/TriangleDraw-iOS/25bc87c479cd10b461a17834b67d99d911f7cc34/Source/TriangleDrawMain/Resources/Images.xcassets/Browser/browser_gear.imageset/browser_gear@3x.pdf -------------------------------------------------------------------------------- /Source/TriangleDrawMain/Resources/Images.xcassets/Canvas/Contents.json: -------------------------------------------------------------------------------- 1 | { 2 | "info" : { 3 | "version" : 1, 4 | "author" : "xcode" 5 | } 6 | } -------------------------------------------------------------------------------- /Source/TriangleDrawMain/Resources/Images.xcassets/Canvas/canvas_enterFullscreen.imageset/Contents.json: -------------------------------------------------------------------------------- 1 | { 2 | "images" : [ 3 | { 4 | "idiom" : "universal", 5 | "scale" : "1x", 6 | "filename" : "canvas_enter_fullscreen.png" 7 | }, 8 | { 9 | "idiom" : "universal", 10 | "scale" : "2x", 11 | "filename" : "canvas_enter_fullscreen@2x.png" 12 | }, 13 | { 14 | "idiom" : "universal", 15 | "scale" : "3x", 16 | "filename" : "canvas_enter_fullscreen@3x.png" 17 | } 18 | ], 19 | "info" : { 20 | "version" : 1, 21 | "author" : "xcode" 22 | } 23 | } -------------------------------------------------------------------------------- /Source/TriangleDrawMain/Resources/Images.xcassets/Canvas/canvas_enterFullscreen.imageset/canvas_enter_fullscreen.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/triangledraw/TriangleDraw-iOS/25bc87c479cd10b461a17834b67d99d911f7cc34/Source/TriangleDrawMain/Resources/Images.xcassets/Canvas/canvas_enterFullscreen.imageset/canvas_enter_fullscreen.png -------------------------------------------------------------------------------- /Source/TriangleDrawMain/Resources/Images.xcassets/Canvas/canvas_enterFullscreen.imageset/canvas_enter_fullscreen@2x.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/triangledraw/TriangleDraw-iOS/25bc87c479cd10b461a17834b67d99d911f7cc34/Source/TriangleDrawMain/Resources/Images.xcassets/Canvas/canvas_enterFullscreen.imageset/canvas_enter_fullscreen@2x.png -------------------------------------------------------------------------------- /Source/TriangleDrawMain/Resources/Images.xcassets/Canvas/canvas_enterFullscreen.imageset/canvas_enter_fullscreen@3x.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/triangledraw/TriangleDraw-iOS/25bc87c479cd10b461a17834b67d99d911f7cc34/Source/TriangleDrawMain/Resources/Images.xcassets/Canvas/canvas_enterFullscreen.imageset/canvas_enter_fullscreen@3x.png -------------------------------------------------------------------------------- /Source/TriangleDrawMain/Resources/Images.xcassets/Canvas/canvas_flipX.imageset/Contents.json: -------------------------------------------------------------------------------- 1 | { 2 | "images" : [ 3 | { 4 | "idiom" : "universal", 5 | "filename" : "canvas_flipX.png", 6 | "scale" : "1x" 7 | }, 8 | { 9 | "idiom" : "universal", 10 | "filename" : "canvas_flipX@2x.png", 11 | "scale" : "2x" 12 | }, 13 | { 14 | "idiom" : "universal", 15 | "scale" : "3x" 16 | } 17 | ], 18 | "info" : { 19 | "version" : 1, 20 | "author" : "xcode" 21 | } 22 | } -------------------------------------------------------------------------------- /Source/TriangleDrawMain/Resources/Images.xcassets/Canvas/canvas_flipX.imageset/canvas_flipX.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/triangledraw/TriangleDraw-iOS/25bc87c479cd10b461a17834b67d99d911f7cc34/Source/TriangleDrawMain/Resources/Images.xcassets/Canvas/canvas_flipX.imageset/canvas_flipX.png -------------------------------------------------------------------------------- /Source/TriangleDrawMain/Resources/Images.xcassets/Canvas/canvas_flipX.imageset/canvas_flipX@2x.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/triangledraw/TriangleDraw-iOS/25bc87c479cd10b461a17834b67d99d911f7cc34/Source/TriangleDrawMain/Resources/Images.xcassets/Canvas/canvas_flipX.imageset/canvas_flipX@2x.png -------------------------------------------------------------------------------- /Source/TriangleDrawMain/Resources/Images.xcassets/Canvas/canvas_flipY.imageset/Contents.json: -------------------------------------------------------------------------------- 1 | { 2 | "images" : [ 3 | { 4 | "idiom" : "universal", 5 | "filename" : "canvas_flipY.png", 6 | "scale" : "1x" 7 | }, 8 | { 9 | "idiom" : "universal", 10 | "filename" : "canvas_flipY@2x.png", 11 | "scale" : "2x" 12 | }, 13 | { 14 | "idiom" : "universal", 15 | "scale" : "3x" 16 | } 17 | ], 18 | "info" : { 19 | "version" : 1, 20 | "author" : "xcode" 21 | } 22 | } -------------------------------------------------------------------------------- /Source/TriangleDrawMain/Resources/Images.xcassets/Canvas/canvas_flipY.imageset/canvas_flipY.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/triangledraw/TriangleDraw-iOS/25bc87c479cd10b461a17834b67d99d911f7cc34/Source/TriangleDrawMain/Resources/Images.xcassets/Canvas/canvas_flipY.imageset/canvas_flipY.png -------------------------------------------------------------------------------- /Source/TriangleDrawMain/Resources/Images.xcassets/Canvas/canvas_flipY.imageset/canvas_flipY@2x.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/triangledraw/TriangleDraw-iOS/25bc87c479cd10b461a17834b67d99d911f7cc34/Source/TriangleDrawMain/Resources/Images.xcassets/Canvas/canvas_flipY.imageset/canvas_flipY@2x.png -------------------------------------------------------------------------------- /Source/TriangleDrawMain/Resources/Images.xcassets/Canvas/canvas_moveDown.imageset/Contents.json: -------------------------------------------------------------------------------- 1 | { 2 | "images" : [ 3 | { 4 | "idiom" : "universal", 5 | "scale" : "1x", 6 | "filename" : "arrow_down.png" 7 | }, 8 | { 9 | "idiom" : "universal", 10 | "scale" : "2x", 11 | "filename" : "arrow_down2x.png" 12 | }, 13 | { 14 | "idiom" : "universal", 15 | "scale" : "3x", 16 | "filename" : "arrow_down3x.png" 17 | } 18 | ], 19 | "info" : { 20 | "version" : 1, 21 | "author" : "xcode" 22 | } 23 | } -------------------------------------------------------------------------------- /Source/TriangleDrawMain/Resources/Images.xcassets/Canvas/canvas_moveDown.imageset/arrow_down.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/triangledraw/TriangleDraw-iOS/25bc87c479cd10b461a17834b67d99d911f7cc34/Source/TriangleDrawMain/Resources/Images.xcassets/Canvas/canvas_moveDown.imageset/arrow_down.png -------------------------------------------------------------------------------- /Source/TriangleDrawMain/Resources/Images.xcassets/Canvas/canvas_moveDown.imageset/arrow_down2x.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/triangledraw/TriangleDraw-iOS/25bc87c479cd10b461a17834b67d99d911f7cc34/Source/TriangleDrawMain/Resources/Images.xcassets/Canvas/canvas_moveDown.imageset/arrow_down2x.png -------------------------------------------------------------------------------- /Source/TriangleDrawMain/Resources/Images.xcassets/Canvas/canvas_moveDown.imageset/arrow_down3x.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/triangledraw/TriangleDraw-iOS/25bc87c479cd10b461a17834b67d99d911f7cc34/Source/TriangleDrawMain/Resources/Images.xcassets/Canvas/canvas_moveDown.imageset/arrow_down3x.png -------------------------------------------------------------------------------- /Source/TriangleDrawMain/Resources/Images.xcassets/Canvas/canvas_moveLeft.imageset/Contents.json: -------------------------------------------------------------------------------- 1 | { 2 | "images" : [ 3 | { 4 | "idiom" : "universal", 5 | "scale" : "1x", 6 | "filename" : "arrow_left.png" 7 | }, 8 | { 9 | "idiom" : "universal", 10 | "scale" : "2x", 11 | "filename" : "arrow_left2x.png" 12 | }, 13 | { 14 | "idiom" : "universal", 15 | "scale" : "3x", 16 | "filename" : "arrow_left3x.png" 17 | } 18 | ], 19 | "info" : { 20 | "version" : 1, 21 | "author" : "xcode" 22 | } 23 | } -------------------------------------------------------------------------------- /Source/TriangleDrawMain/Resources/Images.xcassets/Canvas/canvas_moveLeft.imageset/arrow_left.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/triangledraw/TriangleDraw-iOS/25bc87c479cd10b461a17834b67d99d911f7cc34/Source/TriangleDrawMain/Resources/Images.xcassets/Canvas/canvas_moveLeft.imageset/arrow_left.png -------------------------------------------------------------------------------- /Source/TriangleDrawMain/Resources/Images.xcassets/Canvas/canvas_moveLeft.imageset/arrow_left2x.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/triangledraw/TriangleDraw-iOS/25bc87c479cd10b461a17834b67d99d911f7cc34/Source/TriangleDrawMain/Resources/Images.xcassets/Canvas/canvas_moveLeft.imageset/arrow_left2x.png -------------------------------------------------------------------------------- /Source/TriangleDrawMain/Resources/Images.xcassets/Canvas/canvas_moveLeft.imageset/arrow_left3x.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/triangledraw/TriangleDraw-iOS/25bc87c479cd10b461a17834b67d99d911f7cc34/Source/TriangleDrawMain/Resources/Images.xcassets/Canvas/canvas_moveLeft.imageset/arrow_left3x.png -------------------------------------------------------------------------------- /Source/TriangleDrawMain/Resources/Images.xcassets/Canvas/canvas_moveRight.imageset/Contents.json: -------------------------------------------------------------------------------- 1 | { 2 | "images" : [ 3 | { 4 | "idiom" : "universal", 5 | "scale" : "1x", 6 | "filename" : "arrow_right.png" 7 | }, 8 | { 9 | "idiom" : "universal", 10 | "scale" : "2x", 11 | "filename" : "arrow_right2x.png" 12 | }, 13 | { 14 | "idiom" : "universal", 15 | "scale" : "3x", 16 | "filename" : "arrow_right3x.png" 17 | } 18 | ], 19 | "info" : { 20 | "version" : 1, 21 | "author" : "xcode" 22 | } 23 | } -------------------------------------------------------------------------------- /Source/TriangleDrawMain/Resources/Images.xcassets/Canvas/canvas_moveRight.imageset/arrow_right.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/triangledraw/TriangleDraw-iOS/25bc87c479cd10b461a17834b67d99d911f7cc34/Source/TriangleDrawMain/Resources/Images.xcassets/Canvas/canvas_moveRight.imageset/arrow_right.png -------------------------------------------------------------------------------- /Source/TriangleDrawMain/Resources/Images.xcassets/Canvas/canvas_moveRight.imageset/arrow_right2x.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/triangledraw/TriangleDraw-iOS/25bc87c479cd10b461a17834b67d99d911f7cc34/Source/TriangleDrawMain/Resources/Images.xcassets/Canvas/canvas_moveRight.imageset/arrow_right2x.png -------------------------------------------------------------------------------- /Source/TriangleDrawMain/Resources/Images.xcassets/Canvas/canvas_moveRight.imageset/arrow_right3x.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/triangledraw/TriangleDraw-iOS/25bc87c479cd10b461a17834b67d99d911f7cc34/Source/TriangleDrawMain/Resources/Images.xcassets/Canvas/canvas_moveRight.imageset/arrow_right3x.png -------------------------------------------------------------------------------- /Source/TriangleDrawMain/Resources/Images.xcassets/Canvas/canvas_moveUp.imageset/Contents.json: -------------------------------------------------------------------------------- 1 | { 2 | "images" : [ 3 | { 4 | "idiom" : "universal", 5 | "scale" : "1x", 6 | "filename" : "arrow_up.png" 7 | }, 8 | { 9 | "idiom" : "universal", 10 | "scale" : "2x", 11 | "filename" : "arrow_up2x.png" 12 | }, 13 | { 14 | "idiom" : "universal", 15 | "scale" : "3x", 16 | "filename" : "arrow_up3x.png" 17 | } 18 | ], 19 | "info" : { 20 | "version" : 1, 21 | "author" : "xcode" 22 | } 23 | } -------------------------------------------------------------------------------- /Source/TriangleDrawMain/Resources/Images.xcassets/Canvas/canvas_moveUp.imageset/arrow_up.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/triangledraw/TriangleDraw-iOS/25bc87c479cd10b461a17834b67d99d911f7cc34/Source/TriangleDrawMain/Resources/Images.xcassets/Canvas/canvas_moveUp.imageset/arrow_up.png -------------------------------------------------------------------------------- /Source/TriangleDrawMain/Resources/Images.xcassets/Canvas/canvas_moveUp.imageset/arrow_up2x.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/triangledraw/TriangleDraw-iOS/25bc87c479cd10b461a17834b67d99d911f7cc34/Source/TriangleDrawMain/Resources/Images.xcassets/Canvas/canvas_moveUp.imageset/arrow_up2x.png -------------------------------------------------------------------------------- /Source/TriangleDrawMain/Resources/Images.xcassets/Canvas/canvas_moveUp.imageset/arrow_up3x.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/triangledraw/TriangleDraw-iOS/25bc87c479cd10b461a17834b67d99d911f7cc34/Source/TriangleDrawMain/Resources/Images.xcassets/Canvas/canvas_moveUp.imageset/arrow_up3x.png -------------------------------------------------------------------------------- /Source/TriangleDrawMain/Resources/Images.xcassets/Canvas/canvas_rotateCCW.imageset/Contents.json: -------------------------------------------------------------------------------- 1 | { 2 | "images" : [ 3 | { 4 | "idiom" : "universal", 5 | "scale" : "1x" 6 | }, 7 | { 8 | "idiom" : "universal", 9 | "filename" : "canvas_rotateCCW@2x.png", 10 | "scale" : "2x" 11 | }, 12 | { 13 | "idiom" : "universal", 14 | "scale" : "3x" 15 | } 16 | ], 17 | "info" : { 18 | "version" : 1, 19 | "author" : "xcode" 20 | } 21 | } -------------------------------------------------------------------------------- /Source/TriangleDrawMain/Resources/Images.xcassets/Canvas/canvas_rotateCCW.imageset/canvas_rotateCCW@2x.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/triangledraw/TriangleDraw-iOS/25bc87c479cd10b461a17834b67d99d911f7cc34/Source/TriangleDrawMain/Resources/Images.xcassets/Canvas/canvas_rotateCCW.imageset/canvas_rotateCCW@2x.png -------------------------------------------------------------------------------- /Source/TriangleDrawMain/Resources/Images.xcassets/Canvas/canvas_rotateCW.imageset/Contents.json: -------------------------------------------------------------------------------- 1 | { 2 | "images" : [ 3 | { 4 | "idiom" : "universal", 5 | "scale" : "1x" 6 | }, 7 | { 8 | "idiom" : "universal", 9 | "filename" : "canvas_rotateCW@2x.png", 10 | "scale" : "2x" 11 | }, 12 | { 13 | "idiom" : "universal", 14 | "scale" : "3x" 15 | } 16 | ], 17 | "info" : { 18 | "version" : 1, 19 | "author" : "xcode" 20 | } 21 | } -------------------------------------------------------------------------------- /Source/TriangleDrawMain/Resources/Images.xcassets/Canvas/canvas_rotateCW.imageset/canvas_rotateCW@2x.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/triangledraw/TriangleDraw-iOS/25bc87c479cd10b461a17834b67d99d911f7cc34/Source/TriangleDrawMain/Resources/Images.xcassets/Canvas/canvas_rotateCW.imageset/canvas_rotateCW@2x.png -------------------------------------------------------------------------------- /Source/TriangleDrawMain/Resources/Images.xcassets/Contents.json: -------------------------------------------------------------------------------- 1 | { 2 | "info" : { 3 | "version" : 1, 4 | "author" : "xcode" 5 | } 6 | } -------------------------------------------------------------------------------- /Source/TriangleDrawMain/Resources/Images.xcassets/triangledraw_launchscreen.imageset/Contents.json: -------------------------------------------------------------------------------- 1 | { 2 | "images" : [ 3 | { 4 | "filename" : "triangledraw_launchscreen.pdf", 5 | "idiom" : "universal", 6 | "scale" : "1x" 7 | }, 8 | { 9 | "idiom" : "universal", 10 | "scale" : "2x" 11 | }, 12 | { 13 | "idiom" : "universal", 14 | "scale" : "3x" 15 | } 16 | ], 17 | "info" : { 18 | "author" : "xcode", 19 | "version" : 1 20 | }, 21 | "properties" : { 22 | "preserves-vector-representation" : true 23 | } 24 | } 25 | -------------------------------------------------------------------------------- /Source/TriangleDrawMain/Resources/Images.xcassets/triangledraw_launchscreen.imageset/triangledraw_launchscreen.pdf: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/triangledraw/TriangleDraw-iOS/25bc87c479cd10b461a17834b67d99d911f7cc34/Source/TriangleDrawMain/Resources/Images.xcassets/triangledraw_launchscreen.imageset/triangledraw_launchscreen.pdf -------------------------------------------------------------------------------- /Source/TriangleDrawMain/Resources/TriangleDrawMain.entitlements: -------------------------------------------------------------------------------- 1 | 2 | 3 | 4 | 5 | com.apple.developer.icloud-container-identifiers 6 | 7 | iCloud.$(CFBundleIdentifier) 8 | 9 | com.apple.developer.icloud-services 10 | 11 | CloudDocuments 12 | 13 | com.apple.developer.ubiquity-container-identifiers 14 | 15 | iCloud.$(CFBundleIdentifier) 16 | 17 | com.apple.security.application-groups 18 | 19 | group.com.triangledraw.td3 20 | 21 | 22 | 23 | -------------------------------------------------------------------------------- /Source/TriangleDrawMain/UIKit/BorderedButton.swift: -------------------------------------------------------------------------------- 1 | // MIT license. Copyright (c) 2023 TriangleDraw. All rights reserved. 2 | import UIKit 3 | 4 | @IBDesignable 5 | class BorderedButton: UIButton { 6 | 7 | @IBInspectable 8 | var borderColor: UIColor? { 9 | get { 10 | if let color = layer.borderColor { 11 | return UIColor(cgColor: color) 12 | } 13 | return nil 14 | } 15 | set { 16 | if let color = newValue { 17 | layer.borderColor = color.cgColor 18 | } else { 19 | layer.borderColor = nil 20 | } 21 | } 22 | } 23 | 24 | } 25 | -------------------------------------------------------------------------------- /Source/TriangleDrawMain/UIKit/CGRect+FitSizeInSize.swift: -------------------------------------------------------------------------------- 1 | // MIT license. Copyright (c) 2023 TriangleDraw. All rights reserved. 2 | import CoreGraphics 3 | 4 | extension CGRect { 5 | /// Scale and translate a rectangle so that it fits inside a container rectangle. 6 | /// 7 | /// 8 | /// - parameter size: The size of the rectangle that is to be scaled and translated. 9 | /// - parameter fit: The size of the target container rectangle. 10 | /// 11 | /// - returns: A scaled and translated version of the `size` rectangle. 12 | static func fitSizeInSize(size: CGSize, fit: CGSize) -> CGRect { 13 | assert(size.width > 0) 14 | assert(size.height > 0) 15 | assert(fit.width > 0) 16 | assert(fit.height > 0) 17 | let heightQuotient: CGFloat = size.height / fit.height 18 | let widthQuotient: CGFloat = size.width / fit.width 19 | let result: CGSize 20 | if heightQuotient > widthQuotient { 21 | result = CGSize(width: size.width / heightQuotient, height: fit.height) 22 | } else { 23 | result = CGSize(width: fit.width, height: size.height / widthQuotient) 24 | } 25 | let point = CGPoint( 26 | x: floor((fit.width - result.width) / 2.0), 27 | y: floor((fit.height - result.height) / 2.0) 28 | ) 29 | return CGRect(origin: point, size: result) 30 | } 31 | } 32 | -------------------------------------------------------------------------------- /Source/TriangleDrawMain/UIKit/CGSize+Inset.swift: -------------------------------------------------------------------------------- 1 | // MIT license. Copyright (c) 2023 TriangleDraw. All rights reserved. 2 | import UIKit 3 | 4 | extension CGSize { 5 | func inset(by insets: UIEdgeInsets) -> CGSize { 6 | let newSize: CGSize = CGSize( 7 | width: self.width - (insets.left + insets.right), 8 | height: self.height - (insets.top + insets.bottom) 9 | ) 10 | return newSize 11 | } 12 | } 13 | -------------------------------------------------------------------------------- /Source/TriangleDrawMain/UIKit/CGSize+MinMax.swift: -------------------------------------------------------------------------------- 1 | // MIT license. Copyright (c) 2023 TriangleDraw. All rights reserved. 2 | import CoreGraphics 3 | 4 | extension CGSize { 5 | var minValue: CGFloat { 6 | return min(self.width, self.height) 7 | } 8 | 9 | var maxValue: CGFloat { 10 | return max(self.width, self.height) 11 | } 12 | } 13 | -------------------------------------------------------------------------------- /Source/TriangleDrawMain/UIKit/SwiftBarButtonItem.swift: -------------------------------------------------------------------------------- 1 | // MIT license. Copyright (c) 2023 TriangleDraw. All rights reserved. 2 | import UIKit 3 | 4 | /// See: https://stackoverflow.com/a/56637655/78336 5 | class SwiftBarButtonItem: UIBarButtonItem { 6 | typealias ActionHandler = (UIBarButtonItem) -> Void 7 | 8 | private var actionHandler: ActionHandler? 9 | 10 | convenience init(image: UIImage?, style: UIBarButtonItem.Style, actionHandler: ActionHandler?) { 11 | self.init(image: image, style: style, target: nil, action: #selector(barButtonItemPressed(sender:))) 12 | target = self 13 | self.actionHandler = actionHandler 14 | } 15 | 16 | convenience init(title: String?, style: UIBarButtonItem.Style, actionHandler: ActionHandler?) { 17 | self.init(title: title, style: style, target: nil, action: #selector(barButtonItemPressed(sender:))) 18 | target = self 19 | self.actionHandler = actionHandler 20 | } 21 | 22 | convenience init(barButtonSystemItem systemItem: UIBarButtonItem.SystemItem, actionHandler: ActionHandler?) { 23 | self.init(barButtonSystemItem: systemItem, target: nil, action: #selector(barButtonItemPressed(sender:))) 24 | target = self 25 | self.actionHandler = actionHandler 26 | } 27 | 28 | @objc func barButtonItemPressed(sender: UIBarButtonItem) { 29 | actionHandler?(sender) 30 | } 31 | } 32 | -------------------------------------------------------------------------------- /Source/TriangleDrawMain/UIKit/TDCalculateCubicBezier.swift: -------------------------------------------------------------------------------- 1 | // MIT license. Copyright (c) 2023 TriangleDraw. All rights reserved. 2 | import QuartzCore 3 | 4 | // swiftlint:disable identifier_name 5 | class TDCalculateBezierPoint { 6 | static func calculate(t: CGFloat, p0: CGPoint, p1: CGPoint, p2: CGPoint, p3: CGPoint) -> CGPoint { 7 | let u: CGFloat = 1.0 - t 8 | let tt: CGFloat = t * t 9 | let uu: CGFloat = u * u 10 | let uuu: CGFloat = uu * u 11 | let ttt: CGFloat = tt * t 12 | var x: CGFloat = uuu * p0.x 13 | x += 3 * uu * t * p1.x 14 | x += 3 * u * tt * p2.x 15 | x += ttt * p3.x 16 | var y: CGFloat = uuu * p0.y 17 | y += 3 * uu * t * p1.y 18 | y += 3 * u * tt * p2.y 19 | y += ttt * p3.y 20 | return CGPoint(x: x, y: y) 21 | } 22 | 23 | static func easeInEaseOut(t: CGFloat) -> CGPoint { 24 | let f = CAMediaTimingFunction(name: CAMediaTimingFunctionName.easeInEaseOut) 25 | 26 | var a: [Float] = [0.0, 0.0] 27 | var b: [Float] = [0.0, 0.0] 28 | var c: [Float] = [0.0, 0.0] 29 | var d: [Float] = [0.0, 0.0] 30 | 31 | f.getControlPoint(at: 0, values: &a) 32 | f.getControlPoint(at: 1, values: &b) 33 | f.getControlPoint(at: 2, values: &c) 34 | f.getControlPoint(at: 3, values: &d) 35 | 36 | let p0 = CGPoint(x: CGFloat(a[0]), y: CGFloat(a[1])) 37 | let p1 = CGPoint(x: CGFloat(b[0]), y: CGFloat(b[1])) 38 | let p2 = CGPoint(x: CGFloat(c[0]), y: CGFloat(c[1])) 39 | let p3 = CGPoint(x: CGFloat(d[0]), y: CGFloat(d[1])) 40 | 41 | return calculate(t: t, p0: p0, p1: p1, p2: p2, p3: p3) 42 | } 43 | } 44 | -------------------------------------------------------------------------------- /Source/TriangleDrawMain/UIKit/UIBarButtonItem+NegativeSpacer.swift: -------------------------------------------------------------------------------- 1 | // MIT license. Copyright (c) 2023 TriangleDraw. All rights reserved. 2 | import UIKit 3 | 4 | extension UIBarButtonItem { 5 | class func negativeSpacerWidth(_ width: Int) -> UIBarButtonItem { 6 | let item = UIBarButtonItem(barButtonSystemItem: .fixedSpace, target: nil, action: nil) 7 | item.width = CGFloat(-width) 8 | return item 9 | } 10 | } 11 | -------------------------------------------------------------------------------- /Source/TriangleDrawMain/UIKit/UIColorExtensions.swift: -------------------------------------------------------------------------------- 1 | // MIT license. Copyright (c) 2023 TriangleDraw. All rights reserved. 2 | import UIKit 3 | 4 | extension UIColor { 5 | // usage: 6 | // myButton.backgroundColor = UIColor.rgb(240, 10, 20) 7 | class func rgb(_ red: Int, _ green: Int, _ blue: Int) -> UIColor { 8 | return rgba(red, green, blue, 255) 9 | } 10 | 11 | // usage: 12 | // myButton.backgroundColor = UIColor.rgba(240, 10, 20, 20) 13 | class func rgba(_ red: Int, _ green: Int, _ blue: Int, _ alpha: Int) -> UIColor { 14 | return UIColor( 15 | red: CGFloat(red) / 255.0, 16 | green: CGFloat(green) / 255.0, 17 | blue: CGFloat(blue) / 255.0, 18 | alpha: CGFloat(alpha) / 255.0 19 | ) 20 | } 21 | 22 | // usage: 23 | // myButton.backgroundColor = UIColor.hex(0xaabbcc) 24 | // or 25 | // myButton.backgroundColor = UIColor.hex(0xaabbcc, 0.4) 26 | class func hex(_ hex: Int, _ alpha: Double = 1.0) -> UIColor { 27 | let red = Double((hex & 0xFF0000) >> 16) / 255.0 28 | let green = Double((hex & 0xFF00) >> 8) / 255.0 29 | let blue = Double((hex & 0xFF)) / 255.0 30 | return UIColor(red: CGFloat(red), green: CGFloat(green), blue: CGFloat(blue), alpha: CGFloat(alpha)) 31 | } 32 | 33 | struct ColorRGBA { 34 | var r: Int = 0 35 | var g: Int = 0 36 | var b: Int = 0 37 | var a: Int = 0 38 | } 39 | 40 | func rgba() -> ColorRGBA { 41 | var r: CGFloat = 0 42 | var g: CGFloat = 0 43 | var b: CGFloat = 0 44 | var a: CGFloat = 0 45 | self.getRed(&r, green: &g, blue: &b, alpha: &a) 46 | var rgba = ColorRGBA() 47 | rgba.r = Int(r * 255.0) 48 | rgba.g = Int(g * 255.0) 49 | rgba.b = Int(b * 255.0) 50 | rgba.a = Int(a * 255.0) 51 | return rgba 52 | } 53 | } 54 | -------------------------------------------------------------------------------- /Source/TriangleDrawMain/UIKit/UIEdgeInsets+InsetsByAdding.swift: -------------------------------------------------------------------------------- 1 | // MIT license. Copyright (c) 2023 TriangleDraw. All rights reserved. 2 | import UIKit 3 | 4 | extension UIEdgeInsets { 5 | func insetsByAdding(_ value: CGFloat) -> UIEdgeInsets { 6 | var newInsets = self 7 | newInsets.left += value 8 | newInsets.right += value 9 | newInsets.top += value 10 | newInsets.bottom += value 11 | return newInsets 12 | } 13 | } 14 | -------------------------------------------------------------------------------- /Source/TriangleDrawMain/UIKit/UILabel+TDAlign.swift: -------------------------------------------------------------------------------- 1 | // MIT license. Copyright (c) 2023 TriangleDraw. All rights reserved. 2 | import UIKit 3 | 4 | extension UILabel { 5 | func alignMinX() { 6 | textAlignment = .left 7 | } 8 | 9 | func alignMidX() { 10 | textAlignment = .center 11 | } 12 | 13 | func alignMaxX() { 14 | textAlignment = .right 15 | } 16 | } 17 | -------------------------------------------------------------------------------- /Source/TriangleDrawMain/UIKit/UINavigationItem+BarButtonItemWithTag.swift: -------------------------------------------------------------------------------- 1 | // MIT license. Copyright (c) 2023 TriangleDraw. All rights reserved. 2 | import UIKit 3 | 4 | extension UINavigationItem { 5 | func barButtonItem(withTag tag: Int) -> UIBarButtonItem? { 6 | var items = [UIBarButtonItem]() 7 | items += leftBarButtonItems ?? [] 8 | items += rightBarButtonItems ?? [] 9 | for item: UIBarButtonItem in items { 10 | // swiftlint:disable:next for_where 11 | if item.tag == tag { 12 | return item 13 | } 14 | } 15 | return nil 16 | } 17 | } 18 | -------------------------------------------------------------------------------- /Source/TriangleDrawMain/UIKit/UITextField+TDAlign.swift: -------------------------------------------------------------------------------- 1 | // MIT license. Copyright (c) 2023 TriangleDraw. All rights reserved. 2 | import UIKit 3 | 4 | extension UITextField { 5 | func alignMinX() { 6 | textAlignment = .left 7 | } 8 | 9 | func alignMidX() { 10 | textAlignment = .center 11 | } 12 | 13 | func alignMaxX() { 14 | textAlignment = .right 15 | } 16 | 17 | func alignMinY() { 18 | contentVerticalAlignment = .top 19 | } 20 | 21 | func alignMidY() { 22 | contentVerticalAlignment = .center 23 | } 24 | 25 | func alignMaxY() { 26 | contentVerticalAlignment = .bottom 27 | } 28 | } 29 | -------------------------------------------------------------------------------- /Source/TriangleDrawMain/UIKit/UIView+CenterSubviewConstraints.swift: -------------------------------------------------------------------------------- 1 | // MIT license. Copyright (c) 2023 TriangleDraw. All rights reserved. 2 | import UIKit 3 | 4 | extension UIView { 5 | func addConstraintCenterXSubview(_ subview: UIView) { 6 | addConstraint(NSLayoutConstraint(item: subview, attribute: .centerX, relatedBy: .equal, toItem: self, attribute: .centerX, multiplier: 1, constant: 0)) 7 | } 8 | 9 | func addConstraintCenterYSubview(_ subview: UIView) { 10 | addConstraint(NSLayoutConstraint(item: subview, attribute: .centerY, relatedBy: .equal, toItem: self, attribute: .centerY, multiplier: 1, constant: 0)) 11 | } 12 | } 13 | -------------------------------------------------------------------------------- /Source/TriangleDrawMain/UIKit/UIView+PinToInside.swift: -------------------------------------------------------------------------------- 1 | // MIT license. Copyright (c) 2023 TriangleDraw. All rights reserved. 2 | import UIKit 3 | 4 | extension UIView { 5 | func pinToInside(view child: UIView) { 6 | child.translatesAutoresizingMaskIntoConstraints = false 7 | addSubview(child) 8 | NSLayoutConstraint.activate([ 9 | child.leadingAnchor.constraint(equalTo: leadingAnchor), 10 | child.trailingAnchor.constraint(equalTo: trailingAnchor), 11 | child.topAnchor.constraint(equalTo: safeAreaLayoutGuide.topAnchor), 12 | child.bottomAnchor.constraint(equalTo: safeAreaLayoutGuide.bottomAnchor) 13 | ]) 14 | } 15 | } 16 | -------------------------------------------------------------------------------- /Source/TriangleDrawMain/UIKit/UIView+SuperviewEdgeConstraints.swift: -------------------------------------------------------------------------------- 1 | // MIT license. Copyright (c) 2023 TriangleDraw. All rights reserved. 2 | import UIKit 3 | 4 | extension UIView { 5 | func addConstraintSuperviewEdgeHorizontalSubview(_ subview: UIView) { 6 | let views: [String: Any] = ["subview": subview] 7 | addConstraints(NSLayoutConstraint.constraints(withVisualFormat: "H:|[subview]|", options: [], metrics: nil, views: views)) 8 | } 9 | 10 | func addConstraintSuperviewEdgeVerticalSubview(_ subview: UIView) { 11 | let views: [String: Any] = ["subview": subview] 12 | addConstraints(NSLayoutConstraint.constraints(withVisualFormat: "V:|[subview]|", options: [], metrics: nil, views: views)) 13 | } 14 | } 15 | -------------------------------------------------------------------------------- /Source/TriangleDrawTests/Tests/CGPointTest.swift: -------------------------------------------------------------------------------- 1 | // MIT license. Copyright (c) 2023 TriangleDraw. All rights reserved. 2 | import XCTest 3 | @testable import TriangleDrawMain 4 | 5 | extension CGPoint { 6 | var testString: String { 7 | return String(format: "%.1f %.1f", self.x, self.y) 8 | } 9 | } 10 | 11 | class CGPointTest: XCTestCase { 12 | func testScaleByAroundPoint_zero() { 13 | let result0 = CGPoint.zero.scaleBy(1, aroundPoint: CGPoint.zero).testString 14 | XCTAssertEqual(result0, "0.0 0.0") 15 | let result1 = CGPoint(x: 10, y: 0).scaleBy(2, aroundPoint: CGPoint.zero).testString 16 | XCTAssertEqual(result1, "20.0 0.0") 17 | let result2 = CGPoint(x: -10, y: 0).scaleBy(2, aroundPoint: CGPoint.zero).testString 18 | XCTAssertEqual(result2, "-20.0 0.0") 19 | } 20 | 21 | func testScaleByAroundPoint_plus10() { 22 | let result0 = CGPoint.zero.scaleBy(2, aroundPoint: CGPoint(x: 10, y: 0)).testString 23 | XCTAssertEqual(result0, "-10.0 0.0") 24 | let result1 = CGPoint(x: 10, y: 0).scaleBy(2, aroundPoint: CGPoint(x: 10, y: 0)).testString 25 | XCTAssertEqual(result1, "10.0 0.0") 26 | let result2 = CGPoint(x: 20, y: 0).scaleBy(2, aroundPoint: CGPoint(x: 10, y: 0)).testString 27 | XCTAssertEqual(result2, "30.0 0.0") 28 | } 29 | 30 | func testScaleBy() { 31 | let result0 = CGPoint.zero.scaleBy(10).testString 32 | XCTAssertEqual(result0, "0.0 0.0") 33 | let result1 = CGPoint(x: 3, y: 5).scaleBy(2).testString 34 | XCTAssertEqual(result1, "6.0 10.0") 35 | } 36 | 37 | func testDivideBy() { 38 | let result0 = CGPoint.zero.divideBy(10).testString 39 | XCTAssertEqual(result0, "0.0 0.0") 40 | let result1 = CGPoint(x: 6, y: 10).divideBy(2).testString 41 | XCTAssertEqual(result1, "3.0 5.0") 42 | } 43 | 44 | func testLengthSquared() { 45 | XCTAssertEqual(CGPoint.zero.lengthSquared, 0.0, accuracy: 0.000001) 46 | XCTAssertEqual(CGPoint(x: -2, y: 3).lengthSquared, 13.0, accuracy: 0.000001) 47 | } 48 | } 49 | -------------------------------------------------------------------------------- /Source/TriangleDrawTests/Tests/E2CanvasCopyTests.swift: -------------------------------------------------------------------------------- 1 | // MIT license. Copyright (c) 2023 TriangleDraw. All rights reserved. 2 | import XCTest 3 | @testable import TriangleDrawMain 4 | @testable import TriangleDrawLibrary 5 | 6 | class E2CanvasCopyTests: XCTestCase { 7 | func testCopy() { 8 | let canvas0: E2Canvas = E2Canvas.createBigCanvas() 9 | do { 10 | canvas0.setRawPixel(E2CanvasPoint(x: 0, y: 0), value: 0) 11 | canvas0.setRawPixel(E2CanvasPoint(x: 1, y: 0), value: 10) 12 | canvas0.setRawPixel(E2CanvasPoint(x: 0, y: 1), value: 1) 13 | canvas0.setRawPixel(E2CanvasPoint(x: 1, y: 1), value: 11) 14 | } 15 | let canvas1: E2Canvas = canvas0.createCopy() 16 | do { 17 | XCTAssertTrue(canvas0 !== canvas1) 18 | XCTAssertEqual(canvas0.size.width, canvas1.size.width) 19 | XCTAssertEqual(canvas0.size.height, canvas1.size.height) 20 | XCTAssertEqual(canvas0.cellsPerRow, canvas1.cellsPerRow) 21 | XCTAssertEqual(canvas0.cellsPerColumn, canvas1.cellsPerColumn) 22 | XCTAssertEqual(canvas0.cells.count, canvas1.cells.count) 23 | } 24 | do { 25 | canvas0.setRawPixel(E2CanvasPoint(x: 0, y: 0), value: 255) 26 | canvas0.setRawPixel(E2CanvasPoint(x: 1, y: 0), value: 255) 27 | canvas0.setRawPixel(E2CanvasPoint(x: 0, y: 1), value: 255) 28 | canvas0.setRawPixel(E2CanvasPoint(x: 1, y: 1), value: 255) 29 | } 30 | do { 31 | let value00: UInt8 = canvas0.getPixel(E2CanvasPoint(x: 0, y: 0)) 32 | let value10: UInt8 = canvas0.getPixel(E2CanvasPoint(x: 1, y: 0)) 33 | let value01: UInt8 = canvas0.getPixel(E2CanvasPoint(x: 0, y: 1)) 34 | let value11: UInt8 = canvas0.getPixel(E2CanvasPoint(x: 1, y: 1)) 35 | XCTAssertEqual(value00, 255) 36 | XCTAssertEqual(value10, 255) 37 | XCTAssertEqual(value01, 255) 38 | XCTAssertEqual(value11, 255) 39 | } 40 | do { 41 | let value00: UInt8 = canvas1.getPixel(E2CanvasPoint(x: 0, y: 0)) 42 | let value10: UInt8 = canvas1.getPixel(E2CanvasPoint(x: 1, y: 0)) 43 | let value01: UInt8 = canvas1.getPixel(E2CanvasPoint(x: 0, y: 1)) 44 | let value11: UInt8 = canvas1.getPixel(E2CanvasPoint(x: 1, y: 1)) 45 | XCTAssertEqual(value00, 0) 46 | XCTAssertEqual(value10, 10) 47 | XCTAssertEqual(value01, 1) 48 | XCTAssertEqual(value11, 11) 49 | } 50 | } 51 | } 52 | -------------------------------------------------------------------------------- /Source/TriangleDrawTests/Tests/E2CanvasCountDifferenciesTests.swift: -------------------------------------------------------------------------------- 1 | // MIT license. Copyright (c) 2023 TriangleDraw. All rights reserved. 2 | import XCTest 3 | @testable import TriangleDrawMain 4 | @testable import TriangleDrawLibrary 5 | 6 | // swiftlint:disable identifier_name 7 | class E2CanvasCountDifferenciesTests: XCTestCase { 8 | func point(_ x: Int, _ y: Int) -> E2CanvasPoint { 9 | return E2CanvasPoint(x: x, y: y) 10 | } 11 | 12 | func createCanvas(_ width: UInt, _ height: UInt) -> E2Canvas { 13 | return E2Canvas(canvasSize: E2CanvasSize(width: width, height: height)) 14 | } 15 | 16 | func testCountNoDifference0() { 17 | let c0: E2Canvas = createCanvas(1, 2) 18 | c0.clearWithBlackColor() 19 | let count: UInt = c0.numberOfDifferences(from: c0) 20 | XCTAssertEqual(count, 0) 21 | } 22 | 23 | func testCountNoDifference1() { 24 | let c0: E2Canvas = createCanvas(1, 2) 25 | c0.clearWithBlackColor() 26 | c0.setPixel(point(0, 0), value: 1) 27 | let count: UInt = c0.numberOfDifferences(from: c0) 28 | XCTAssertEqual(count, 0) 29 | } 30 | 31 | func testCount0() { 32 | let c0: E2Canvas = createCanvas(1, 2) 33 | c0.clearWithBlackColor() 34 | let c1: E2Canvas = createCanvas(1, 2) 35 | c1.clearWithBlackColor() 36 | c1.setPixel(point(0, 0), value: 1) 37 | let count: UInt = c0.numberOfDifferences(from: c1) 38 | XCTAssertEqual(count, 1) 39 | } 40 | 41 | func testCount1() { 42 | let c0: E2Canvas = createCanvas(1, 2) 43 | c0.clearWithBlackColor() 44 | c0.setPixel(point(1, 0), value: 1) 45 | let c1: E2Canvas = createCanvas(1, 2) 46 | c1.clearWithBlackColor() 47 | c1.setPixel(point(0, 0), value: 1) 48 | let count: UInt = c0.numberOfDifferences(from: c1) 49 | XCTAssertEqual(count, 2) 50 | } 51 | 52 | func testCount2() { 53 | let c0: E2Canvas = createCanvas(2, 4) 54 | c0.clearWithBlackColor() 55 | c0.setPixel(point(2, 1), value: 1) 56 | let c1: E2Canvas = createCanvas(2, 4) 57 | c1.clearWithBlackColor() 58 | c1.setPixel(point(3, 3), value: 1) 59 | let count: UInt = c0.numberOfDifferences(from: c1) 60 | XCTAssertEqual(count, 2) 61 | } 62 | } 63 | -------------------------------------------------------------------------------- /Source/TriangleDrawTests/Tests/E2CanvasFlipTests.swift: -------------------------------------------------------------------------------- 1 | // MIT license. Copyright (c) 2023 TriangleDraw. All rights reserved. 2 | import XCTest 3 | @testable import TriangleDrawLibrary 4 | 5 | class E2CanvasFlipTests: XCTestCase { 6 | func testFlipX0() { 7 | let canvas: E2Canvas = loadCanvas("test_flipx_simple_before.txt") 8 | let canvasExpected: E2Canvas = loadCanvas("test_flipx_simple_after.txt") 9 | canvas.flipX() 10 | let actual = canvas.stringRepresentation 11 | let expected = canvasExpected.stringRepresentation 12 | XCTAssertEqual(actual, expected) 13 | } 14 | 15 | func testFlipX1() { 16 | let canvas: E2Canvas = loadCanvas("test_flipx_simple2_before.txt") 17 | let canvasExpected: E2Canvas = loadCanvas("test_flipx_simple2_after.txt") 18 | canvas.flipX() 19 | let actual = canvas.stringRepresentation 20 | let expected = canvasExpected.stringRepresentation 21 | XCTAssertEqual(actual, expected) 22 | } 23 | 24 | func testFlipY() { 25 | let canvas: E2Canvas = loadCanvas("test_flipy_simple_before.txt") 26 | let canvasExpected: E2Canvas = loadCanvas("test_flipy_simple_after.txt") 27 | canvas.flipY() 28 | let actual = canvas.stringRepresentation 29 | let expected = canvasExpected.stringRepresentation 30 | XCTAssertEqual(actual, expected) 31 | } 32 | } 33 | -------------------------------------------------------------------------------- /Source/TriangleDrawTests/Tests/E2CanvasHistogramTests.swift: -------------------------------------------------------------------------------- 1 | // MIT license. Copyright (c) 2023 TriangleDraw. All rights reserved. 2 | import XCTest 3 | @testable import TriangleDrawLibrary 4 | 5 | class E2CanvasHistogramTests: XCTestCase { 6 | func point(_ x: Int, _ y: Int) -> E2CanvasPoint { 7 | return E2CanvasPoint(x: x, y: y) 8 | } 9 | 10 | func test0() { 11 | let canvas: E2Canvas = loadCanvas("test_histogram0.txt") 12 | let result = canvas.histogram() 13 | XCTAssertEqual(result.count, 2) 14 | XCTAssertEqual(result[0], 11375) 15 | XCTAssertEqual(result[1], 241) 16 | } 17 | 18 | func test1() { 19 | let canvas: E2Canvas = loadCanvas("test_histogram1.txt") 20 | let result = canvas.histogram() 21 | XCTAssertEqual(result.count, 2) 22 | XCTAssertEqual(result[0], 241) 23 | XCTAssertEqual(result[1], 11375) 24 | } 25 | 26 | func test2() { 27 | let canvas: E2Canvas = E2Canvas.createBigCanvas() 28 | canvas.inner_setPixel(point: point(60, 52), value: 1, sanitize: false) 29 | canvas.inner_setPixel(point: point(60, 53), value: 1, sanitize: false) 30 | canvas.inner_setPixel(point: point(60, 54), value: 1, sanitize: false) 31 | canvas.inner_setPixel(point: point(90, 52), value: 5, sanitize: false) 32 | canvas.inner_setPixel(point: point(90, 53), value: 5, sanitize: false) 33 | canvas.inner_setPixel(point: point(90, 54), value: 5, sanitize: false) 34 | let result = canvas.histogram() 35 | XCTAssertEqual(result.count, 3) 36 | XCTAssertEqual(result[0], 11610) 37 | XCTAssertEqual(result[1], 3) 38 | XCTAssertEqual(result[5], 3) 39 | } 40 | } 41 | -------------------------------------------------------------------------------- /Source/TriangleDrawTests/Tests/E2CanvasPointOrientationTests.swift: -------------------------------------------------------------------------------- 1 | // MIT license. Copyright (c) 2023 TriangleDraw. All rights reserved. 2 | import XCTest 3 | @testable import TriangleDrawLibrary 4 | 5 | class E2CanvasPointOrientationTests: XCTestCase { 6 | func testUpward() { 7 | let canvas: E2Canvas = loadCanvas("test_orientation_upward.pbm") 8 | var countUpward: UInt = 0 9 | var countDownward: UInt = 0 10 | for y in 0..(capacity: 3, defaultValue: 1) 9 | do { 10 | let values: [Int] = fifo.array 11 | XCTAssertEqual(values, [1, 1, 1]) 12 | } 13 | fifo.append(2) 14 | do { 15 | let values: [Int] = fifo.array 16 | XCTAssertEqual(values, [1, 1, 2]) 17 | } 18 | fifo.append(3) 19 | do { 20 | let values: [Int] = fifo.array 21 | XCTAssertEqual(values, [1, 2, 3]) 22 | } 23 | fifo.append(4) 24 | do { 25 | let values: [Int] = fifo.array 26 | XCTAssertEqual(values, [2, 3, 4]) 27 | } 28 | fifo.append(5) 29 | do { 30 | let values: [Int] = fifo.array 31 | XCTAssertEqual(values, [3, 4, 5]) 32 | } 33 | } 34 | } 35 | -------------------------------------------------------------------------------- /Source/TriangleDrawTests/Tests/TestData_ParsePBM/test_parsepbm_comments3.pbm: -------------------------------------------------------------------------------- 1 | P1 2 | # This is Ripley 3 | # last survivor of the Nostromo 4 | # signing off 5 | 1 1 6 | 1 7 | -------------------------------------------------------------------------------- /Source/TriangleDrawTests/Tests/TestData_ParsePBM/test_parsepbm_illegal_cell_values.pbm: -------------------------------------------------------------------------------- 1 | P1 2 | # {"FileFormat":3,"ToolName":"TriangleDraw-iOS","ToolVersion":"2019.1.1","AuthorName":"Simon Strandgaard"} 3 | 4 3 4 | 1 1 1 1 5 | 1 666 1 0 6 | 0 0 0 0 -------------------------------------------------------------------------------- /Source/TriangleDrawTests/Tests/TestData_ParsePBM/test_parsepbm_invalid1.pbm: -------------------------------------------------------------------------------- 1 | This is an invalid file. 2 | It's not a TriangleDraw file. -------------------------------------------------------------------------------- /Source/TriangleDrawTests/Tests/TestData_ParsePBM/test_parsepbm_negative_height.pbm: -------------------------------------------------------------------------------- 1 | P1 2 | # {"FileFormat":3,"ToolName":"TriangleDraw-iOS","ToolVersion":"2019.1.1","AuthorName":"Simon Strandgaard"} 3 | 4 -3 4 | 1 1 1 1 5 | 1 0 1 0 6 | 0 0 0 0 -------------------------------------------------------------------------------- /Source/TriangleDrawTests/Tests/TestData_ParsePBM/test_parsepbm_negative_width.pbm: -------------------------------------------------------------------------------- 1 | P1 2 | # {"FileFormat":3,"ToolName":"TriangleDraw-iOS","ToolVersion":"2019.1.1","AuthorName":"Simon Strandgaard"} 3 | -4 3 4 | 1 1 1 1 5 | 1 0 1 0 6 | 0 0 0 0 -------------------------------------------------------------------------------- /Source/TriangleDrawTests/Tests/TestData_ParsePBM/test_parsepbm_simple1.pbm: -------------------------------------------------------------------------------- 1 | P1 2 | # {"FileFormat":3,"ToolName":"TriangleDraw-iOS","ToolVersion":"2019.1.1","AuthorName":"Simon Strandgaard"} 3 | 1 1 4 | 0 -------------------------------------------------------------------------------- /Source/TriangleDrawTests/Tests/TestData_ParsePBM/test_parsepbm_simple2.pbm: -------------------------------------------------------------------------------- 1 | P1 2 | # {"FileFormat":3,"ToolName":"TriangleDraw-iOS","ToolVersion":"2019.1.1","AuthorName":"Simon Strandgaard"} 3 | 4 3 4 | 1 1 1 1 5 | 1 0 1 0 6 | 0 0 0 0 -------------------------------------------------------------------------------- /Source/TriangleDrawTests/Tests/TestData_ParsePBM/test_parsepbm_spacing1.pbm: -------------------------------------------------------------------------------- 1 | P1 2 | # {"FileFormat":3,"ToolName":"TriangleDraw-iOS","ToolVersion":"2019.1.1","AuthorName":"Simon Strandgaard"} 3 | 2 2 4 | 5 | 0 1 6 | #test 7 | 1 0 8 | 9 | 10 | -------------------------------------------------------------------------------- /Source/TriangleDrawTests/Tests/TestData_ParsePBM/test_parsepbm_utf16be.pbm: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/triangledraw/TriangleDraw-iOS/25bc87c479cd10b461a17834b67d99d911f7cc34/Source/TriangleDrawTests/Tests/TestData_ParsePBM/test_parsepbm_utf16be.pbm -------------------------------------------------------------------------------- /Source/TriangleDrawTests/Tests/TestData_ParsePBM/test_parsepbm_utf16le.pbm: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/triangledraw/TriangleDraw-iOS/25bc87c479cd10b461a17834b67d99d911f7cc34/Source/TriangleDrawTests/Tests/TestData_ParsePBM/test_parsepbm_utf16le.pbm -------------------------------------------------------------------------------- /Source/TriangleDrawTests/Tests/TestData_ParsePBM/test_parsepbm_utf8.pbm: -------------------------------------------------------------------------------- 1 | P1 2 | # This is UTF8 encoded. Danish letters: ÆØÅ 3 | 1 1 4 | 0 -------------------------------------------------------------------------------- /Source/TriangleDrawTests/Tests/TestData_ReadWrite/test_readwrite_wrongdimensions1.pbm: -------------------------------------------------------------------------------- 1 | P1 2 | # {"FileFormat":3,"ToolName":"TriangleDraw-iOS","ToolVersion":"2019.1.1","AuthorName":"Simon Strandgaard"} 3 | 4 3 4 | 1 1 1 1 5 | 1 0 0 1 6 | 1 1 1 1 -------------------------------------------------------------------------------- /Source/TriangleDrawTests/Tests/Tests-Bridging-Header.h: -------------------------------------------------------------------------------- 1 | // 2 | // Use this file to import your target's public headers that you would like to expose to Swift. 3 | // 4 | #import "TriangleDrawMain-Bridging-Header.h" 5 | -------------------------------------------------------------------------------- /Source/TriangleDrawTests/Tests/Tests-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 | CFBundlePackageType 14 | BNDL 15 | CFBundleShortVersionString 16 | 1.0 17 | CFBundleSignature 18 | ???? 19 | CFBundleVersion 20 | 1 21 | 22 | 23 | -------------------------------------------------------------------------------- /Source/TriangleDrawTests/Tests/URLDisplayNameTests.swift: -------------------------------------------------------------------------------- 1 | // MIT license. Copyright (c) 2023 TriangleDraw. All rights reserved. 2 | import XCTest 3 | @testable import TriangleDrawMain 4 | 5 | class URLDisplayNameTests: XCTestCase { 6 | func testFileURL_simple() { 7 | let url: URL = URL(fileURLWithPath: "file:///var/mobile/Containers/Data/Application/1FB629DF-2E96-4047-BF06-373BB57A1965/Documents/Mona%20Lisa.triangleDraw/") 8 | let name: String = url.triangleDraw_displayName 9 | XCTAssertEqual(name, "Mona Lisa") 10 | } 11 | 12 | func testFileURL_emoji_flagForKenya() { 13 | // Filename containing the kenyan flag: 🇰🇪 14 | // https://emojipedia.org/flag-for-kenya/ 15 | let url: URL = URL(fileURLWithPath: "file:///var/mobile/Containers/Data/Application/1FB629DF-2E96-4047-BF06-373BB57A1965/Documents/%F0%9F%87%B0%F0%9F%87%AA.triangleDraw/") 16 | let name: String = url.triangleDraw_displayName 17 | let data: Data = name.data(using: String.Encoding.utf8, allowLossyConversion: false) ?? Data() 18 | let base64: String = data.base64EncodedString() 19 | XCTAssertEqual(base64, "8J+HsPCfh6o=") 20 | } 21 | 22 | func testWebURL_garbage() { 23 | // `triangleDraw_displayName` is intended to work with fileURL's 24 | // `triangleDraw_displayName` is not supposed to be used with web URLs, thus garbage 25 | do { 26 | let url: URL = URL(string: "https://example.com/monalisa")! 27 | XCTAssertEqual(url.triangleDraw_displayName, "monalisa") 28 | } 29 | do { 30 | let url: URL = URL(string: "https://example.com/monalisa.png?x=3")! 31 | XCTAssertEqual(url.triangleDraw_displayName, "monalisa") 32 | } 33 | do { 34 | let url: URL = URL(string: "https://example.com")! 35 | XCTAssertEqual(url.triangleDraw_displayName, "") 36 | } 37 | do { 38 | let url: URL = URL(string: "https://")! 39 | XCTAssertEqual(url.triangleDraw_displayName, "") 40 | } 41 | } 42 | } 43 | -------------------------------------------------------------------------------- /Source/TriangleDrawTests/Tests/XCTestCase+LoadCanvas.swift: -------------------------------------------------------------------------------- 1 | // MIT license. Copyright (c) 2023 TriangleDraw. All rights reserved. 2 | import XCTest 3 | @testable import TriangleDrawMain 4 | @testable import TriangleDrawLibrary 5 | 6 | extension XCTestCase { 7 | func loadCanvas(_ resourceName: String) -> E2Canvas { 8 | if resourceName.hasSuffix(".txt") { 9 | return loadCanvasFromTextFile(resourceName) 10 | } 11 | if resourceName.hasSuffix(".pbm") { 12 | guard let canvas: E2Canvas = loadCanvasFromPBMFile(resourceName) else { 13 | fatalError("Unable to load PBM file for resource: \(resourceName)") 14 | } 15 | return canvas 16 | } 17 | fatalError() 18 | } 19 | 20 | func loadCanvasFromTextFile(_ resourceName: String) -> E2Canvas { 21 | guard let url: URL = Bundle(for: type(of: self)).url(forResource: resourceName, withExtension: nil) else { 22 | log.error("no url for resource: \(resourceName)") 23 | fatalError() 24 | } 25 | guard let content = try? String(contentsOf: url, encoding: .utf8) else { 26 | log.error("Unable to load file for resource: \(resourceName) at url: \(url)") 27 | fatalError() 28 | } 29 | let canvas: E2Canvas = E2Canvas.createBigCanvas() 30 | canvas.load(fromStringRepresentation: content) 31 | return canvas 32 | } 33 | 34 | func loadCanvasFromPBMFile(_ resourceName: String) -> E2Canvas? { 35 | guard let url: URL = Bundle(for: type(of: self)).url(forResource: resourceName, withExtension: nil) else { 36 | //print("no url for resource: \(resourceName)") 37 | return nil 38 | } 39 | guard let content: Data = try? Data(contentsOf: url) else { 40 | //print("unable to read file: \(url)") 41 | return nil 42 | } 43 | let canvas: E2Canvas? = try? TDCanvasReader.canvas(fromPBMRepresentation: content) 44 | return canvas 45 | } 46 | 47 | func loadCanvasMask() -> E2Canvas { 48 | return E2Canvas.bigCanvasMask_create() 49 | } 50 | 51 | } 52 | -------------------------------------------------------------------------------- /Source/TriangleDrawTests/Tests/en.lproj/InfoPlist.strings: -------------------------------------------------------------------------------- 1 | /* Localized versions of Info.plist keys */ 2 | 3 | -------------------------------------------------------------------------------- /Source/TriangleDrawTests/UITests/Info.plist: -------------------------------------------------------------------------------- 1 | 2 | 3 | 4 | 5 | CFBundleDevelopmentRegion 6 | $(DEVELOPMENT_LANGUAGE) 7 | CFBundleExecutable 8 | $(EXECUTABLE_NAME) 9 | CFBundleIdentifier 10 | $(PRODUCT_BUNDLE_IDENTIFIER) 11 | CFBundleInfoDictionaryVersion 12 | 6.0 13 | CFBundleName 14 | $(PRODUCT_NAME) 15 | CFBundlePackageType 16 | $(PRODUCT_BUNDLE_PACKAGE_TYPE) 17 | CFBundleShortVersionString 18 | 1.0 19 | CFBundleVersion 20 | 1 21 | 22 | 23 | -------------------------------------------------------------------------------- /Source/TriangleDrawTests/UITests/UITests.swift: -------------------------------------------------------------------------------- 1 | // MIT license. Copyright (c) 2023 TriangleDraw. All rights reserved. 2 | import XCTest 3 | 4 | class UITests: XCTestCase { 5 | override func setUp() { 6 | // In UI tests it is usually best to stop immediately when a failure occurs. 7 | continueAfterFailure = false 8 | } 9 | 10 | func testCaptureScreenshot_browserWithDocumentExamples() { 11 | let app = XCUIApplication() 12 | setupSnapshot(app) 13 | app.launchArguments.append("-ScreenshotBrowserImportDocumentExamples") 14 | app.launchArguments.append("true") 15 | app.launch() 16 | snapshot("0browser") 17 | } 18 | 19 | func testCaptureScreenshot_canvasWithTriangleDrawLogo() { 20 | let app = XCUIApplication() 21 | setupSnapshot(app) 22 | app.launchArguments.append("-ScreenshotCanvasWithTriangleDrawLogo") 23 | app.launchArguments.append("true") 24 | app.launch() 25 | snapshot("1canvas") 26 | } 27 | 28 | func testCaptureScreenshot_canvasWithRune() { 29 | let app = XCUIApplication() 30 | setupSnapshot(app) 31 | app.launchArguments.append("-ScreenshotCanvasWithRune") 32 | app.launchArguments.append("true") 33 | app.launch() 34 | snapshot("2canvas") 35 | } 36 | } 37 | -------------------------------------------------------------------------------- /Source/TriangleDrawThumbnail/Images.xcassets/Contents.json: -------------------------------------------------------------------------------- 1 | { 2 | "info" : { 3 | "version" : 1, 4 | "author" : "xcode" 5 | } 6 | } -------------------------------------------------------------------------------- /Source/TriangleDrawThumbnail/Images.xcassets/boom.imageset/Contents.json: -------------------------------------------------------------------------------- 1 | { 2 | "images" : [ 3 | { 4 | "idiom" : "universal", 5 | "filename" : "boom.png", 6 | "scale" : "1x" 7 | }, 8 | { 9 | "idiom" : "universal", 10 | "scale" : "2x" 11 | }, 12 | { 13 | "idiom" : "universal", 14 | "scale" : "3x" 15 | } 16 | ], 17 | "info" : { 18 | "version" : 1, 19 | "author" : "xcode" 20 | } 21 | } -------------------------------------------------------------------------------- /Source/TriangleDrawThumbnail/Images.xcassets/boom.imageset/boom.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/triangledraw/TriangleDraw-iOS/25bc87c479cd10b461a17834b67d99d911f7cc34/Source/TriangleDrawThumbnail/Images.xcassets/boom.imageset/boom.png -------------------------------------------------------------------------------- /Source/TriangleDrawThumbnail/Info.plist: -------------------------------------------------------------------------------- 1 | 2 | 3 | 4 | 5 | CFBundleDevelopmentRegion 6 | $(DEVELOPMENT_LANGUAGE) 7 | CFBundleDisplayName 8 | TriangleDrawThumbnail 9 | CFBundleExecutable 10 | $(EXECUTABLE_NAME) 11 | CFBundleIdentifier 12 | $(PRODUCT_BUNDLE_IDENTIFIER) 13 | CFBundleInfoDictionaryVersion 14 | 6.0 15 | CFBundleName 16 | $(PRODUCT_NAME) 17 | CFBundlePackageType 18 | XPC! 19 | CFBundleShortVersionString 20 | $(MARKETING_VERSION) 21 | CFBundleVersion 22 | $(CURRENT_PROJECT_VERSION) 23 | ITSAppUsesNonExemptEncryption 24 | 25 | LSEnvironment 26 | 27 | CG_CONTEXT_SHOW_BACKTRACE 28 | YES 29 | OS_ACTIVITY_MODE 30 | default 31 | 32 | NSExtension 33 | 34 | NSExtensionAttributes 35 | 36 | QLSupportedContentTypes 37 | 38 | com.triangledraw.td3.doc 39 | 40 | 41 | NSExtensionPointIdentifier 42 | com.apple.quicklook.thumbnail 43 | NSExtensionPrincipalClass 44 | $(PRODUCT_MODULE_NAME).ThumbnailProvider 45 | 46 | 47 | 48 | -------------------------------------------------------------------------------- /Source/TriangleDrawThumbnail/TriangleDrawThumbnail.entitlements: -------------------------------------------------------------------------------- 1 | 2 | 3 | 4 | 5 | com.apple.security.application-groups 6 | 7 | group.com.triangledraw.td3 8 | 9 | 10 | 11 | -------------------------------------------------------------------------------- /Source/fastlane/Fastfile: -------------------------------------------------------------------------------- 1 | 2 | # Capture screenshots of the canvas 3 | # 4 | # Before running this, the "UITests" must manually added to the "tests". 5 | # This is far from optimal. 6 | # 7 | # This only works with Xcode11 or newer 8 | # The HexagonCanvas uses Metal. Xcode11beta4 or newer supports Metal in the simulator. 9 | # 10 | # Xcode10.x doesn't support Metal in the simulator, so it's not possible to capture screenshots of the canvas in that setup. 11 | # 12 | # Unfortunately Xcode11beta4 or newer doesn't have a working UIDocumentBrowserViewController. It doesn't show any thumbnails of the documents. 13 | # So it's not possible to use Xcode11 for capturing screenshots of the browser. 14 | # 15 | # What would be nice is an Xcode that have: 16 | # - Metal support 17 | # - UIDocuemntBrowserViewController 18 | # - Doesn't crash when running UITests. 19 | # 20 | lane :snapshot_canvas do 21 | xcode_select("/Applications/Xcode.app") 22 | 23 | my_devices = [ 24 | # iPad 12.9" display 25 | "iPad Pro (12.9-inch) (6th generation)", 26 | "iPad Pro (12.9-inch) (2nd generation)", 27 | 28 | # iPhone 6.7" display 29 | "iPhone 14 Pro Max", 30 | 31 | # iPhone 6.5" display 32 | "iPhone Xs Max", 33 | 34 | # iPhone 5.5" display 35 | "iPhone 8 Plus", 36 | ] 37 | capture_ios_screenshots( 38 | devices: my_devices, 39 | ios_version: '16.0', 40 | skip_open_summary: true, 41 | clean: false, 42 | stop_after_first_error: true, 43 | concurrent_simulators: false 44 | ) 45 | end 46 | -------------------------------------------------------------------------------- /Source/fastlane/README.md: -------------------------------------------------------------------------------- 1 | fastlane documentation 2 | ---- 3 | 4 | # Installation 5 | 6 | Make sure you have the latest version of the Xcode command line tools installed: 7 | 8 | ```sh 9 | xcode-select --install 10 | ``` 11 | 12 | For _fastlane_ installation instructions, see [Installing _fastlane_](https://docs.fastlane.tools/#installing-fastlane) 13 | 14 | # Available Actions 15 | 16 | ### snapshot_canvas 17 | 18 | ```sh 19 | [bundle exec] fastlane snapshot_canvas 20 | ``` 21 | 22 | 23 | 24 | ---- 25 | 26 | This README.md is auto-generated and will be re-generated every time [_fastlane_](https://fastlane.tools) is run. 27 | 28 | More information about _fastlane_ can be found on [fastlane.tools](https://fastlane.tools). 29 | 30 | The documentation of _fastlane_ can be found on [docs.fastlane.tools](https://docs.fastlane.tools). 31 | -------------------------------------------------------------------------------- /Source/fastlane/report.xml: -------------------------------------------------------------------------------- 1 | 2 | 3 | 4 | 5 | 6 | 7 | 8 | 9 | 10 | 11 | 12 | 13 | 14 | 15 | 16 | 17 | 18 | 19 | -------------------------------------------------------------------------------- /Source/fastlane/screenshots/en-US/iPad Pro (12.9-inch) (2nd generation)-0browser.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/triangledraw/TriangleDraw-iOS/25bc87c479cd10b461a17834b67d99d911f7cc34/Source/fastlane/screenshots/en-US/iPad Pro (12.9-inch) (2nd generation)-0browser.png -------------------------------------------------------------------------------- /Source/fastlane/screenshots/en-US/iPad Pro (12.9-inch) (2nd generation)-1canvas.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/triangledraw/TriangleDraw-iOS/25bc87c479cd10b461a17834b67d99d911f7cc34/Source/fastlane/screenshots/en-US/iPad Pro (12.9-inch) (2nd generation)-1canvas.png -------------------------------------------------------------------------------- /Source/fastlane/screenshots/en-US/iPad Pro (12.9-inch) (2nd generation)-2canvas.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/triangledraw/TriangleDraw-iOS/25bc87c479cd10b461a17834b67d99d911f7cc34/Source/fastlane/screenshots/en-US/iPad Pro (12.9-inch) (2nd generation)-2canvas.png -------------------------------------------------------------------------------- /Source/fastlane/screenshots/en-US/iPad Pro (12.9-inch) (6th generation)-0browser.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/triangledraw/TriangleDraw-iOS/25bc87c479cd10b461a17834b67d99d911f7cc34/Source/fastlane/screenshots/en-US/iPad Pro (12.9-inch) (6th generation)-0browser.png -------------------------------------------------------------------------------- /Source/fastlane/screenshots/en-US/iPad Pro (12.9-inch) (6th generation)-1canvas.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/triangledraw/TriangleDraw-iOS/25bc87c479cd10b461a17834b67d99d911f7cc34/Source/fastlane/screenshots/en-US/iPad Pro (12.9-inch) (6th generation)-1canvas.png -------------------------------------------------------------------------------- /Source/fastlane/screenshots/en-US/iPad Pro (12.9-inch) (6th generation)-2canvas.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/triangledraw/TriangleDraw-iOS/25bc87c479cd10b461a17834b67d99d911f7cc34/Source/fastlane/screenshots/en-US/iPad Pro (12.9-inch) (6th generation)-2canvas.png -------------------------------------------------------------------------------- /Source/fastlane/screenshots/en-US/iPhone 14 Pro Max-0browser.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/triangledraw/TriangleDraw-iOS/25bc87c479cd10b461a17834b67d99d911f7cc34/Source/fastlane/screenshots/en-US/iPhone 14 Pro Max-0browser.png -------------------------------------------------------------------------------- /Source/fastlane/screenshots/en-US/iPhone 14 Pro Max-1canvas.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/triangledraw/TriangleDraw-iOS/25bc87c479cd10b461a17834b67d99d911f7cc34/Source/fastlane/screenshots/en-US/iPhone 14 Pro Max-1canvas.png -------------------------------------------------------------------------------- /Source/fastlane/screenshots/en-US/iPhone 14 Pro Max-2canvas.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/triangledraw/TriangleDraw-iOS/25bc87c479cd10b461a17834b67d99d911f7cc34/Source/fastlane/screenshots/en-US/iPhone 14 Pro Max-2canvas.png -------------------------------------------------------------------------------- /Source/fastlane/screenshots/en-US/iPhone 8 Plus-0browser.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/triangledraw/TriangleDraw-iOS/25bc87c479cd10b461a17834b67d99d911f7cc34/Source/fastlane/screenshots/en-US/iPhone 8 Plus-0browser.png -------------------------------------------------------------------------------- /Source/fastlane/screenshots/en-US/iPhone 8 Plus-1canvas.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/triangledraw/TriangleDraw-iOS/25bc87c479cd10b461a17834b67d99d911f7cc34/Source/fastlane/screenshots/en-US/iPhone 8 Plus-1canvas.png -------------------------------------------------------------------------------- /Source/fastlane/screenshots/en-US/iPhone 8 Plus-2canvas.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/triangledraw/TriangleDraw-iOS/25bc87c479cd10b461a17834b67d99d911f7cc34/Source/fastlane/screenshots/en-US/iPhone 8 Plus-2canvas.png -------------------------------------------------------------------------------- /Source/fastlane/screenshots/en-US/iPhone Xs Max-0browser.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/triangledraw/TriangleDraw-iOS/25bc87c479cd10b461a17834b67d99d911f7cc34/Source/fastlane/screenshots/en-US/iPhone Xs Max-0browser.png -------------------------------------------------------------------------------- /Source/fastlane/screenshots/en-US/iPhone Xs Max-1canvas.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/triangledraw/TriangleDraw-iOS/25bc87c479cd10b461a17834b67d99d911f7cc34/Source/fastlane/screenshots/en-US/iPhone Xs Max-1canvas.png -------------------------------------------------------------------------------- /Source/fastlane/screenshots/en-US/iPhone Xs Max-2canvas.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/triangledraw/TriangleDraw-iOS/25bc87c479cd10b461a17834b67d99d911f7cc34/Source/fastlane/screenshots/en-US/iPhone Xs Max-2canvas.png --------------------------------------------------------------------------------