diff --git a/Sources/ResgenSwift/Images/Generator/XcassetsGenerator.swift b/Sources/ResgenSwift/Images/Generator/XcassetsGenerator.swift index fec56e7..768695b 100644 --- a/Sources/ResgenSwift/Images/Generator/XcassetsGenerator.swift +++ b/Sources/ResgenSwift/Images/Generator/XcassetsGenerator.swift @@ -8,10 +8,13 @@ import Foundation import ToolCore +enum OutputImageExtension: String { + case png + case svg +} + class XcassetsGenerator { - - static let outputImageExtension = "png" - + let forceGeneration: Bool // MARK: - Init @@ -60,10 +63,10 @@ class XcassetsGenerator { generatedAssetsPaths.append(imagesetName) // Generate output images path - let output1x = "\(imagesetPath)/\(parsedImage.name).\(XcassetsGenerator.outputImageExtension)" - let output2x = "\(imagesetPath)/\(parsedImage.name)@2x.\(XcassetsGenerator.outputImageExtension)" - let output3x = "\(imagesetPath)/\(parsedImage.name)@3x.\(XcassetsGenerator.outputImageExtension)" - + let output1x = "\(imagesetPath)/\(parsedImage.name).\(OutputImageExtension.png.rawValue)" + let output2x = "\(imagesetPath)/\(parsedImage.name)@2x.\(OutputImageExtension.png.rawValue)" + let output3x = "\(imagesetPath)/\(parsedImage.name)@3x.\(OutputImageExtension.png.rawValue)" + // Check if we need to convert image guard self.shouldGenerate(inputImagePath: imageData.path, xcassetImagePath: output1x) else { //print("\(parsedImage.name) -> Not regenerating") @@ -81,25 +84,38 @@ class XcassetsGenerator { Images.exit(withError: error) } } - - // Convert image + let convertArguments = parsedImage.convertArguments - if imageData.ext == "svg" { + + if parsedImage.imageExtensions.contains(.vector) { + let output = "\(imagesetPath)/\(parsedImage.name).\(OutputImageExtension.svg.rawValue)" + let tempURL = URL(fileURLWithPath: output) + + do { + if FileManager.default.fileExists(atPath: tempURL.path) { + try FileManager.default.removeItem(atPath: tempURL.path) + } + try FileManager.default.copyItem(atPath: imageData.path, toPath: tempURL.path) + } catch { + print(error.localizedDescription) + } + + } else if imageData.ext == "svg" { // /usr/local/bin/rsvg-convert path/to/image.png -w 200 -h 300 -o path/to/output.png // /usr/local/bin/rsvg-convert path/to/image.png -w 200 -o path/to/output.png // /usr/local/bin/rsvg-convert path/to/image.png -h 300 -o path/to/output.png var command1x = ["\(svgConverter)", "\(imageData.path)"] var command2x = ["\(svgConverter)", "\(imageData.path)"] var command3x = ["\(svgConverter)", "\(imageData.path)"] - + self.addConvertArgument(command: &command1x, convertArgument: convertArguments.x1) self.addConvertArgument(command: &command2x, convertArgument: convertArguments.x2) self.addConvertArgument(command: &command3x, convertArgument: convertArguments.x3) - + command1x.append(contentsOf: ["-o", output1x]) command2x.append(contentsOf: ["-o", output2x]) command3x.append(contentsOf: ["-o", output3x]) - + Shell.shell(command1x) Shell.shell(command2x) Shell.shell(command3x) diff --git a/Sources/ResgenSwift/Images/Model/ImageContent.swift b/Sources/ResgenSwift/Images/Model/ImageContent.swift index 55847d8..fc6f37f 100644 --- a/Sources/ResgenSwift/Images/Model/ImageContent.swift +++ b/Sources/ResgenSwift/Images/Model/ImageContent.swift @@ -7,14 +7,30 @@ import Foundation +enum TemplateRenderingIntent: String, Codable { + case template + case original +} + struct AssetContent: Codable, Equatable { let images: [AssetImageDescription] let info: AssetInfo + let properties: AssetProperties? + + init( + images: [AssetImageDescription], + info: AssetInfo, + properties: AssetProperties? = nil + ) { + self.images = images + self.info = info + self.properties = properties + } static func == (lhs: AssetContent, rhs: AssetContent) -> Bool { guard lhs.images.count == rhs.images.count else { return false } - let lhsImages = lhs.images.sorted(by: { $0.scale < $1.scale }) - let rhsImages = rhs.images.sorted(by: { $0.scale < $1.scale }) + let lhsImages = lhs.images.sorted(by: { $0.filename < $1.filename }) + let rhsImages = rhs.images.sorted(by: { $0.filename < $1.filename }) return lhsImages == rhsImages } @@ -22,11 +38,39 @@ struct AssetContent: Codable, Equatable { struct AssetImageDescription: Codable, Equatable { let idiom: String - let scale: String + let scale: String? let filename: String + + init( + idiom: String, + scale: String? = nil, + filename: String + ) { + self.idiom = idiom + self.scale = scale + self.filename = filename + } } struct AssetInfo: Codable, Equatable { let version: Int let author: String } + +struct AssetProperties: Codable, Equatable { + let preservesVectorRepresentation: Bool + let templateRenderingIntent: TemplateRenderingIntent? + + init( + preservesVectorRepresentation: Bool, + templateRenderingIntent: TemplateRenderingIntent? = nil + ) { + self.preservesVectorRepresentation = preservesVectorRepresentation + self.templateRenderingIntent = templateRenderingIntent + } + + enum CodingKeys: String, CodingKey { + case preservesVectorRepresentation = "preserves-vector-representation" + case templateRenderingIntent = "template-rendering-intent" + } +} diff --git a/Sources/ResgenSwift/Images/Model/ParsedImage.swift b/Sources/ResgenSwift/Images/Model/ParsedImage.swift index 096c5c0..f43368c 100644 --- a/Sources/ResgenSwift/Images/Model/ParsedImage.swift +++ b/Sources/ResgenSwift/Images/Model/ParsedImage.swift @@ -7,12 +7,31 @@ import Foundation +enum ImageExtension: String { + case vector +} + struct ParsedImage { let name: String let tags: String let width: Int let height: Int - + let imageExtensions: [ImageExtension] + + init( + name: String, + tags: String, + width: Int, + height: Int, + imageExtensions: [ImageExtension] = [] + ) { + self.name = name + self.tags = tags + self.width = width + self.height = height + self.imageExtensions = imageExtensions + } + // MARK: - Convert var convertArguments: (x1: ConvertArgument, x2: ConvertArgument, x3: ConvertArgument) { @@ -56,29 +75,49 @@ struct ParsedImage { } var imageContent: AssetContent { - return AssetContent( - images: [ - AssetImageDescription( - idiom: "universal", - scale: "1x", - filename: "\(name).\(XcassetsGenerator.outputImageExtension)" + if imageExtensions.contains(.vector) { + return AssetContent( + images: [ + AssetImageDescription( + idiom: "universal", + filename: "\(name).\(OutputImageExtension.svg.rawValue)" + ) + ], + info: AssetInfo( + version: 1, + author: "ResgenSwift-Imagium" ), - AssetImageDescription( - idiom: "universal", - scale: "2x", - filename: "\(name)@2x.\(XcassetsGenerator.outputImageExtension)" - ), - AssetImageDescription( - idiom: "universal", - scale: "3x", - filename: "\(name)@3x.\(XcassetsGenerator.outputImageExtension)" + properties: AssetProperties( + preservesVectorRepresentation: true, + templateRenderingIntent: .template ) - ], - info: AssetInfo( - version: 1, - author: "ResgenSwift-Imagium" ) - ) + } else { + + return AssetContent( + images: [ + AssetImageDescription( + idiom: "universal", + scale: "1x", + filename: "\(name).\(OutputImageExtension.png.rawValue)" + ), + AssetImageDescription( + idiom: "universal", + scale: "2x", + filename: "\(name)@2x.\(OutputImageExtension.png.rawValue)" + ), + AssetImageDescription( + idiom: "universal", + scale: "3x", + filename: "\(name)@3x.\(OutputImageExtension.png.rawValue)" + ) + ], + info: AssetInfo( + version: 1, + author: "ResgenSwift-Imagium" + ) + ) + } } // MARK: - Extension property diff --git a/Sources/ResgenSwift/Images/Parser/ImageFileParser.swift b/Sources/ResgenSwift/Images/Parser/ImageFileParser.swift index 8a66d41..eb2278b 100644 --- a/Sources/ResgenSwift/Images/Parser/ImageFileParser.swift +++ b/Sources/ResgenSwift/Images/Parser/ImageFileParser.swift @@ -38,11 +38,21 @@ class ImageFileParser { } return Int(splittedLine[3])! }() - - let image = ParsedImage(name: String(splittedLine[1]), tags: String(splittedLine[0]), width: width, height: height) + + var imageExtensions: [ImageExtension] = [] + + splittedLine.forEach { stringExtension in + if let imageExtension = ImageExtension(rawValue: String(stringExtension)) { + imageExtensions.append(imageExtension) + } + } + + let image = ParsedImage(name: String(splittedLine[1]), tags: String(splittedLine[0]), width: width, height: height, imageExtensions: imageExtensions) imagesToGenerate.append(image) } - + + print(imagesToGenerate) + return imagesToGenerate.filter { $0.tags.contains(platform.rawValue) } diff --git a/Tests/ResgenSwiftTests/Images/ImageFileParserTests.swift b/Tests/ResgenSwiftTests/Images/ImageFileParserTests.swift index 0dad2e6..8122150 100644 --- a/Tests/ResgenSwiftTests/Images/ImageFileParserTests.swift +++ b/Tests/ResgenSwiftTests/Images/ImageFileParserTests.swift @@ -17,8 +17,8 @@ class ImageFileParserTests: XCTestCase { # # SMAAS Support # - id image_one 25 ? - di image_two ? 50 + id image_one 25 ? vector + di image_two ? 50 webp vector d image_three 25 ? d image_four 75 ? """ @@ -38,13 +38,15 @@ class ImageFileParserTests: XCTestCase { XCTAssertEqual(firstImage!.tags, "id") XCTAssertEqual(firstImage!.width, 25) XCTAssertEqual(firstImage!.height, -1) - + XCTAssertEqual(firstImage!.imageExtensions, [.vector]) + let secondImage = parsedImages.first { $0.name == "image_two" } XCTAssertEqual(secondImage!.name, "image_two") XCTAssertEqual(secondImage!.tags, "di") XCTAssertEqual(secondImage!.width, -1) - XCTAssertEqual(secondImage!.height, 50) + XCTAssertEqual(secondImage!.height, 50) + XCTAssertEqual(firstImage!.imageExtensions, [.vector]) } } diff --git a/Tests/ResgenSwiftTests/Images/ParsedImageTests.swift b/Tests/ResgenSwiftTests/Images/ParsedImageTests.swift index 0fea3d8..45a0401 100644 --- a/Tests/ResgenSwiftTests/Images/ParsedImageTests.swift +++ b/Tests/ResgenSwiftTests/Images/ParsedImageTests.swift @@ -135,17 +135,17 @@ final class ParsedImageTests: XCTestCase { AssetImageDescription( idiom: "universal", scale: "1x", - filename: "\(parsedImage.name).\(XcassetsGenerator.outputImageExtension)" + filename: "\(parsedImage.name).\(OutputImageExtension.png.rawValue)" ), AssetImageDescription( idiom: "universal", scale: "2x", - filename: "\(parsedImage.name)@2x.\(XcassetsGenerator.outputImageExtension)" + filename: "\(parsedImage.name)@2x.\(OutputImageExtension.png.rawValue)" ), AssetImageDescription( idiom: "universal", scale: "3x", - filename: "\(parsedImage.name)@3x.\(XcassetsGenerator.outputImageExtension)" + filename: "\(parsedImage.name)@3x.\(OutputImageExtension.png.rawValue)" ) ], info: AssetInfo( @@ -156,4 +156,40 @@ final class ParsedImageTests: XCTestCase { XCTAssertEqual(property, expect) } + + func testAssetVector() { + // Given + let imageName = "the_name" + let parsedImage = ParsedImage(name: imageName, + tags: "id", + width: 10, + height: 10, + imageExtensions: [.vector]) + + // When + let property = parsedImage.imageContent + + // Expect + let expect = AssetContent( + images: [ + AssetImageDescription( + idiom: "universal", + filename: "\(parsedImage.name).\(OutputImageExtension.svg.rawValue)" + ) + ], + info: AssetInfo( + version: 1, + author: "ResgenSwift-Imagium" + ), + properties: AssetProperties( + preservesVectorRepresentation: true, + templateRenderingIntent: .template + ) + ) + + debugPrint(property) + debugPrint(expect) + + XCTAssertEqual(property, expect) + } }