From 7e1ddaf2bf3aef2dd26f161afb8ba9eeb4ce9545 Mon Sep 17 00:00:00 2001 From: Joshua Goins Date: Mon, 27 Sep 2021 11:48:16 -0400 Subject: [PATCH] Splitting up some of the longer parts of the drawing function --- SilicaViewer/Document.swift | 230 +++++++++++++++++------------------- 1 file changed, 109 insertions(+), 121 deletions(-) diff --git a/SilicaViewer/Document.swift b/SilicaViewer/Document.swift index 2e64a52..74bcbdb 100644 --- a/SilicaViewer/Document.swift +++ b/SilicaViewer/Document.swift @@ -142,6 +142,107 @@ class Document: NSDocument { } } + func getChunkRect(_ chunk: SilicaChunk) -> NSRect { + let x = chunk.x + var y = chunk.y + + let (width, height) = getTileSize(x: x, y: y) + + if y == rows { + y = 0 + } + + return NSRect(x: info.tileSize * x, y: info.height - (info.tileSize * y), width: width, height: height) + } + + // TODO: convert to switch/case + func getBlendKernel(_ layer: SilicaLayer) -> CIBlendKernel? { + if layer.data.blendMode == 1 { + return .multiply + } + if layer.data.blendMode == 10 { + return .colorBurn + } + if layer.data.blendMode == 19 { + return .darken + } + if layer.data.blendMode == 8 { + return .linearBurn + } + if layer.data.blendMode == 4 { + return .lighten + } + if layer.data.blendMode == 2 { + return .screen + } + if layer.data.blendMode == 13 { + return .hardLight + } + if layer.data.blendMode == 9 { + return .colorDodge + } + if layer.data.blendMode == 3 { + return .subtract + } + + if layer.data.blendMode == 0 && layer.data.blendMode != layer.data.extendedBlend { + if layer.data.extendedBlend == 25 { + return .darkerColor + } + if layer.data.extendedBlend == 24 { + return .lighterColor + } + if layer.data.extendedBlend == 21 { + return .vividLight + } + if layer.data.extendedBlend == 22 { + return .linearLight + } + if layer.data.extendedBlend == 23 { + return .pinLight + } + if layer.data.extendedBlend == 20 { + return .hardMix + } + if layer.data.extendedBlend == 26 { + return .divide + } + } + + if layer.data.blendMode == 11 { + return .overlay + } + if layer.data.blendMode == 17 { + return .softLight + } + if layer.data.blendMode == 12 { + return .hardLight + } + if layer.data.blendMode == 6 { + return .difference + } + if layer.data.blendMode == 5 { + return .exclusion + } + if layer.data.blendMode == 7 { + return .componentAdd + } + if layer.data.blendMode == 15 { + return .hue + } + if layer.data.blendMode == 16 { + return .saturation + } + if layer.data.blendMode == 13 { + return .color + } + if layer.data.blendMode == 14 { + return .luminosity + } + + return .sourceOver; + } + func parseSilicaLayer(archive: Archive, dict: NSDictionary, isMask: Bool) -> SilicaLayer? { let objectsArray = self.dict?["$objects"] as! NSArray @@ -199,11 +300,7 @@ class Document: NSDocument { let (width, height) = getTileSize(x: x, y: y) - var numChannels = 4 - if isMask { - numChannels = 1 - } - + let numChannels = isMask ? 1 : 4 let byteSize = width * height * numChannels let uncompressedMemory = UnsafeMutablePointer.allocate(capacity: byteSize) @@ -221,16 +318,9 @@ class Document: NSDocument { let imageData = Data(bytes: uncompressedMemory, count: byteSize) let render: CGColorRenderingIntent = .defaultIntent - var rgbColorSpace = info.colorSpace + let rgbColorSpace = isMask ? CGColorSpaceCreateDeviceGray() : info.colorSpace - if isMask { - rgbColorSpace = CGColorSpaceCreateDeviceGray() - } - - var bitmapInfo = CGBitmapInfo(rawValue: CGImageAlphaInfo.last.rawValue).union(.byteOrder32Big) - if isMask { - bitmapInfo = CGBitmapInfo(rawValue: CGImageAlphaInfo.none.rawValue).union(.byteOrder32Big) - } + let bitmapInfo = CGBitmapInfo(rawValue: (isMask ? CGImageAlphaInfo.none : CGImageAlphaInfo.last).rawValue).union(.byteOrder32Big) let providerRef: CGDataProvider? = CGDataProvider(data: imageData as CFData) guard let cgimage = CGImage(width: width, height: height, bitsPerComponent: 8, bitsPerPixel: 8 * numChannels, bytesPerRow: width * numChannels, space: rgbColorSpace, bitmapInfo: bitmapInfo, provider: providerRef!, decode: nil, shouldInterpolate: false, intent: render) else { @@ -410,6 +500,8 @@ class Document: NSDocument { // start by creating a new layer composite image, needed for image masking let layerContext = CGContext(data: nil, width: info.width, height: info.height, bitsPerComponent: 8, bytesPerRow: info.width * 4, space: info.colorSpace, bitmapInfo: bitmapInfo.rawValue) + let graphicsContext = NSGraphicsContext(cgContext: layerContext!, flipped: false) + let grayColorSpace = CGColorSpaceCreateDeviceGray() let maskBitmapInfo = CGBitmapInfo(rawValue: CGImageAlphaInfo.none.rawValue).union(.byteOrder16Big) @@ -418,126 +510,22 @@ class Document: NSDocument { maskContext?.setFillColor(.white) maskContext?.fill(info.cgRect) - var kernel: CIBlendKernel? = .sourceOver - if layer.data.blendMode == 1 { - kernel = .multiply - } - if layer.data.blendMode == 10 { - kernel = .colorBurn - } - if layer.data.blendMode == 19 { - kernel = .darken - } - if layer.data.blendMode == 8 { - kernel = .linearBurn - } - if layer.data.blendMode == 4 { - kernel = .lighten - } - if layer.data.blendMode == 2 { - kernel = .screen - } - if layer.data.blendMode == 13 { - kernel = .hardLight - } - if layer.data.blendMode == 9 { - kernel = .colorDodge - } - if layer.data.blendMode == 3 { - kernel = .subtract - } + let kernel = getBlendKernel(layer) - if layer.data.blendMode == 0 && layer.data.blendMode != layer.data.extendedBlend { - if layer.data.extendedBlend == 25 { - kernel = .darkerColor - } - if layer.data.extendedBlend == 24 { - kernel = .lighterColor - } - if layer.data.extendedBlend == 21 { - kernel = .vividLight - } - if layer.data.extendedBlend == 22 { - kernel = .linearLight - } - if layer.data.extendedBlend == 23 { - kernel = .pinLight - } - if layer.data.extendedBlend == 20 { - kernel = .hardMix - } - if layer.data.extendedBlend == 26 { - kernel = .divide - } - } - - if layer.data.blendMode == 11 { - kernel = .overlay - } - if layer.data.blendMode == 17 { - kernel = .softLight - } - if layer.data.blendMode == 12 { - kernel = .hardLight - } - if layer.data.blendMode == 6 { - kernel = .difference - } - if layer.data.blendMode == 5 { - kernel = .exclusion - } - if layer.data.blendMode == 7 { - kernel = .componentAdd - } - if layer.data.blendMode == 15 { - kernel = .hue - } - if layer.data.blendMode == 16 { - kernel = .saturation - } - if layer.data.blendMode == 13 { - kernel = .color - } - if layer.data.blendMode == 14 { - kernel = .luminosity - } - if layer.mask != nil { for chunk in layer.mask!.chunks { - let x = chunk.x - var y = chunk.y - - let (width, height) = getTileSize(x: x, y: y) - - if y == rows { - y = 0 - } - - let rect = NSRect(x: info.tileSize * x, y: info.height - (info.tileSize * y), width: width, height: height) - if !layer.data.hidden { - maskContext?.draw(chunk.image.cgImage(forProposedRect: nil, context: NSGraphicsContext.current, hints: nil)!, in: rect) + maskContext?.draw(chunk.image.cgImage(forProposedRect: nil, context: graphicsContext, hints: nil)!, in: getChunkRect(chunk)) } } } for chunk in layer.data.chunks { - let x = chunk.x - var y = chunk.y - - let (width, height) = getTileSize(x: x, y: y) - - if y == rows { - y = 0 - } - - let rect = NSRect(x: info.tileSize * x, y: info.height - (info.tileSize * y), width: width, height: height) - layerContext?.setAlpha(CGFloat(layer.data.opacity)) layerContext?.setBlendMode(.copy) if !layer.data.hidden { - layerContext?.draw(chunk.image.cgImage(forProposedRect: nil, context: NSGraphicsContext(cgContext: layerContext!, flipped: false), hints: nil)!, in: rect) + layerContext?.draw(chunk.image.cgImage(forProposedRect: nil, context: graphicsContext, hints: nil)!, in: getChunkRect(chunk)) } }