Verified Commit d039c4f5 authored by Geoff Pado's avatar Geoff Pado

Draw the correct black streaks instead of green lines

parent 6ff8e9da
{
"images" : [
{
"idiom" : "universal",
"filename" : "brush.png",
"scale" : "1x"
},
{
"idiom" : "universal",
"filename" : "brush@2x.png",
"scale" : "2x"
},
{
"idiom" : "universal",
"filename" : "brush@3x.png",
"scale" : "3x"
}
],
"info" : {
"version" : 1,
"author" : "xcode"
}
}
\ No newline at end of file
......@@ -9,4 +9,29 @@ extension UIBezierPath {
let strokedCGPath = cgPath.copy(strokingWithWidth: lineWidth, lineCap: lineCapStyle, lineJoin: lineJoinStyle, miterLimit: miterLimit)
return UIBezierPath(cgPath: strokedCGPath)
}
var dashedPath: UIBezierPath {
let cgPath = self.cgPath
let dashedCGPath = cgPath.copy(dashingWithPhase: 0, lengths: [4, 4])
let dashedPath = UIBezierPath(cgPath: dashedCGPath)
dashedPath.lineWidth = lineWidth
return dashedPath
}
func forEachPoint(_ function: @escaping ((CGPoint) -> Void)) {
let cgPath = self.cgPath
withUnsafePointer(to: function) { functionPointer in
let rawFunctionPointer = UnsafeMutableRawPointer(mutating: functionPointer)
cgPath.apply(info: rawFunctionPointer) { functionPointer, elementPointer in
let function = functionPointer?.assumingMemoryBound(to: ((CGPoint) -> Void).self).pointee
let element = elementPointer.pointee
let elementType = element.type
guard elementType == .moveToPoint || elementType == .addLineToPoint else { return }
let elementPoint = element.points.pointee
function?(elementPoint)
}
}
}
}
......@@ -16,16 +16,44 @@ class PhotoEditingRedactionView: UIView {
super.draw(rect)
UIColor.green.setStroke()
redactions.forEach { redaction in
let path = redaction.path
path.lineWidth = 10.0
path.stroke()
redactions
.flatMap { $0.paths }
.map { $0.dashedPath }
.forEach { path in
let brushStampImage = brushStamp(scaledToHeight: path.lineWidth)
path.forEachPoint{ point in
guard let context = UIGraphicsGetCurrentContext() else { return }
context.saveGState()
defer { context.restoreGState() }
context.translateBy(x: brushStampImage.size.width * -0.5, y: brushStampImage.size.height * -0.5)
brushStampImage.draw(at: point)
}
}
}
func add(_ redaction: Redaction) {
redactions.append(redaction)
setNeedsDisplay(redaction.path.bounds)
setNeedsDisplay()
}
private func brushStamp(scaledToHeight height: CGFloat) -> UIImage {
guard let standardImage = UIImage(named: "Brush") else { fatalError("Unable to load brush stamp image") }
let brushScale = height / standardImage.size.height
let scaledBrushSize = standardImage.size * brushScale
UIGraphicsBeginImageContext(scaledBrushSize)
defer { UIGraphicsEndImageContext() }
guard let context = UIGraphicsGetCurrentContext() else { fatalError("Unable to create brush scaling image context") }
context.scaleBy(x: brushScale, y: brushScale)
standardImage.draw(at: .zero)
guard let scaledImage = UIGraphicsGetImageFromCurrentImageContext() else { fatalError("Unable to get scaled brush image from context") }
return scaledImage
}
// MARK: Boilerplate
......
......@@ -4,14 +4,14 @@
import UIKit
protocol Redaction {
var path: UIBezierPath { get }
var paths: [UIBezierPath] { get }
}
struct CharacterObservationRedaction: Redaction {
init(_ characterObservations: [CharacterObservation]) {
self.characterObservations = characterObservations
self.path = characterObservations.reduce(into: [UUID: [CharacterObservation]]()) { result, characterObservation in
self.paths = characterObservations.reduce(into: [UUID: [CharacterObservation]]()) { result, characterObservation in
let textObservationUUID = characterObservation.textObservationUUID
var siblingObservations = result[textObservationUUID] ?? []
siblingObservations.append(characterObservation)
......@@ -20,12 +20,15 @@ struct CharacterObservationRedaction: Redaction {
siblingObservations.reduce(siblingObservations[0].bounds, { currentRect, characterObservation in
currentRect.union(characterObservation.bounds)
})
}.reduce(into: UIBezierPath(), { path, rect in
}.map { rect in
let path = UIBezierPath()
path.lineWidth = rect.height
path.move(to: CGPoint(x: rect.minX, y: rect.midY))
path.addLine(to: CGPoint(x: rect.maxX, y: rect.midY))
})
return path
}
}
let path: UIBezierPath
let paths: [UIBezierPath]
private let characterObservations: [CharacterObservation]
}
Markdown is supported
0% or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment