Skip to content

Commit

Permalink
Finish extracting Redactions module after merging Observations
Browse files Browse the repository at this point in the history
  • Loading branch information
Arclite committed May 9, 2024
2 parents bb7e22a + 0b7cac6 commit 24f5766
Show file tree
Hide file tree
Showing 68 changed files with 270 additions and 133 deletions.
1 change: 1 addition & 0 deletions Automator/Sources/RedactActionExportOperation.swift
Original file line number Diff line number Diff line change
Expand Up @@ -3,6 +3,7 @@

import AppKit
import Redacting
import Redactions

class RedactActionExportOperation: Operation {
var result: Result<String, Error>?
Expand Down
1 change: 1 addition & 0 deletions Automator/Sources/RedactOperation.swift
Original file line number Diff line number Diff line change
Expand Up @@ -3,6 +3,7 @@

import Foundation
import Redacting
import Redactions

class RedactOperation: Operation {
var result: Result<String, Error>?
Expand Down
1 change: 1 addition & 0 deletions Automator/Sources/RedactedImageExporter.swift
Original file line number Diff line number Diff line change
Expand Up @@ -3,6 +3,7 @@

import AppKit
import Redacting
import Redactions

class RedactActionExporter: NSObject {
static func export(_ input: RedactActionInput, redactions: [Redaction], completionHandler: @escaping((Result<String, Error>) -> Void)) {
Expand Down
Original file line number Diff line number Diff line change
@@ -0,0 +1,25 @@
// Created by Geoff Pado on 5/8/24.
// Copyright © 2024 Cocoatype, LLC. All rights reserved.

import CoreGraphics

extension CGPoint {
static func flippedPoint(from point: CGPoint, scaledTo size: CGSize) -> CGPoint {
var scaledPoint = point

#if canImport(UIKit)
scaledPoint.y = (1.0 - scaledPoint.y)
#endif

scaledPoint.x *= size.width
scaledPoint.y *= size.height

return scaledPoint
}
}

extension CGSize {
static func * (size: CGSize, multiplier: CGFloat) -> CGSize {
return CGSize(width: size.width * multiplier, height: size.height * multiplier)
}
}
Original file line number Diff line number Diff line change
@@ -1,7 +1,7 @@
// Created by Geoff Pado on 5/29/20.
// Copyright © 2020 Cocoatype, LLC. All rights reserved.

public extension String {
extension String {
var words: [(String, Range<String.Index>)] {
var words = [(String, Range<String.Index>)]()
enumerateSubstrings(in: startIndex..<endIndex, options: [.byWords]) { word, wordRange, _, _ in
Expand Down
Original file line number Diff line number Diff line change
@@ -0,0 +1,10 @@
// Created by Geoff Pado on 5/1/19.
// Copyright © 2019 Cocoatype, LLC. All rights reserved.

import CoreGraphics
import Foundation

public struct CharacterObservation: Hashable {
public let bounds: Shape
public let textObservationUUID: UUID
}
Original file line number Diff line number Diff line change
Expand Up @@ -5,7 +5,7 @@ import Foundation
import Vision

public struct RecognizedTextObservation: TextObservation, RedactableObservation {
init?(_ recognizedText: RecognizedText, imageSize: CGSize) {
public init?(_ recognizedText: RecognizedText, imageSize: CGSize) {
self.recognizedText = recognizedText
self.imageSize = imageSize

Expand Down Expand Up @@ -42,7 +42,7 @@ public struct RecognizedTextObservation: TextObservation, RedactableObservation
}
}

var allWordObservations: [WordObservation] {
public var allWordObservations: [WordObservation] {
wordObservations { _, _ in true }
}

Expand All @@ -55,7 +55,7 @@ public struct RecognizedTextObservation: TextObservation, RedactableObservation
private let recognizedText: RecognizedText
private let imageSize: CGSize

let characterObservations: [CharacterObservation]
public let characterObservations: [CharacterObservation]
}

extension Shape {
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -3,6 +3,6 @@

import Foundation

protocol RedactableObservation {
public protocol RedactableObservation {
var characterObservations: [CharacterObservation] { get }
}
Original file line number Diff line number Diff line change
Expand Up @@ -7,6 +7,6 @@ public protocol TextObservation: Equatable {
var bounds: Shape { get }
}

extension TextObservation {
public extension TextObservation {
var path: CGPath { bounds.path }
}
Original file line number Diff line number Diff line change
@@ -1,22 +1,26 @@
// Created by Geoff Pado on 5/17/22.
// Copyright © 2022 Cocoatype, LLC. All rights reserved.

import Vision

#if canImport(AppKit)
import AppKit
#elseif canImport(UIKit)
#endif

#if canImport(UIKit)
import UIKit
#endif

import Vision

public struct TextRectangleObservation: TextObservation, RedactableObservation {
#if canImport(UIKit)
init(_ textObservation: VNTextObservation, in image: UIImage) {
public init(_ textObservation: VNTextObservation, in image: UIImage) {
let imageSize = image.size * image.scale
self.init(textObservation, scaledTo: imageSize)
}
#elseif canImport(AppKit)
init(_ textObservation: VNTextObservation, in image: NSImage) {
#endif

#if canImport(AppKit) && !targetEnvironment(macCatalyst)
public init(_ textObservation: VNTextObservation, in image: NSImage) {
self.init(textObservation, scaledTo: image.size)
}
#endif
Expand All @@ -32,5 +36,5 @@ public struct TextRectangleObservation: TextObservation, RedactableObservation {
}

public let bounds: Shape
let characterObservations: [CharacterObservation]
public let characterObservations: [CharacterObservation]
}
Original file line number Diff line number Diff line change
@@ -1,11 +1,8 @@
// Created by Geoff Pado on 5/17/22.
// Copyright © 2022 Cocoatype, LLC. All rights reserved.

#if canImport(AppKit)
import AppKit
#elseif canImport(UIKit)
import UIKit
#endif
import CoreGraphics
import Foundation

public struct WordObservation: TextObservation {
init?(recognizedText: RecognizedText, string: String, range: Range<String.Index>, imageSize: CGSize) {
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -3,23 +3,23 @@

import Vision

struct RecognizedText: Equatable {
public struct RecognizedText: Equatable {
let recognizedText: VisionText
let uuid: UUID

var string: String { recognizedText.string }

init(recognizedText: VisionText, uuid: UUID) {
public init(recognizedText: VisionText, uuid: UUID) {
self.recognizedText = recognizedText
self.uuid = uuid
}

static func == (lhs: RecognizedText, rhs: RecognizedText) -> Bool {
public static func == (lhs: RecognizedText, rhs: RecognizedText) -> Bool {
lhs.uuid == rhs.uuid
}
}

protocol VisionText {
public protocol VisionText {
func boundingBox(for range: Range<String.Index>) throws -> VNRectangleObservation?
var string: String { get }
}
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -10,7 +10,7 @@ public struct Shape: Hashable {
public let topLeft: CGPoint
public let topRight: CGPoint

internal init(bottomLeft: CGPoint, bottomRight: CGPoint, topLeft: CGPoint, topRight: CGPoint) {
public init(bottomLeft: CGPoint, bottomRight: CGPoint, topLeft: CGPoint, topRight: CGPoint) {
self.bottomLeft = bottomLeft
self.bottomRight = bottomRight
self.topLeft = topLeft
Expand All @@ -26,9 +26,9 @@ public struct Shape: Hashable {
)
}

var boundingBox: CGRect { path.boundingBox }
public var boundingBox: CGRect { path.boundingBox }

var path: CGPath {
public var path: CGPath {
let path = CGMutablePath()
path.move(to: topLeft)
path.addLine(to: bottomLeft)
Expand All @@ -52,22 +52,22 @@ public struct Shape: Hashable {
)
}

var angle: Double {
public var angle: Double {
guard (centerRight.x - centerLeft.x) != 0 else { return .pi / 2 }
// leftyLoosey by @KaenAitch on 2/3/22
// the slope of the primary axis of the shape
let leftyLoosey = Double((centerRight.y - centerLeft.y) / (centerRight.x - centerLeft.x))
return atan(leftyLoosey)
}

var center: CGPoint {
public var center: CGPoint {
CGPoint(
x: (topLeft.x + bottomLeft.x + bottomRight.x + topRight.x) / 4.0,
y: (topLeft.y + bottomLeft.y + bottomRight.y + topRight.y) / 4.0
)
}

func union(_ other: Shape) -> Shape {
public func union(_ other: Shape) -> Shape {
let transform = CGAffineTransformMakeRotation(angle)

let ourRotatedCenterLeft = centerLeft.applying(transform)
Expand Down Expand Up @@ -95,11 +95,11 @@ public struct Shape: Hashable {
}

static let zero = Shape(bottomLeft: .zero, bottomRight: .zero, topLeft: .zero, topRight: .zero)
var isNotZero: Bool {
public var isNotZero: Bool {
self != Self.zero
}

var isNotEmpty: Bool {
public var isNotEmpty: Bool {
// https://math.stackexchange.com/a/1259133
let shoelace =
bottomLeft.x * bottomRight.y +
Expand Down
30 changes: 30 additions & 0 deletions Modules/Capabilities/Observations/Tests/ShapeTests.swift
Original file line number Diff line number Diff line change
@@ -0,0 +1,30 @@
// Created by Geoff Pado on 10/19/23.
// Copyright © 2023 Cocoatype, LLC. All rights reserved.

import XCTest

@testable import Observations

final class ShapeTests: XCTestCase {
func testIsNotEmptyReturnsFalseForEmptyShape() {
let emptyShape = Shape(
bottomLeft: CGPoint(x: 5, y: 5),
bottomRight: CGPoint(x: 5, y: 5),
topLeft: CGPoint(x: 5, y: 5),
topRight: CGPoint(x: 5, y: 5)
)

XCTAssertFalse(emptyShape.isNotEmpty)
}

func testIsNotEmptyReturnsTrueForNonEmptyShape() {
let shape = Shape(
bottomLeft: CGPoint(x: 0, y: 5),
bottomRight: CGPoint(x: 5, y: 5),
topLeft: CGPoint(x: 0, y: 0),
topRight: CGPoint(x: 5, y: 0)
)

XCTAssertTrue(shape.isNotEmpty)
}
}
Original file line number Diff line number Diff line change
@@ -0,0 +1,38 @@
// Created by Geoff Pado on 5/8/24.
// Copyright © 2024 Cocoatype, LLC. All rights reserved.

import Observations

#if canImport(AppKit) && !targetEnvironment(macCatalyst)
import AppKit

extension NSBezierPath {
convenience init(cgPath: CGPath) {
self.init()

cgPath.applyWithBlock { elementPointer in
let element = elementPointer.pointee

switch element.type {
case .moveToPoint:
let point = element.points.pointee
self.move(to: point)
case .addLineToPoint:
let point = element.points.pointee
self.line(to: point)
case .addQuadCurveToPoint:
break // NSBezierPath does not support
case .addCurveToPoint:
let bufferPointer = UnsafeBufferPointer(start: element.points, count: 3)
let points = Array(bufferPointer)
self.curve(to: points[0], controlPoint1: points[1], controlPoint2: points[2])
case .closeSubpath:
self.close()
@unknown default:
break
}
}
}
}

#endif
Original file line number Diff line number Diff line change
@@ -0,0 +1,39 @@
// Created by Geoff Pado on 5/8/24.
// Copyright © 2024 Cocoatype, LLC. All rights reserved.

#if canImport(UIKit)
import Observations
import SwiftUI
import UIKit

extension UIBezierPath {
var shape: Observations.Shape? {
let path = Path(self.cgPath)
var elements = [Path.Element]()
path.forEach { element in
elements.append(element)
}

let points = elements.compactMap(\.point)

return Shape(
bottomLeft: points[1],
bottomRight: points[2],
topLeft: points[0],
topRight: points[3]
)
}
}

private extension Path.Element {
var point: CGPoint? {
switch self {
case .move(let to): return to
case .line(let to): return to
case .quadCurve: return nil
case .curve: return nil
case .closeSubpath: return nil
}
}
}
#endif
2 changes: 2 additions & 0 deletions Modules/Capabilities/Redactions/Sources/RedactionPart.swift
Original file line number Diff line number Diff line change
@@ -1,6 +1,8 @@
// Created by Geoff Pado on 5/8/24.
// Copyright © 2024 Cocoatype, LLC. All rights reserved.

import Observations

public enum RedactionPart: Equatable {
case path(RedactionPath)
case shape(Shape)
Expand Down
Original file line number Diff line number Diff line change
@@ -1,6 +1,7 @@
// Created by Geoff Pado on 10/16/19.
// Copyright © 2019 Cocoatype, LLC. All rights reserved.

#if canImport(UIKit)
import UIKit

public class RedactionSerializer: NSObject {
Expand Down Expand Up @@ -35,3 +36,4 @@ public class RedactionSerializer: NSObject {
}
}
}
#endif
Loading

0 comments on commit 24f5766

Please sign in to comment.