Fix indentation and remove more debug logging
This commit is contained in:
parent
eeba7bba02
commit
897df62a49
1 changed files with 86 additions and 89 deletions
|
@ -13,34 +13,34 @@ struct SilicaChunk {
|
||||||
// all supported Procreate blend modes
|
// all supported Procreate blend modes
|
||||||
enum BlendMode : Int {
|
enum BlendMode : Int {
|
||||||
case Normal = 0,
|
case Normal = 0,
|
||||||
Multiply = 1,
|
Multiply = 1,
|
||||||
Screen = 2,
|
Screen = 2,
|
||||||
Add = 3,
|
Add = 3,
|
||||||
Lighten = 4,
|
Lighten = 4,
|
||||||
Exclusion = 5,
|
Exclusion = 5,
|
||||||
Difference = 6,
|
Difference = 6,
|
||||||
Subtract = 7,
|
Subtract = 7,
|
||||||
LinearBurn = 8,
|
LinearBurn = 8,
|
||||||
ColorDodge = 9,
|
ColorDodge = 9,
|
||||||
ColorBurn = 10,
|
ColorBurn = 10,
|
||||||
Overlay = 11,
|
Overlay = 11,
|
||||||
HardLight = 12,
|
HardLight = 12,
|
||||||
Color = 13,
|
Color = 13,
|
||||||
Luminosity = 14,
|
Luminosity = 14,
|
||||||
Hue = 15,
|
Hue = 15,
|
||||||
Saturation = 16,
|
Saturation = 16,
|
||||||
SoftLight = 17,
|
SoftLight = 17,
|
||||||
// what is this mysterious 18?
|
// what is this mysterious 18?
|
||||||
Darken = 19,
|
Darken = 19,
|
||||||
|
|
||||||
// extended modes
|
// extended modes
|
||||||
HardMix = 20,
|
HardMix = 20,
|
||||||
VividLight = 21,
|
VividLight = 21,
|
||||||
LinearLight = 22,
|
LinearLight = 22,
|
||||||
PinLight = 23,
|
PinLight = 23,
|
||||||
LighterColor = 24,
|
LighterColor = 24,
|
||||||
DarkerColor = 25,
|
DarkerColor = 25,
|
||||||
Divide = 26
|
Divide = 26
|
||||||
}
|
}
|
||||||
|
|
||||||
struct SilicaLayerData {
|
struct SilicaLayerData {
|
||||||
|
@ -104,9 +104,9 @@ class Document: NSDocument {
|
||||||
var data: Data? // oh no...
|
var data: Data? // oh no...
|
||||||
|
|
||||||
var dict: NSDictionary?
|
var dict: NSDictionary?
|
||||||
|
|
||||||
var info = SilicaDocument()
|
var info = SilicaDocument()
|
||||||
|
|
||||||
var rows: Int = 0
|
var rows: Int = 0
|
||||||
var columns: Int = 0
|
var columns: Int = 0
|
||||||
|
|
||||||
|
@ -162,7 +162,7 @@ class Document: NSDocument {
|
||||||
*/
|
*/
|
||||||
func getDocumentClassName(dict: NSDictionary) -> String? {
|
func getDocumentClassName(dict: NSDictionary) -> String? {
|
||||||
let objectsArray = self.dict?["$objects"] as! NSArray
|
let objectsArray = self.dict?["$objects"] as! NSArray
|
||||||
|
|
||||||
if let value = dict["$class"] {
|
if let value = dict["$class"] {
|
||||||
let classObjectId = objectRefGetValue2(value as CFTypeRef)
|
let classObjectId = objectRefGetValue2(value as CFTypeRef)
|
||||||
let classObject = objectsArray[Int(classObjectId)] as! NSDictionary
|
let classObject = objectsArray[Int(classObjectId)] as! NSDictionary
|
||||||
|
@ -221,7 +221,7 @@ class Document: NSDocument {
|
||||||
if y == rows {
|
if y == rows {
|
||||||
y = 0
|
y = 0
|
||||||
}
|
}
|
||||||
|
|
||||||
return NSRect(x: info.tileSize * x, y: info.height - (info.tileSize * y), width: width, height: height)
|
return NSRect(x: info.tileSize * x, y: info.height - (info.tileSize * y), width: width, height: height)
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -292,7 +292,7 @@ class Document: NSDocument {
|
||||||
|
|
||||||
func parseSilicaLayer(archive: Archive, dict: NSDictionary, isMask: Bool) -> SilicaLayer? {
|
func parseSilicaLayer(archive: Archive, dict: NSDictionary, isMask: Bool) -> SilicaLayer? {
|
||||||
let objectsArray = self.dict?["$objects"] as! NSArray
|
let objectsArray = self.dict?["$objects"] as! NSArray
|
||||||
|
|
||||||
if getDocumentClassName(dict: dict) == LayerClassName {
|
if getDocumentClassName(dict: dict) == LayerClassName {
|
||||||
var layer = SilicaLayer()
|
var layer = SilicaLayer()
|
||||||
|
|
||||||
|
@ -310,13 +310,13 @@ class Document: NSDocument {
|
||||||
let maskKey = dict["mask"]
|
let maskKey = dict["mask"]
|
||||||
let maskClassID = getClassID(id: maskKey)
|
let maskClassID = getClassID(id: maskKey)
|
||||||
let maskClass = objectsArray[maskClassID]
|
let maskClass = objectsArray[maskClassID]
|
||||||
|
|
||||||
layer.data.blendMode = parseRawBlendMode(blendMode: (dict["blend"] as? NSNumber)!.intValue, extendedBlend: (dict["extendedBlend"] as? NSNumber)!.intValue)!
|
layer.data.blendMode = parseRawBlendMode(blendMode: (dict["blend"] as? NSNumber)!.intValue, extendedBlend: (dict["extendedBlend"] as? NSNumber)!.intValue)!
|
||||||
|
|
||||||
layer.data.opacity = (dict["opacity"] as? NSNumber)!.doubleValue
|
layer.data.opacity = (dict["opacity"] as? NSNumber)!.doubleValue
|
||||||
layer.data.hidden = (dict["hidden"] as? Bool)!
|
layer.data.hidden = (dict["hidden"] as? Bool)!
|
||||||
layer.clipped = (dict["clipped"] as? Bool)!
|
layer.clipped = (dict["clipped"] as? Bool)!
|
||||||
|
|
||||||
if maskClassID != 0 {
|
if maskClassID != 0 {
|
||||||
layer.mask = parseSilicaLayer(archive: archive, dict: maskClass as! NSDictionary, isMask: true)?.data
|
layer.mask = parseSilicaLayer(archive: archive, dict: maskClass as! NSDictionary, isMask: true)?.data
|
||||||
}
|
}
|
||||||
|
@ -338,9 +338,9 @@ class Document: NSDocument {
|
||||||
guard let threadArchive = Archive(data: self.data!, accessMode: .read) else {
|
guard let threadArchive = Archive(data: self.data!, accessMode: .read) else {
|
||||||
return
|
return
|
||||||
}
|
}
|
||||||
|
|
||||||
let threadEntry = threadArchive[chunkPaths[i]]
|
let threadEntry = threadArchive[chunkPaths[i]]
|
||||||
|
|
||||||
guard let (x, y) = parseChunkFilename(threadEntry!.path) else {
|
guard let (x, y) = parseChunkFilename(threadEntry!.path) else {
|
||||||
return
|
return
|
||||||
}
|
}
|
||||||
|
@ -351,7 +351,7 @@ class Document: NSDocument {
|
||||||
let byteSize = width * height * numChannels
|
let byteSize = width * height * numChannels
|
||||||
|
|
||||||
let uncompressedMemory = UnsafeMutablePointer<UInt8>.allocate(capacity: byteSize)
|
let uncompressedMemory = UnsafeMutablePointer<UInt8>.allocate(capacity: byteSize)
|
||||||
|
|
||||||
guard let lzoData = readData(archive: threadArchive, entry: threadEntry!) else {
|
guard let lzoData = readData(archive: threadArchive, entry: threadEntry!) else {
|
||||||
return
|
return
|
||||||
}
|
}
|
||||||
|
@ -373,7 +373,7 @@ class Document: NSDocument {
|
||||||
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 {
|
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 {
|
||||||
return
|
return
|
||||||
}
|
}
|
||||||
|
|
||||||
queue.async(group: dispatchGroup) {
|
queue.async(group: dispatchGroup) {
|
||||||
layer.data.chunks[i].image = cgimage
|
layer.data.chunks[i].image = cgimage
|
||||||
layer.data.chunks[i].x = x
|
layer.data.chunks[i].x = x
|
||||||
|
@ -404,7 +404,7 @@ class Document: NSDocument {
|
||||||
|
|
||||||
func parseSilicaDocument(archive: Archive, dict: NSDictionary) {
|
func parseSilicaDocument(archive: Archive, dict: NSDictionary) {
|
||||||
let objectsArray = self.dict?["$objects"] as! NSArray
|
let objectsArray = self.dict?["$objects"] as! NSArray
|
||||||
|
|
||||||
if getDocumentClassName(dict: dict) == DocumentClassName {
|
if getDocumentClassName(dict: dict) == DocumentClassName {
|
||||||
info.trackedTime = (dict[TrackedTimeKey] as! NSNumber).intValue
|
info.trackedTime = (dict[TrackedTimeKey] as! NSNumber).intValue
|
||||||
info.tileSize = (dict[TileSizeKey] as! NSNumber).intValue
|
info.tileSize = (dict[TileSizeKey] as! NSNumber).intValue
|
||||||
|
@ -419,18 +419,18 @@ class Document: NSDocument {
|
||||||
let frameSizeClassKey = videoResolution["frameSize"]
|
let frameSizeClassKey = videoResolution["frameSize"]
|
||||||
let frameSizeClassID = getClassID(id: frameSizeClassKey)
|
let frameSizeClassID = getClassID(id: frameSizeClassKey)
|
||||||
let frameSize = objectsArray[frameSizeClassID] as! String
|
let frameSize = objectsArray[frameSizeClassID] as! String
|
||||||
|
|
||||||
info.videoFrame = parsePairString(frameSize)!
|
info.videoFrame = parsePairString(frameSize)!
|
||||||
|
|
||||||
let colorProfileClassKey = dict["colorProfile"]
|
let colorProfileClassKey = dict["colorProfile"]
|
||||||
if colorProfileClassKey != nil {
|
if colorProfileClassKey != nil {
|
||||||
let colorProfileClassID = getClassID(id: colorProfileClassKey)
|
let colorProfileClassID = getClassID(id: colorProfileClassKey)
|
||||||
let colorProfile = objectsArray[colorProfileClassID] as! NSDictionary
|
let colorProfile = objectsArray[colorProfileClassID] as! NSDictionary
|
||||||
|
|
||||||
let colorProfileNameClassKey = colorProfile["SiColorProfileArchiveICCNameKey"]
|
let colorProfileNameClassKey = colorProfile["SiColorProfileArchiveICCNameKey"]
|
||||||
let colorProfileNameClassID = getClassID(id: colorProfileNameClassKey)
|
let colorProfileNameClassID = getClassID(id: colorProfileNameClassKey)
|
||||||
let colorProfileName = objectsArray[colorProfileNameClassID] as! NSString
|
let colorProfileName = objectsArray[colorProfileNameClassID] as! NSString
|
||||||
|
|
||||||
// we only support the basic "Display P3" color space... does Procreate actually store the ICC data??
|
// we only support the basic "Display P3" color space... does Procreate actually store the ICC data??
|
||||||
if colorProfileName == "Display P3" {
|
if colorProfileName == "Display P3" {
|
||||||
info.colorSpace = CGColorSpace(name: CGColorSpace.displayP3)!
|
info.colorSpace = CGColorSpace(name: CGColorSpace.displayP3)!
|
||||||
|
@ -442,9 +442,9 @@ class Document: NSDocument {
|
||||||
let backgroundClassKey = dict["backgroundColor"]
|
let backgroundClassKey = dict["backgroundColor"]
|
||||||
let backgroundClassID = getClassID(id: backgroundClassKey)
|
let backgroundClassID = getClassID(id: backgroundClassKey)
|
||||||
let background = objectsArray[backgroundClassID] as! NSData
|
let background = objectsArray[backgroundClassID] as! NSData
|
||||||
|
|
||||||
var backgroundArray: [Float] = [0.0, 0.0, 0.0, 0.0]
|
var backgroundArray: [Float] = [0.0, 0.0, 0.0, 0.0]
|
||||||
|
|
||||||
background.getBytes(&backgroundArray, length: 16)
|
background.getBytes(&backgroundArray, length: 16)
|
||||||
let backgroundCgArray: [CGFloat] = [CGFloat(backgroundArray[0]), CGFloat(backgroundArray[1]), CGFloat(backgroundArray[2]), CGFloat(backgroundArray[3])]
|
let backgroundCgArray: [CGFloat] = [CGFloat(backgroundArray[0]), CGFloat(backgroundArray[1]), CGFloat(backgroundArray[2]), CGFloat(backgroundArray[3])]
|
||||||
|
|
||||||
|
@ -455,15 +455,15 @@ class Document: NSDocument {
|
||||||
let strokeCount = objectsArray[strokeClassID] as! NSNumber
|
let strokeCount = objectsArray[strokeClassID] as! NSNumber
|
||||||
|
|
||||||
info.strokeCount = Int(truncating: strokeCount)
|
info.strokeCount = Int(truncating: strokeCount)
|
||||||
|
|
||||||
let nameClassKey = dict[NameKey]
|
let nameClassKey = dict[NameKey]
|
||||||
let nameClassID = getClassID(id: nameClassKey)
|
let nameClassID = getClassID(id: nameClassKey)
|
||||||
let nameString = objectsArray[nameClassID] as! NSString
|
let nameString = objectsArray[nameClassID] as! NSString
|
||||||
|
|
||||||
if nameString != "$null" {
|
if nameString != "$null" {
|
||||||
info.name = nameString as String
|
info.name = nameString as String
|
||||||
}
|
}
|
||||||
|
|
||||||
let authorClassKey = dict[AuthorNameKey]
|
let authorClassKey = dict[AuthorNameKey]
|
||||||
if authorClassKey != nil {
|
if authorClassKey != nil {
|
||||||
let authorClassID = getClassID(id: authorClassKey)
|
let authorClassID = getClassID(id: authorClassKey)
|
||||||
|
@ -477,14 +477,14 @@ class Document: NSDocument {
|
||||||
let sizeClassKey = dict[SizeKey]
|
let sizeClassKey = dict[SizeKey]
|
||||||
let sizeClassID = getClassID(id: sizeClassKey)
|
let sizeClassID = getClassID(id: sizeClassKey)
|
||||||
let sizeString = objectsArray[sizeClassID] as! String
|
let sizeString = objectsArray[sizeClassID] as! String
|
||||||
|
|
||||||
let (width, height) = parsePairString(sizeString)!
|
let (width, height) = parsePairString(sizeString)!
|
||||||
info.width = width
|
info.width = width
|
||||||
info.height = height
|
info.height = height
|
||||||
|
|
||||||
columns = Int(ceil(Float(info.width) / Float(info.tileSize)))
|
columns = Int(ceil(Float(info.width) / Float(info.tileSize)))
|
||||||
rows = Int(ceil(Float(info.height) / Float(info.tileSize))) + 1 // TODO: lol why
|
rows = Int(ceil(Float(info.height) / Float(info.tileSize))) + 1 // TODO: lol why
|
||||||
|
|
||||||
if info.width % info.tileSize != 0 {
|
if info.width % info.tileSize != 0 {
|
||||||
remainderWidth = (columns * info.tileSize) - info.width
|
remainderWidth = (columns * info.tileSize) - info.width
|
||||||
}
|
}
|
||||||
|
@ -496,15 +496,15 @@ class Document: NSDocument {
|
||||||
let layersClassKey = dict[LayersKey]
|
let layersClassKey = dict[LayersKey]
|
||||||
let layersClassID = getClassID(id: layersClassKey)
|
let layersClassID = getClassID(id: layersClassKey)
|
||||||
let layersClass = objectsArray[layersClassID] as! NSDictionary
|
let layersClass = objectsArray[layersClassID] as! NSDictionary
|
||||||
|
|
||||||
let array = layersClass["NS.objects"] as! NSArray
|
let array = layersClass["NS.objects"] as! NSArray
|
||||||
|
|
||||||
for object in array {
|
for object in array {
|
||||||
let layerClassID = getClassID(id: object)
|
let layerClassID = getClassID(id: object)
|
||||||
let layerClass = objectsArray[layerClassID] as! NSDictionary
|
let layerClass = objectsArray[layerClassID] as! NSDictionary
|
||||||
|
|
||||||
guard let layer = parseSilicaLayer(archive: archive, dict: layerClass, isMask: false) else { return }
|
guard let layer = parseSilicaLayer(archive: archive, dict: layerClass, isMask: false) else { return }
|
||||||
|
|
||||||
info.layers.append(layer)
|
info.layers.append(layer)
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
@ -526,11 +526,11 @@ class Document: NSDocument {
|
||||||
let topObject = dict["$top"] as! NSDictionary
|
let topObject = dict["$top"] as! NSDictionary
|
||||||
let topClassID = objectRefGetValue2(topObject["root"] as CFTypeRef)
|
let topClassID = objectRefGetValue2(topObject["root"] as CFTypeRef)
|
||||||
let topObjectClass = objectsArray[Int(topClassID)] as! NSDictionary
|
let topObjectClass = objectsArray[Int(topClassID)] as! NSDictionary
|
||||||
|
|
||||||
parseSilicaDocument(archive: archive, dict: topObjectClass)
|
parseSilicaDocument(archive: archive, dict: topObjectClass)
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
override func read(from data: Data, ofType typeName: String) throws {
|
override func read(from data: Data, ofType typeName: String) throws {
|
||||||
self.data = data
|
self.data = data
|
||||||
|
|
||||||
|
@ -538,7 +538,7 @@ class Document: NSDocument {
|
||||||
throwError(.invalid)
|
throwError(.invalid)
|
||||||
return
|
return
|
||||||
}
|
}
|
||||||
|
|
||||||
guard let documentEntry = archive[DocumentArchivePath] else {
|
guard let documentEntry = archive[DocumentArchivePath] else {
|
||||||
throwError(.invalid)
|
throwError(.invalid)
|
||||||
return
|
return
|
||||||
|
@ -554,13 +554,13 @@ class Document: NSDocument {
|
||||||
throwError(.invalid)
|
throwError(.invalid)
|
||||||
return
|
return
|
||||||
}
|
}
|
||||||
|
|
||||||
parseDocument(archive: archive, dict: propertyList as! NSDictionary)
|
parseDocument(archive: archive, dict: propertyList as! NSDictionary)
|
||||||
}
|
}
|
||||||
|
|
||||||
func makeBlendImage(_ layer: SilicaLayer) -> CGImage {
|
func makeBlendImage(_ layer: SilicaLayer) -> CGImage {
|
||||||
var maskContext: CGContext?
|
var maskContext: CGContext?
|
||||||
|
|
||||||
if layer.mask != nil {
|
if layer.mask != nil {
|
||||||
let grayColorSpace = CGColorSpaceCreateDeviceGray()
|
let grayColorSpace = CGColorSpaceCreateDeviceGray()
|
||||||
let maskBitmapInfo = CGBitmapInfo(rawValue: CGImageAlphaInfo.none.rawValue).union(.byteOrder16Big)
|
let maskBitmapInfo = CGBitmapInfo(rawValue: CGImageAlphaInfo.none.rawValue).union(.byteOrder16Big)
|
||||||
|
@ -569,7 +569,7 @@ class Document: NSDocument {
|
||||||
|
|
||||||
maskContext?.setFillColor(.white)
|
maskContext?.setFillColor(.white)
|
||||||
maskContext?.fill(info.cgRect)
|
maskContext?.fill(info.cgRect)
|
||||||
|
|
||||||
for chunk in layer.mask!.chunks {
|
for chunk in layer.mask!.chunks {
|
||||||
maskContext?.draw(chunk.image!, in: getChunkRect(chunk))
|
maskContext?.draw(chunk.image!, in: getChunkRect(chunk))
|
||||||
}
|
}
|
||||||
|
@ -580,12 +580,12 @@ class Document: NSDocument {
|
||||||
|
|
||||||
func simpleDrawLayer(_ layer : SilicaLayerData) -> CGImage? {
|
func simpleDrawLayer(_ layer : SilicaLayerData) -> CGImage? {
|
||||||
let bitmapInfo = CGBitmapInfo(rawValue: CGImageAlphaInfo.premultipliedLast.rawValue).union(.byteOrder32Big)
|
let bitmapInfo = CGBitmapInfo(rawValue: CGImageAlphaInfo.premultipliedLast.rawValue).union(.byteOrder32Big)
|
||||||
|
|
||||||
// start by creating a new layer composite image, needed for image masking
|
// 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 layerContext = CGContext(data: nil, width: info.width, height: info.height, bitsPerComponent: 8, bytesPerRow: info.width * 4, space: info.colorSpace, bitmapInfo: bitmapInfo.rawValue)
|
||||||
|
|
||||||
layerContext?.clear(info.cgRect)
|
layerContext?.clear(info.cgRect)
|
||||||
|
|
||||||
for chunk in layer.chunks {
|
for chunk in layer.chunks {
|
||||||
layerContext?.setAlpha(1.0)
|
layerContext?.setAlpha(1.0)
|
||||||
layerContext?.setBlendMode(.normal)
|
layerContext?.setBlendMode(.normal)
|
||||||
|
@ -600,15 +600,13 @@ class Document: NSDocument {
|
||||||
|
|
||||||
func blendLayer(_ layer : SilicaLayer, previousImage : inout CGImage?) -> CIImage {
|
func blendLayer(_ layer : SilicaLayer, previousImage : inout CGImage?) -> CIImage {
|
||||||
let bitmapInfo = CGBitmapInfo(rawValue: CGImageAlphaInfo.premultipliedLast.rawValue).union(.byteOrder32Big)
|
let bitmapInfo = CGBitmapInfo(rawValue: CGImageAlphaInfo.premultipliedLast.rawValue).union(.byteOrder32Big)
|
||||||
|
|
||||||
// start by creating a new layer composite image, needed for image masking
|
// 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 layerContext = CGContext(data: nil, width: info.width, height: info.height, bitsPerComponent: 8, bytesPerRow: info.width * 4, space: info.colorSpace, bitmapInfo: bitmapInfo.rawValue)
|
||||||
|
|
||||||
layerContext?.clear(info.cgRect)
|
layerContext?.clear(info.cgRect)
|
||||||
|
|
||||||
let kernel = getBlendKernel(layer)
|
|
||||||
|
|
||||||
Swift.print(layer.name + " - " + kernel!.name)
|
let kernel = getBlendKernel(layer)
|
||||||
|
|
||||||
for chunk in layer.data.chunks {
|
for chunk in layer.data.chunks {
|
||||||
layerContext?.setAlpha(CGFloat(layer.data.opacity))
|
layerContext?.setAlpha(CGFloat(layer.data.opacity))
|
||||||
|
@ -620,7 +618,7 @@ class Document: NSDocument {
|
||||||
}
|
}
|
||||||
|
|
||||||
let layerImage = layerContext?.makeImage()
|
let layerImage = layerContext?.makeImage()
|
||||||
|
|
||||||
// apply image
|
// apply image
|
||||||
return kernel!.apply(foreground: CIImage(cgImage: layerImage!), background: previousImage == nil ? CIImage(color: .clear) : CIImage(cgImage: previousImage!), colorSpace: info.colorSpace)!
|
return kernel!.apply(foreground: CIImage(cgImage: layerImage!), background: previousImage == nil ? CIImage(color: .clear) : CIImage(cgImage: previousImage!), colorSpace: info.colorSpace)!
|
||||||
}
|
}
|
||||||
|
@ -650,14 +648,14 @@ class Document: NSDocument {
|
||||||
|
|
||||||
func blendLayer(_ layer : SilicaLayer, previousImage : inout CGImage?, applyOpacity : Bool) -> CIImage {
|
func blendLayer(_ layer : SilicaLayer, previousImage : inout CGImage?, applyOpacity : Bool) -> CIImage {
|
||||||
let bitmapInfo = CGBitmapInfo(rawValue: CGImageAlphaInfo.premultipliedLast.rawValue).union(.byteOrder32Big)
|
let bitmapInfo = CGBitmapInfo(rawValue: CGImageAlphaInfo.premultipliedLast.rawValue).union(.byteOrder32Big)
|
||||||
|
|
||||||
// start by creating a new layer composite image, needed for image masking
|
// 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 layerContext = CGContext(data: nil, width: info.width, height: info.height, bitsPerComponent: 8, bytesPerRow: info.width * 4, space: info.colorSpace, bitmapInfo: bitmapInfo.rawValue)
|
||||||
|
|
||||||
layerContext?.clear(info.cgRect)
|
layerContext?.clear(info.cgRect)
|
||||||
|
|
||||||
let kernel = getBlendKernel(layer)
|
let kernel = getBlendKernel(layer)
|
||||||
|
|
||||||
for chunk in layer.data.chunks {
|
for chunk in layer.data.chunks {
|
||||||
if applyOpacity {
|
if applyOpacity {
|
||||||
layerContext?.setAlpha(CGFloat(layer.data.opacity))
|
layerContext?.setAlpha(CGFloat(layer.data.opacity))
|
||||||
|
@ -672,7 +670,7 @@ class Document: NSDocument {
|
||||||
}
|
}
|
||||||
|
|
||||||
let layerImage = layerContext?.makeImage()
|
let layerImage = layerContext?.makeImage()
|
||||||
|
|
||||||
// apply image
|
// apply image
|
||||||
return kernel!.apply(foreground: CIImage(cgImage: layerImage!), background: previousImage == nil ? CIImage(color: .clear) : CIImage(cgImage: previousImage!), colorSpace: info.colorSpace)!
|
return kernel!.apply(foreground: CIImage(cgImage: layerImage!), background: previousImage == nil ? CIImage(color: .clear) : CIImage(cgImage: previousImage!), colorSpace: info.colorSpace)!
|
||||||
}
|
}
|
||||||
|
@ -680,12 +678,12 @@ class Document: NSDocument {
|
||||||
func makeComposite() -> NSImage? {
|
func makeComposite() -> NSImage? {
|
||||||
// create the final composite output image
|
// create the final composite output image
|
||||||
let bitmapInfo = CGBitmapInfo(rawValue: CGImageAlphaInfo.premultipliedLast.rawValue).union(.byteOrder32Big)
|
let bitmapInfo = CGBitmapInfo(rawValue: CGImageAlphaInfo.premultipliedLast.rawValue).union(.byteOrder32Big)
|
||||||
|
|
||||||
let ccgContext = CGContext(data: nil, width: info.width, height: info.height, bitsPerComponent: 8, bytesPerRow: info.width * 4, space: info.colorSpace, bitmapInfo: bitmapInfo.rawValue)
|
let ccgContext = CGContext(data: nil, width: info.width, height: info.height, bitsPerComponent: 8, bytesPerRow: info.width * 4, space: info.colorSpace, bitmapInfo: bitmapInfo.rawValue)
|
||||||
|
|
||||||
ccgContext?.setFillColor(info.backgroundColor)
|
ccgContext?.setFillColor(info.backgroundColor)
|
||||||
ccgContext?.fill(info.cgRect)
|
ccgContext?.fill(info.cgRect)
|
||||||
|
|
||||||
let context = CIContext()
|
let context = CIContext()
|
||||||
|
|
||||||
guard let cgImage = ccgContext?.makeImage() else {
|
guard let cgImage = ccgContext?.makeImage() else {
|
||||||
|
@ -693,7 +691,7 @@ class Document: NSDocument {
|
||||||
}
|
}
|
||||||
|
|
||||||
var masterImage = CIImage(cgImage: cgImage)
|
var masterImage = CIImage(cgImage: cgImage)
|
||||||
|
|
||||||
var previousImage: CGImage? = nil
|
var previousImage: CGImage? = nil
|
||||||
|
|
||||||
for layer in info.layers.reversed() {
|
for layer in info.layers.reversed() {
|
||||||
|
@ -702,9 +700,9 @@ class Document: NSDocument {
|
||||||
let layerContext = CGContext(data: nil, width: info.width, height: info.height, bitsPerComponent: 8, bytesPerRow: info.width * 4, space: info.colorSpace, bitmapInfo: bitmapInfo.rawValue)
|
let layerContext = CGContext(data: nil, width: info.width, height: info.height, bitsPerComponent: 8, bytesPerRow: info.width * 4, space: info.colorSpace, bitmapInfo: bitmapInfo.rawValue)
|
||||||
|
|
||||||
layerContext?.clear(info.cgRect)
|
layerContext?.clear(info.cgRect)
|
||||||
|
|
||||||
var maskContext: CGContext?
|
var maskContext: CGContext?
|
||||||
|
|
||||||
let kernel = getBlendKernel(layer)
|
let kernel = getBlendKernel(layer)
|
||||||
|
|
||||||
if layer.mask != nil {
|
if layer.mask != nil {
|
||||||
|
@ -715,7 +713,7 @@ class Document: NSDocument {
|
||||||
|
|
||||||
maskContext?.setFillColor(.white)
|
maskContext?.setFillColor(.white)
|
||||||
maskContext?.fill(info.cgRect)
|
maskContext?.fill(info.cgRect)
|
||||||
|
|
||||||
for chunk in layer.mask!.chunks {
|
for chunk in layer.mask!.chunks {
|
||||||
maskContext?.draw(chunk.image!, in: getChunkRect(chunk))
|
maskContext?.draw(chunk.image!, in: getChunkRect(chunk))
|
||||||
}
|
}
|
||||||
|
@ -733,13 +731,12 @@ class Document: NSDocument {
|
||||||
let clippingLayers = getAllClippingLayers(layer: layer)
|
let clippingLayers = getAllClippingLayers(layer: layer)
|
||||||
if !clippingLayers.isEmpty {
|
if !clippingLayers.isEmpty {
|
||||||
let layerImage = layerContext?.makeImage()
|
let layerImage = layerContext?.makeImage()
|
||||||
|
|
||||||
var clippedMaster: CGImage? = layerImage
|
var clippedMaster: CGImage? = layerImage
|
||||||
for layer in clippingLayers {
|
for layer in clippingLayers {
|
||||||
// so we if we want to clip, we want to gather all of the clipping layers in order first...
|
// so we if we want to clip, we want to gather all of the clipping layers in order first...
|
||||||
|
|
||||||
let temporaryClippedMaster = blendLayer(layer, previousImage: &clippedMaster)
|
let temporaryClippedMaster = blendLayer(layer, previousImage: &clippedMaster)
|
||||||
|
|
||||||
clippedMaster = context.createCGImage(temporaryClippedMaster, from: info.cgRect, format: .RGBA8, colorSpace: info.colorSpace)
|
clippedMaster = context.createCGImage(temporaryClippedMaster, from: info.cgRect, format: .RGBA8, colorSpace: info.colorSpace)
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -747,19 +744,19 @@ class Document: NSDocument {
|
||||||
layerContext?.setBlendMode(.sourceAtop)
|
layerContext?.setBlendMode(.sourceAtop)
|
||||||
|
|
||||||
layerContext?.draw(clippedMaster!, in: info.cgRect)
|
layerContext?.draw(clippedMaster!, in: info.cgRect)
|
||||||
}
|
}
|
||||||
|
|
||||||
let layerImage = layerContext?.makeImage()
|
let layerImage = layerContext?.makeImage()
|
||||||
|
|
||||||
if layer.mask != nil && maskContext != nil {
|
if layer.mask != nil && maskContext != nil {
|
||||||
let maskImage = (maskContext?.makeImage())!
|
let maskImage = (maskContext?.makeImage())!
|
||||||
let newImage = layerImage!.masking(maskImage)!
|
let newImage = layerImage!.masking(maskImage)!
|
||||||
|
|
||||||
previousImage = newImage
|
previousImage = newImage
|
||||||
} else {
|
} else {
|
||||||
previousImage = layerImage
|
previousImage = layerImage
|
||||||
}
|
}
|
||||||
|
|
||||||
// apply image
|
// apply image
|
||||||
masterImage = kernel!.apply(foreground: CIImage(cgImage: previousImage!), background: masterImage, colorSpace: info.colorSpace)!
|
masterImage = kernel!.apply(foreground: CIImage(cgImage: previousImage!), background: masterImage, colorSpace: info.colorSpace)!
|
||||||
}
|
}
|
||||||
|
@ -786,7 +783,7 @@ class Document: NSDocument {
|
||||||
} else if !info.flippedVertically && (info.orientation == 3 || info.orientation == 4) {
|
} else if !info.flippedVertically && (info.orientation == 3 || info.orientation == 4) {
|
||||||
image = image.flipHorizontally()
|
image = image.flipHorizontally()
|
||||||
}
|
}
|
||||||
|
|
||||||
return image
|
return image
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -802,7 +799,7 @@ class Document: NSDocument {
|
||||||
guard let thumbnailData = readData(archive: archive, entry: entry) else {
|
guard let thumbnailData = readData(archive: archive, entry: entry) else {
|
||||||
return nil
|
return nil
|
||||||
}
|
}
|
||||||
|
|
||||||
return NSImage(data: thumbnailData)
|
return NSImage(data: thumbnailData)
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
Reference in a new issue