mirror of
https://github.com/dscyrescotti/Memola.git
synced 2026-04-25 10:08:34 +02:00
refactor: clean up
This commit is contained in:
@@ -57,7 +57,7 @@
|
|||||||
ECA738C92BE60EF700A4542E /* GraphicContext.swift in Sources */ = {isa = PBXBuildFile; fileRef = ECA738C82BE60EF700A4542E /* GraphicContext.swift */; };
|
ECA738C92BE60EF700A4542E /* GraphicContext.swift in Sources */ = {isa = PBXBuildFile; fileRef = ECA738C82BE60EF700A4542E /* GraphicContext.swift */; };
|
||||||
ECA738CB2BE60F1900A4542E /* ViewPortContext.swift in Sources */ = {isa = PBXBuildFile; fileRef = ECA738CA2BE60F1900A4542E /* ViewPortContext.swift */; };
|
ECA738CB2BE60F1900A4542E /* ViewPortContext.swift in Sources */ = {isa = PBXBuildFile; fileRef = ECA738CA2BE60F1900A4542E /* ViewPortContext.swift */; };
|
||||||
ECA738CD2BE60F2F00A4542E /* GridContext.swift in Sources */ = {isa = PBXBuildFile; fileRef = ECA738CC2BE60F2F00A4542E /* GridContext.swift */; };
|
ECA738CD2BE60F2F00A4542E /* GridContext.swift in Sources */ = {isa = PBXBuildFile; fileRef = ECA738CC2BE60F2F00A4542E /* GridContext.swift */; };
|
||||||
ECA738D22BE60F7B00A4542E /* Stroke.swift in Sources */ = {isa = PBXBuildFile; fileRef = ECA738D12BE60F7B00A4542E /* Stroke.swift */; };
|
ECA738D22BE60F7B00A4542E /* PenStroke.swift in Sources */ = {isa = PBXBuildFile; fileRef = ECA738D12BE60F7B00A4542E /* PenStroke.swift */; };
|
||||||
ECA738D42BE60F9100A4542E /* StrokeGenerator.swift in Sources */ = {isa = PBXBuildFile; fileRef = ECA738D32BE60F9100A4542E /* StrokeGenerator.swift */; };
|
ECA738D42BE60F9100A4542E /* StrokeGenerator.swift in Sources */ = {isa = PBXBuildFile; fileRef = ECA738D32BE60F9100A4542E /* StrokeGenerator.swift */; };
|
||||||
ECA738D72BE60FC100A4542E /* SolidPointStrokeGenerator.swift in Sources */ = {isa = PBXBuildFile; fileRef = ECA738D62BE60FC100A4542E /* SolidPointStrokeGenerator.swift */; };
|
ECA738D72BE60FC100A4542E /* SolidPointStrokeGenerator.swift in Sources */ = {isa = PBXBuildFile; fileRef = ECA738D62BE60FC100A4542E /* SolidPointStrokeGenerator.swift */; };
|
||||||
ECA738DA2BE60FF100A4542E /* CacheRenderPass.swift in Sources */ = {isa = PBXBuildFile; fileRef = ECA738D92BE60FF100A4542E /* CacheRenderPass.swift */; };
|
ECA738DA2BE60FF100A4542E /* CacheRenderPass.swift in Sources */ = {isa = PBXBuildFile; fileRef = ECA738D92BE60FF100A4542E /* CacheRenderPass.swift */; };
|
||||||
@@ -139,7 +139,7 @@
|
|||||||
ECA738C82BE60EF700A4542E /* GraphicContext.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = GraphicContext.swift; sourceTree = "<group>"; };
|
ECA738C82BE60EF700A4542E /* GraphicContext.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = GraphicContext.swift; sourceTree = "<group>"; };
|
||||||
ECA738CA2BE60F1900A4542E /* ViewPortContext.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = ViewPortContext.swift; sourceTree = "<group>"; };
|
ECA738CA2BE60F1900A4542E /* ViewPortContext.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = ViewPortContext.swift; sourceTree = "<group>"; };
|
||||||
ECA738CC2BE60F2F00A4542E /* GridContext.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = GridContext.swift; sourceTree = "<group>"; };
|
ECA738CC2BE60F2F00A4542E /* GridContext.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = GridContext.swift; sourceTree = "<group>"; };
|
||||||
ECA738D12BE60F7B00A4542E /* Stroke.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = Stroke.swift; sourceTree = "<group>"; };
|
ECA738D12BE60F7B00A4542E /* PenStroke.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = PenStroke.swift; sourceTree = "<group>"; };
|
||||||
ECA738D32BE60F9100A4542E /* StrokeGenerator.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = StrokeGenerator.swift; sourceTree = "<group>"; };
|
ECA738D32BE60F9100A4542E /* StrokeGenerator.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = StrokeGenerator.swift; sourceTree = "<group>"; };
|
||||||
ECA738D62BE60FC100A4542E /* SolidPointStrokeGenerator.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = SolidPointStrokeGenerator.swift; sourceTree = "<group>"; };
|
ECA738D62BE60FC100A4542E /* SolidPointStrokeGenerator.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = SolidPointStrokeGenerator.swift; sourceTree = "<group>"; };
|
||||||
ECA738D92BE60FF100A4542E /* CacheRenderPass.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = CacheRenderPass.swift; sourceTree = "<group>"; };
|
ECA738D92BE60FF100A4542E /* CacheRenderPass.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = CacheRenderPass.swift; sourceTree = "<group>"; };
|
||||||
@@ -539,10 +539,10 @@
|
|||||||
ECA738CE2BE60F5000A4542E /* Stroke */ = {
|
ECA738CE2BE60F5000A4542E /* Stroke */ = {
|
||||||
isa = PBXGroup;
|
isa = PBXGroup;
|
||||||
children = (
|
children = (
|
||||||
|
ECE883B92C009DCA0045C53D /* Core */,
|
||||||
|
ECE883B82C009DC30045C53D /* Strokes */,
|
||||||
EC5E838E2BFDB69000261D9C /* Algorithms */,
|
EC5E838E2BFDB69000261D9C /* Algorithms */,
|
||||||
ECA738D52BE60FA200A4542E /* Generators */,
|
ECA738D52BE60FA200A4542E /* Generators */,
|
||||||
ECA738D12BE60F7B00A4542E /* Stroke.swift */,
|
|
||||||
ECA738D32BE60F9100A4542E /* StrokeGenerator.swift */,
|
|
||||||
);
|
);
|
||||||
path = Stroke;
|
path = Stroke;
|
||||||
sourceTree = "<group>";
|
sourceTree = "<group>";
|
||||||
@@ -618,6 +618,22 @@
|
|||||||
path = Core;
|
path = Core;
|
||||||
sourceTree = "<group>";
|
sourceTree = "<group>";
|
||||||
};
|
};
|
||||||
|
ECE883B82C009DC30045C53D /* Strokes */ = {
|
||||||
|
isa = PBXGroup;
|
||||||
|
children = (
|
||||||
|
ECA738D12BE60F7B00A4542E /* PenStroke.swift */,
|
||||||
|
);
|
||||||
|
path = Strokes;
|
||||||
|
sourceTree = "<group>";
|
||||||
|
};
|
||||||
|
ECE883B92C009DCA0045C53D /* Core */ = {
|
||||||
|
isa = PBXGroup;
|
||||||
|
children = (
|
||||||
|
ECA738D32BE60F9100A4542E /* StrokeGenerator.swift */,
|
||||||
|
);
|
||||||
|
path = Core;
|
||||||
|
sourceTree = "<group>";
|
||||||
|
};
|
||||||
ECFA151E2BEF21BE00455818 /* Objects */ = {
|
ECFA151E2BEF21BE00455818 /* Objects */ = {
|
||||||
isa = PBXGroup;
|
isa = PBXGroup;
|
||||||
children = (
|
children = (
|
||||||
@@ -777,7 +793,7 @@
|
|||||||
ECFA15282BEF225000455818 /* QuadObject.swift in Sources */,
|
ECFA15282BEF225000455818 /* QuadObject.swift in Sources */,
|
||||||
ECA738932BE6011100A4542E /* Stroke.metal in Sources */,
|
ECA738932BE6011100A4542E /* Stroke.metal in Sources */,
|
||||||
ECA738B62BE60DCD00A4542E /* History.swift in Sources */,
|
ECA738B62BE60DCD00A4542E /* History.swift in Sources */,
|
||||||
ECA738D22BE60F7B00A4542E /* Stroke.swift in Sources */,
|
ECA738D22BE60F7B00A4542E /* PenStroke.swift in Sources */,
|
||||||
ECA738F22BE6128F00A4542E /* Collection++.swift in Sources */,
|
ECA738F22BE6128F00A4542E /* Collection++.swift in Sources */,
|
||||||
EC5050072BF65CED00B4D86E /* PenDropDelegate.swift in Sources */,
|
EC5050072BF65CED00B4D86E /* PenDropDelegate.swift in Sources */,
|
||||||
ECA738A32BE6020A00A4542E /* CGFloat++.swift in Sources */,
|
ECA738A32BE6020A00A4542E /* CGFloat++.swift in Sources */,
|
||||||
|
|||||||
@@ -11,11 +11,11 @@ import CoreData
|
|||||||
import Foundation
|
import Foundation
|
||||||
|
|
||||||
final class GraphicContext: @unchecked Sendable {
|
final class GraphicContext: @unchecked Sendable {
|
||||||
var strokes: [Stroke] = []
|
var strokes: [PenStroke] = []
|
||||||
var object: GraphicContextObject?
|
var object: GraphicContextObject?
|
||||||
|
|
||||||
var currentStroke: Stroke?
|
var currentStroke: PenStroke?
|
||||||
var previousStroke: Stroke?
|
var previousStroke: PenStroke?
|
||||||
var currentPoint: CGPoint?
|
var currentPoint: CGPoint?
|
||||||
var renderType: RenderType = .finished
|
var renderType: RenderType = .finished
|
||||||
var vertices: [ViewPortVertex] = []
|
var vertices: [ViewPortVertex] = []
|
||||||
@@ -64,9 +64,9 @@ extension GraphicContext {
|
|||||||
guard let object else { return }
|
guard let object else { return }
|
||||||
let queue = OperationQueue()
|
let queue = OperationQueue()
|
||||||
queue.qualityOfService = .userInteractive
|
queue.qualityOfService = .userInteractive
|
||||||
self.strokes = object.strokes.compactMap { stroke -> Stroke? in
|
self.strokes = object.strokes.compactMap { stroke -> PenStroke? in
|
||||||
guard let stroke = stroke as? StrokeObject else { return nil }
|
guard let stroke = stroke as? StrokeObject else { return nil }
|
||||||
let _stroke = Stroke(object: stroke)
|
let _stroke = PenStroke(object: stroke)
|
||||||
if _stroke.isVisible(in: bounds) {
|
if _stroke.isVisible(in: bounds) {
|
||||||
let id = stroke.objectID
|
let id = stroke.objectID
|
||||||
queue.addOperation {
|
queue.addOperation {
|
||||||
@@ -91,7 +91,7 @@ extension GraphicContext {
|
|||||||
|
|
||||||
func loadQuads(_ bounds: CGRect) {
|
func loadQuads(_ bounds: CGRect) {
|
||||||
for stroke in self.strokes {
|
for stroke in self.strokes {
|
||||||
guard stroke.isVisible(in: bounds), stroke.quads.isEmpty else { continue }
|
guard stroke.isVisible(in: bounds), stroke.isEmpty else { continue }
|
||||||
stroke.loadQuads()
|
stroke.loadQuads()
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
@@ -114,8 +114,8 @@ extension GraphicContext: Drawable {
|
|||||||
}
|
}
|
||||||
|
|
||||||
extension GraphicContext {
|
extension GraphicContext {
|
||||||
func beginStroke(at point: CGPoint, pen: Pen) -> Stroke {
|
func beginStroke(at point: CGPoint, pen: Pen) -> PenStroke {
|
||||||
let stroke = Stroke(
|
let stroke = PenStroke(
|
||||||
bounds: [point.x - pen.thickness, point.y - pen.thickness, point.x + pen.thickness, point.y + pen.thickness],
|
bounds: [point.x - pen.thickness, point.y - pen.thickness, point.x + pen.thickness, point.y + pen.thickness],
|
||||||
color: pen.rgba,
|
color: pen.rgba,
|
||||||
style: pen.strokeStyle.rawValue,
|
style: pen.strokeStyle.rawValue,
|
||||||
|
|||||||
@@ -104,7 +104,7 @@ extension Canvas {
|
|||||||
|
|
||||||
// MARK: - Graphic Context
|
// MARK: - Graphic Context
|
||||||
extension Canvas {
|
extension Canvas {
|
||||||
func beginTouch(at point: CGPoint, pen: Pen) -> Stroke {
|
func beginTouch(at point: CGPoint, pen: Pen) -> PenStroke {
|
||||||
graphicContext.beginStroke(at: point, pen: pen)
|
graphicContext.beginStroke(at: point, pen: pen)
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -124,7 +124,7 @@ extension Canvas {
|
|||||||
graphicContext.renderType = renderType
|
graphicContext.renderType = renderType
|
||||||
}
|
}
|
||||||
|
|
||||||
func getNewlyAddedStroke() -> Stroke? {
|
func getNewlyAddedStroke() -> PenStroke? {
|
||||||
graphicContext.strokes.last
|
graphicContext.strokes.last
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -12,7 +12,7 @@ protocol StrokeGenerator {
|
|||||||
|
|
||||||
var configuration: Configuration { get set }
|
var configuration: Configuration { get set }
|
||||||
|
|
||||||
func begin(at point: CGPoint, on stroke: Stroke)
|
func begin(at point: CGPoint, on stroke: PenStroke)
|
||||||
func append(to point: CGPoint, on stroke: Stroke)
|
func append(to point: CGPoint, on stroke: PenStroke)
|
||||||
func finish(at point: CGPoint, on stroke: Stroke)
|
func finish(at point: CGPoint, on stroke: PenStroke)
|
||||||
}
|
}
|
||||||
@@ -10,13 +10,13 @@ import Foundation
|
|||||||
struct SolidPointStrokeGenerator: StrokeGenerator {
|
struct SolidPointStrokeGenerator: StrokeGenerator {
|
||||||
var configuration: Configuration
|
var configuration: Configuration
|
||||||
|
|
||||||
func begin(at point: CGPoint, on stroke: Stroke) {
|
func begin(at point: CGPoint, on stroke: PenStroke) {
|
||||||
let point = stroke.movingAverage.addPoint(point)
|
let point = stroke.movingAverage.addPoint(point)
|
||||||
stroke.keyPoints.append(point)
|
stroke.keyPoints.append(point)
|
||||||
addPoint(point, on: stroke)
|
addPoint(point, on: stroke)
|
||||||
}
|
}
|
||||||
|
|
||||||
func append(to point: CGPoint, on stroke: Stroke) {
|
func append(to point: CGPoint, on stroke: PenStroke) {
|
||||||
guard stroke.keyPoints.endIndex > 0 else {
|
guard stroke.keyPoints.endIndex > 0 else {
|
||||||
return
|
return
|
||||||
}
|
}
|
||||||
@@ -49,7 +49,7 @@ struct SolidPointStrokeGenerator: StrokeGenerator {
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
func finish(at point: CGPoint, on stroke: Stroke) {
|
func finish(at point: CGPoint, on stroke: PenStroke) {
|
||||||
switch stroke.keyPoints.endIndex {
|
switch stroke.keyPoints.endIndex {
|
||||||
case 0...1:
|
case 0...1:
|
||||||
break
|
break
|
||||||
@@ -58,7 +58,7 @@ struct SolidPointStrokeGenerator: StrokeGenerator {
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
private func smoothOutPath(on stroke: Stroke) {
|
private func smoothOutPath(on stroke: PenStroke) {
|
||||||
stroke.removeQuads(from: stroke.quadIndex + 1)
|
stroke.removeQuads(from: stroke.quadIndex + 1)
|
||||||
adjustKeyPoint(on: stroke)
|
adjustKeyPoint(on: stroke)
|
||||||
switch stroke.keyPoints.endIndex {
|
switch stroke.keyPoints.endIndex {
|
||||||
@@ -79,7 +79,7 @@ struct SolidPointStrokeGenerator: StrokeGenerator {
|
|||||||
stroke.quadIndex = stroke.quads.endIndex - 1
|
stroke.quadIndex = stroke.quads.endIndex - 1
|
||||||
}
|
}
|
||||||
|
|
||||||
private func adjustKeyPoint(on stroke: Stroke) {
|
private func adjustKeyPoint(on stroke: PenStroke) {
|
||||||
let index = stroke.keyPoints.endIndex - 1
|
let index = stroke.keyPoints.endIndex - 1
|
||||||
let prev = stroke.keyPoints[index - 1]
|
let prev = stroke.keyPoints[index - 1]
|
||||||
let current = stroke.keyPoints[index]
|
let current = stroke.keyPoints[index]
|
||||||
@@ -89,7 +89,7 @@ struct SolidPointStrokeGenerator: StrokeGenerator {
|
|||||||
stroke.keyPoints[index] = point
|
stroke.keyPoints[index] = point
|
||||||
}
|
}
|
||||||
|
|
||||||
private func addPoint(_ point: CGPoint, on stroke: Stroke) {
|
private func addPoint(_ point: CGPoint, on stroke: PenStroke) {
|
||||||
let rotation: CGFloat
|
let rotation: CGFloat
|
||||||
switch configuration.rotation {
|
switch configuration.rotation {
|
||||||
case .fixed:
|
case .fixed:
|
||||||
@@ -100,7 +100,7 @@ struct SolidPointStrokeGenerator: StrokeGenerator {
|
|||||||
stroke.addQuad(at: point, rotation: rotation, shape: .rounded)
|
stroke.addQuad(at: point, rotation: rotation, shape: .rounded)
|
||||||
}
|
}
|
||||||
|
|
||||||
private func addCurve(from start: CGPoint, to end: CGPoint, by control: CGPoint, on stroke: Stroke) {
|
private func addCurve(from start: CGPoint, to end: CGPoint, by control: CGPoint, on stroke: PenStroke) {
|
||||||
let distance = start.distance(to: end)
|
let distance = start.distance(to: end)
|
||||||
let factor: CGFloat
|
let factor: CGFloat
|
||||||
switch configuration.granularity {
|
switch configuration.granularity {
|
||||||
|
|||||||
@@ -1,5 +1,5 @@
|
|||||||
//
|
//
|
||||||
// Stroke.swift
|
// PenStroke.swift
|
||||||
// Memola
|
// Memola
|
||||||
//
|
//
|
||||||
// Created by Dscyre Scotti on 5/4/24.
|
// Created by Dscyre Scotti on 5/4/24.
|
||||||
@@ -9,7 +9,7 @@ import MetalKit
|
|||||||
import CoreData
|
import CoreData
|
||||||
import Foundation
|
import Foundation
|
||||||
|
|
||||||
final class Stroke: @unchecked Sendable {
|
final class PenStroke: @unchecked Sendable {
|
||||||
var object: StrokeObject?
|
var object: StrokeObject?
|
||||||
var bounds: [CGFloat]
|
var bounds: [CGFloat]
|
||||||
var color: [CGFloat]
|
var color: [CGFloat]
|
||||||
@@ -17,6 +17,7 @@ final class Stroke: @unchecked Sendable {
|
|||||||
var createdAt: Date
|
var createdAt: Date
|
||||||
var thickness: CGFloat
|
var thickness: CGFloat
|
||||||
var quads: [Quad]
|
var quads: [Quad]
|
||||||
|
var penStyle: Style
|
||||||
|
|
||||||
init(object: StrokeObject) {
|
init(object: StrokeObject) {
|
||||||
self.object = object
|
self.object = object
|
||||||
@@ -26,6 +27,7 @@ final class Stroke: @unchecked Sendable {
|
|||||||
self.createdAt = object.createdAt
|
self.createdAt = object.createdAt
|
||||||
self.thickness = object.thickness
|
self.thickness = object.thickness
|
||||||
self.quads = []
|
self.quads = []
|
||||||
|
self.penStyle = Style(rawValue: style) ?? .marker
|
||||||
}
|
}
|
||||||
|
|
||||||
init(
|
init(
|
||||||
@@ -42,17 +44,12 @@ final class Stroke: @unchecked Sendable {
|
|||||||
self.createdAt = createdAt
|
self.createdAt = createdAt
|
||||||
self.thickness = thickness
|
self.thickness = thickness
|
||||||
self.quads = quads
|
self.quads = quads
|
||||||
}
|
self.penStyle = Style(rawValue: style) ?? .marker
|
||||||
|
|
||||||
var angle: CGFloat = 0
|
|
||||||
var penStyle: Style {
|
|
||||||
Style(rawValue: style) ?? .marker
|
|
||||||
}
|
}
|
||||||
|
|
||||||
var batchIndex: Int = 0
|
var batchIndex: Int = 0
|
||||||
var quadIndex: Int = -1
|
var quadIndex: Int = -1
|
||||||
var keyPoints: [CGPoint] = []
|
var keyPoints: [CGPoint] = []
|
||||||
var thicknessFactor: CGFloat = 0.7
|
|
||||||
|
|
||||||
let movingAverage = MovingAverage(windowSize: 3)
|
let movingAverage = MovingAverage(windowSize: 3)
|
||||||
|
|
||||||
@@ -60,12 +57,7 @@ final class Stroke: @unchecked Sendable {
|
|||||||
var indexBuffer: MTLBuffer?
|
var indexBuffer: MTLBuffer?
|
||||||
var vertexBuffer: MTLBuffer?
|
var vertexBuffer: MTLBuffer?
|
||||||
|
|
||||||
var isEmpty: Bool {
|
var isEmpty: Bool { quads.isEmpty }
|
||||||
quads.isEmpty
|
|
||||||
}
|
|
||||||
var isEraserPenStyle: Bool {
|
|
||||||
penStyle == .eraser
|
|
||||||
}
|
|
||||||
var strokeBounds: CGRect {
|
var strokeBounds: CGRect {
|
||||||
let x = bounds[0]
|
let x = bounds[0]
|
||||||
let y = bounds[1]
|
let y = bounds[1]
|
||||||
@@ -92,7 +84,7 @@ final class Stroke: @unchecked Sendable {
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
extension Stroke {
|
extension PenStroke {
|
||||||
func loadQuads() {
|
func loadQuads() {
|
||||||
guard let object else { return }
|
guard let object else { return }
|
||||||
quads = object.quads.compactMap { quad in
|
quads = object.quads.compactMap { quad in
|
||||||
@@ -153,7 +145,7 @@ extension Stroke {
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
extension Stroke: Drawable {
|
extension PenStroke: Drawable {
|
||||||
func prepare(device: MTLDevice) {
|
func prepare(device: MTLDevice) {
|
||||||
if texture == nil {
|
if texture == nil {
|
||||||
texture = penStyle.anyPenStyle.loadTexture(on: device)
|
texture = penStyle.anyPenStyle.loadTexture(on: device)
|
||||||
@@ -177,7 +169,7 @@ extension Stroke: Drawable {
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
extension Stroke {
|
extension PenStroke {
|
||||||
enum Style: Int16 {
|
enum Style: Int16 {
|
||||||
case marker
|
case marker
|
||||||
case eraser
|
case eraser
|
||||||
@@ -8,5 +8,5 @@
|
|||||||
import Foundation
|
import Foundation
|
||||||
|
|
||||||
enum HistoryEvent {
|
enum HistoryEvent {
|
||||||
case stroke(Stroke)
|
case stroke(PenStroke)
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -46,11 +46,12 @@ class CacheRenderPass: RenderPass {
|
|||||||
|
|
||||||
let graphicContext = canvas.graphicContext
|
let graphicContext = canvas.graphicContext
|
||||||
if let stroke = graphicContext.currentStroke {
|
if let stroke = graphicContext.currentStroke {
|
||||||
if stroke.isEraserPenStyle {
|
switch stroke.penStyle {
|
||||||
|
case .eraser:
|
||||||
eraserRenderPass.stroke = stroke
|
eraserRenderPass.stroke = stroke
|
||||||
eraserRenderPass.descriptor = descriptor
|
eraserRenderPass.descriptor = descriptor
|
||||||
eraserRenderPass.draw(on: canvas, with: renderer)
|
eraserRenderPass.draw(on: canvas, with: renderer)
|
||||||
} else {
|
case .marker:
|
||||||
canvas.setGraphicRenderType(.inProgress)
|
canvas.setGraphicRenderType(.inProgress)
|
||||||
strokeRenderPass.stroke = stroke
|
strokeRenderPass.stroke = stroke
|
||||||
strokeRenderPass.graphicDescriptor = descriptor
|
strokeRenderPass.graphicDescriptor = descriptor
|
||||||
|
|||||||
@@ -16,7 +16,7 @@ class EraserRenderPass: RenderPass {
|
|||||||
var eraserPipelineState: MTLRenderPipelineState?
|
var eraserPipelineState: MTLRenderPipelineState?
|
||||||
var quadPipelineState: MTLComputePipelineState?
|
var quadPipelineState: MTLComputePipelineState?
|
||||||
|
|
||||||
var stroke: Stroke?
|
var stroke: PenStroke?
|
||||||
weak var graphicTexture: MTLTexture?
|
weak var graphicTexture: MTLTexture?
|
||||||
|
|
||||||
init(renderer: Renderer) {
|
init(renderer: Renderer) {
|
||||||
@@ -48,7 +48,7 @@ class EraserRenderPass: RenderPass {
|
|||||||
}
|
}
|
||||||
|
|
||||||
private func generateVertexBuffer(on canvas: Canvas, with renderer: Renderer) {
|
private func generateVertexBuffer(on canvas: Canvas, with renderer: Renderer) {
|
||||||
guard let stroke, !stroke.quads.isEmpty, let quadPipelineState else { return }
|
guard let stroke, !stroke.isEmpty, let quadPipelineState else { return }
|
||||||
guard let quadCommandBuffer = renderer.commandQueue.makeCommandBuffer() else { return }
|
guard let quadCommandBuffer = renderer.commandQueue.makeCommandBuffer() else { return }
|
||||||
guard let computeEncoder = quadCommandBuffer.makeComputeCommandEncoder() else { return }
|
guard let computeEncoder = quadCommandBuffer.makeComputeCommandEncoder() else { return }
|
||||||
|
|
||||||
|
|||||||
@@ -52,11 +52,12 @@ class GraphicRenderPass: RenderPass {
|
|||||||
guard stroke.isVisible(in: canvas.bounds) else { continue }
|
guard stroke.isVisible(in: canvas.bounds) else { continue }
|
||||||
descriptor.colorAttachments[0].loadAction = clearsTexture ? .clear : .load
|
descriptor.colorAttachments[0].loadAction = clearsTexture ? .clear : .load
|
||||||
clearsTexture = false
|
clearsTexture = false
|
||||||
if stroke.isEraserPenStyle {
|
switch stroke.penStyle {
|
||||||
|
case .eraser:
|
||||||
eraserRenderPass.stroke = stroke
|
eraserRenderPass.stroke = stroke
|
||||||
eraserRenderPass.descriptor = descriptor
|
eraserRenderPass.descriptor = descriptor
|
||||||
eraserRenderPass.draw(on: canvas, with: renderer)
|
eraserRenderPass.draw(on: canvas, with: renderer)
|
||||||
} else {
|
case .marker:
|
||||||
canvas.setGraphicRenderType(.finished)
|
canvas.setGraphicRenderType(.finished)
|
||||||
strokeRenderPass.stroke = stroke
|
strokeRenderPass.stroke = stroke
|
||||||
strokeRenderPass.graphicDescriptor = descriptor
|
strokeRenderPass.graphicDescriptor = descriptor
|
||||||
@@ -70,11 +71,12 @@ class GraphicRenderPass: RenderPass {
|
|||||||
if let stroke = graphicContext.previousStroke {
|
if let stroke = graphicContext.previousStroke {
|
||||||
descriptor.colorAttachments[0].loadAction = clearsTexture ? .clear : .load
|
descriptor.colorAttachments[0].loadAction = clearsTexture ? .clear : .load
|
||||||
clearsTexture = false
|
clearsTexture = false
|
||||||
if stroke.isEraserPenStyle {
|
switch stroke.penStyle {
|
||||||
|
case .eraser:
|
||||||
eraserRenderPass.stroke = stroke
|
eraserRenderPass.stroke = stroke
|
||||||
eraserRenderPass.descriptor = descriptor
|
eraserRenderPass.descriptor = descriptor
|
||||||
eraserRenderPass.draw(on: canvas, with: renderer)
|
eraserRenderPass.draw(on: canvas, with: renderer)
|
||||||
} else {
|
case .marker:
|
||||||
canvas.setGraphicRenderType(.newlyFinished)
|
canvas.setGraphicRenderType(.newlyFinished)
|
||||||
strokeRenderPass.stroke = stroke
|
strokeRenderPass.stroke = stroke
|
||||||
strokeRenderPass.graphicDescriptor = descriptor
|
strokeRenderPass.graphicDescriptor = descriptor
|
||||||
|
|||||||
@@ -18,7 +18,7 @@ class StrokeRenderPass: RenderPass {
|
|||||||
var quadPipelineState: MTLComputePipelineState?
|
var quadPipelineState: MTLComputePipelineState?
|
||||||
weak var graphicPipelineState: MTLRenderPipelineState?
|
weak var graphicPipelineState: MTLRenderPipelineState?
|
||||||
|
|
||||||
var stroke: Stroke?
|
var stroke: PenStroke?
|
||||||
var strokeTexture: MTLTexture?
|
var strokeTexture: MTLTexture?
|
||||||
|
|
||||||
init(renderer: Renderer) {
|
init(renderer: Renderer) {
|
||||||
@@ -61,7 +61,7 @@ class StrokeRenderPass: RenderPass {
|
|||||||
}
|
}
|
||||||
|
|
||||||
private func generateVertexBuffer(on canvas: Canvas, with renderer: Renderer) {
|
private func generateVertexBuffer(on canvas: Canvas, with renderer: Renderer) {
|
||||||
guard let stroke, !stroke.quads.isEmpty, let quadPipelineState else { return }
|
guard let stroke, !stroke.isEmpty, let quadPipelineState else { return }
|
||||||
guard let quadCommandBuffer = renderer.commandQueue.makeCommandBuffer() else { return }
|
guard let quadCommandBuffer = renderer.commandQueue.makeCommandBuffer() else { return }
|
||||||
guard let computeEncoder = quadCommandBuffer.makeComputeCommandEncoder() else { return }
|
guard let computeEncoder = quadCommandBuffer.makeComputeCommandEncoder() else { return }
|
||||||
|
|
||||||
|
|||||||
@@ -43,14 +43,14 @@ class Pen: NSObject, ObservableObject, Identifiable {
|
|||||||
init(object: PenObject) {
|
init(object: PenObject) {
|
||||||
self.object = object
|
self.object = object
|
||||||
self.id = object.objectID.uriRepresentation().absoluteString
|
self.id = object.objectID.uriRepresentation().absoluteString
|
||||||
self.style = (Stroke.Style(rawValue: object.style) ?? .marker).anyPenStyle
|
self.style = (PenStroke.Style(rawValue: object.style) ?? .marker).anyPenStyle
|
||||||
self.rgba = object.color
|
self.rgba = object.color
|
||||||
self.thickness = object.thickness
|
self.thickness = object.thickness
|
||||||
self.isSelected = object.isSelected
|
self.isSelected = object.isSelected
|
||||||
super.init()
|
super.init()
|
||||||
}
|
}
|
||||||
|
|
||||||
var strokeStyle: Stroke.Style {
|
var strokeStyle: PenStroke.Style {
|
||||||
style.strokeStyle
|
style.strokeStyle
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -24,7 +24,7 @@ extension PenStyle {
|
|||||||
Textures.createPenTexture(with: textureName, on: device)
|
Textures.createPenTexture(with: textureName, on: device)
|
||||||
}
|
}
|
||||||
|
|
||||||
var strokeStyle: Stroke.Style {
|
var strokeStyle: PenStroke.Style {
|
||||||
switch self {
|
switch self {
|
||||||
case is MarkerPenStyle:
|
case is MarkerPenStyle:
|
||||||
return .marker
|
return .marker
|
||||||
|
|||||||
Reference in New Issue
Block a user