diff --git a/README.md b/README.md
index e8491d1..a33646f 100644
--- a/README.md
+++ b/README.md
@@ -211,7 +211,7 @@ CGImageRef cgr = [doc cgImageWithDimension:400 error:&error];
| Bitmap | Vector |
|----------|----------|
-|||
+|||
### Set the error correction
@@ -279,12 +279,6 @@ let loadedDoc = try QRCode.Document(jsonData: jsonData)
-There are also some extensions on `CGImage` to help making qr codes even easier
-
-```swift
-let qrCodeImage = CGImage.qrCode("Hi there!", dimension: 800)
-```
-
### QRCode builder
`QRCode.Builder` is a lightweight Swift-only convenience shim for the QRCode Document.
diff --git a/Sources/QRCode/QRCode+Document+Export.swift b/Sources/QRCode/QRCode+Document+Export.swift
index abe46ae..4755adc 100644
--- a/Sources/QRCode/QRCode+Document+Export.swift
+++ b/Sources/QRCode/QRCode+Document+Export.swift
@@ -75,6 +75,7 @@ public extension QRCode.Document {
),
components: components,
shape: self.design.shape,
+ logoTemplate: self.logoTemplate,
additionalQuietSpace: additionalQuietSpace
)
}
@@ -85,11 +86,7 @@ public extension QRCode.Document {
/// - components: The components of the QR code to include in the path
/// - Returns: A path containing the components
@objc func path(dimension: Int, components: QRCode.Components = .all) -> CGPath {
- return self.qrcode.path(
- CGSize(dimension: dimension),
- components: components,
- shape: self.design.shape
- )
+ self.path(CGSize(dimension: dimension), components: components)
}
}
diff --git a/Tests/QRCodeTests/QRCodeDocGenerator.swift b/Tests/QRCodeTests/QRCodeDocGenerator.swift
index 59875ab..5bfd672 100644
--- a/Tests/QRCodeTests/QRCodeDocGenerator.swift
+++ b/Tests/QRCodeTests/QRCodeDocGenerator.swift
@@ -699,8 +699,8 @@ final class QRCodeDocGeneratorTests: XCTestCase {
func testComponentGeneration() throws {
markdownText += "## Component paths\n\n"
- markdownText += "| all | on pixels | off pixels | eye background | eye outer | eye pupil |\n"
- markdownText += "|:------:|:------:|:------:|:------:|:------:|:------:|\n"
+ markdownText += "| | all | on pixels | off pixels | eye background | eye outer | eye pupil |\n"
+ markdownText += "|:------:|:------:|:------:|:------:|:------:|:------:|:------:|\n"
let doc = try QRCode.Document(
utf8String: "QR Code generation test with a lot of content to display!",
@@ -717,54 +717,75 @@ final class QRCodeDocGeneratorTests: XCTestCase {
let rect = CGRect(origin: .zero, size: .init(width: dimension, height: dimension))
- // Do all first
+ let logoTemplate = QRCode.LogoTemplate(
+ image: try resourceImage(for: "apple", extension: "png"),
+ path: CGPath(rect: CGRect(x: 0.40, y: 0.365, width: 0.55, height: 0.25), transform: nil),
+ inset: 32
+ )
+ let logoImageC = try resourceImage(for: "instagram-icon", extension: "png")
+ let logoTemplate2 = QRCode.LogoTemplate.CircleCenter(image: logoImageC)
+
+ try [
+ ("nologo", nil),
+ ("logo-1", logoTemplate),
+ ("logo-2", logoTemplate2)
+ ].forEach { template in
+
+ doc.logoTemplate = template.1
+ let filenameaddition = template.0
+
+ markdownText += "| \(filenameaddition) "
+
+ // Do all first
+
+ do {
+ let image = try CGImage.Create(size: rect.size, flipped: true) { ctx in
+ ctx.saveGState()
+ ctx.setFillColor(CGColor.gray(0, 0.05))
+ ctx.fill([rect])
+ ctx.setStrokeColor(CGColor.gray(0, 0.8))
+ ctx.setLineWidth(0.5)
+ ctx.stroke(rect)
+ ctx.restoreGState()
+
+ for item in items {
+ let path = doc.path(dimension: self.dimension, components: item.0)
+ ctx.addPath(path)
+ ctx.setFillColor(item.2)
+ ctx.fillPath()
+ }
+ }//.flipping(.horizontally)
+
+ let content = try image.representation.png()
+ let filename = "components-all-\(filenameaddition).png"
+ let link = try imageStore.store(content, filename: filename)
+ markdownText += "|
"
+ }
+
+ // Now each individually
+
+ for item in items.enumerated() {
+ let path = doc.path(dimension: dimension, components: item.element.0)
+ let image = try CGImage.Create(size: rect.size, flipped: true) { ctx in
+ ctx.saveGState()
+ ctx.setFillColor(CGColor.gray(0, 0.05))
+ ctx.fill([rect])
+ ctx.setStrokeColor(CGColor.gray(0, 0.8))
+ ctx.setLineWidth(0.5)
+ ctx.stroke(rect)
+ ctx.restoreGState()
- do {
- let image = try CGImage.Create(size: rect.size, flipped: true) { ctx in
- ctx.saveGState()
- ctx.setFillColor(CGColor.gray(0, 0.05))
- ctx.fill([rect])
- ctx.setStrokeColor(CGColor.gray(0, 0.8))
- ctx.setLineWidth(0.5)
- ctx.stroke(rect)
- ctx.restoreGState()
-
- for item in items {
- let path = doc.path(dimension: self.dimension, components: item.0)
ctx.addPath(path)
- ctx.setFillColor(item.2)
+ ctx.setFillColor(item.element.2)
ctx.fillPath()
}
- }//.flipping(.horizontally)
- let content = try image.representation.png()
- let filename = "components-all.png"
- let link = try imageStore.store(content, filename: filename)
- markdownText += "
|"
- }
-
- // Now each individually
-
- for item in items.enumerated() {
- let path = doc.path(dimension: dimension, components: item.element.0)
- let image = try CGImage.Create(size: rect.size, flipped: true) { ctx in
- ctx.saveGState()
- ctx.setFillColor(CGColor.gray(0, 0.05))
- ctx.fill([rect])
- ctx.setStrokeColor(CGColor.gray(0, 0.8))
- ctx.setLineWidth(0.5)
- ctx.stroke(rect)
- ctx.restoreGState()
-
- ctx.addPath(path)
- ctx.setFillColor(item.element.2)
- ctx.fillPath()
+ let content = try image.representation.png()
+ let filename = "components-\(item.offset)-\(filenameaddition).png"
+ let link = try imageStore.store(content, filename: filename)
+ markdownText += "|"
}
-
- let content = try image.representation.png()
- let filename = "components-\(item.offset).png"
- let link = try imageStore.store(content, filename: filename)
- markdownText += "|"
+ markdownText += "|\n"
}
markdownText += "\n"
diff --git a/Tests/QRCodeTests/QRCodeMaskingTests.swift b/Tests/QRCodeTests/QRCodeMaskingTests.swift
index 0349f06..4e26435 100644
--- a/Tests/QRCodeTests/QRCodeMaskingTests.swift
+++ b/Tests/QRCodeTests/QRCodeMaskingTests.swift
@@ -328,4 +328,52 @@ final class QRCodeMaskingTests: XCTestCase {
try outputFolder.write(pdfhBigger, to: "logotemplate-issue34-height-bigger-\(quietSpace).pdf")
}
}
+
+ func testPathGenerationWithLogoTemplate() throws {
+
+ // Check that generating a CGPath contains a hole for the logotemplate if it exists
+
+ let outputFolder = try outputFolder.subfolder(with: "logo-path-check")
+
+ let logoImage = try resourceImage(for: "instagram-icon", extension: "png")
+ let logoTemplate = QRCode.LogoTemplate(
+ image: logoImage,
+ path: CGPath(ellipseIn: CGRect(x: 0.65, y: 0.35, width: 0.30, height: 0.30), transform: nil),
+ inset: 8
+ )
+
+ let doc = try QRCode.build
+ .text("Logo template checking with path export Logo template checking with path export Logo template checking with path export")
+ .backgroundColor(CGColor(srgbRed: 1, green: 1, blue: 0, alpha: 1))
+ .eye.shape(QRCode.EyeShape.Squircle())
+ .document
+
+ try [0, 12].forEach { quietSpace in
+ doc.design.additionalQuietZonePixels = UInt(quietSpace)
+
+ do {
+ // No logotemplate
+ doc.logoTemplate = nil
+ let path = doc.path(dimension: 400)
+ let b1 = try CreateBitmap(dimension: 400, backgroundColor: CGColor.commonWhite) { ctx in
+ ctx.addPath(path)
+ ctx.setFillColor(.commonBlack)
+ ctx.fillPath()
+ }
+ try outputFolder.write(try b1.representation.png(), to: "path-without-logotemplate-\(quietSpace).png")
+ }
+
+ do {
+ // No logotemplate
+ doc.logoTemplate = logoTemplate
+ let path = doc.path(dimension: 400)
+ let b1 = try CreateBitmap(dimension: 400, backgroundColor: CGColor.commonWhite) { ctx in
+ ctx.addPath(path)
+ ctx.setFillColor(.commonBlack)
+ ctx.fillPath()
+ }
+ try outputFolder.write(try b1.representation.png(), to: "path-with-logotemplate-\(quietSpace).png")
+ }
+ }
+ }
}
diff --git a/Tests/QRCodeTests/Utils.swift b/Tests/QRCodeTests/Utils.swift
index f3eaacf..a14d07e 100644
--- a/Tests/QRCodeTests/Utils.swift
+++ b/Tests/QRCodeTests/Utils.swift
@@ -121,7 +121,7 @@ enum CreateBitmapError: Error {
}
/// Create a bitmap and draw into it
-func CreateBitmap(dimension: Int, flipped: Bool = true, _ block: (CGContext) -> Void) throws -> CGImage {
+func CreateBitmap(dimension: Int, backgroundColor: CGColor? = nil, flipped: Bool = true, _ block: (CGContext) -> Void) throws -> CGImage {
let bitmapInfo = CGBitmapInfo(rawValue: CGImageAlphaInfo.premultipliedLast.rawValue)
let colorSpace = CGColorSpace(name: CGColorSpace.sRGB)!
guard let ctx = CGContext(
@@ -141,6 +141,14 @@ func CreateBitmap(dimension: Int, flipped: Bool = true, _ block: (CGContext) ->
ctx.scaleBy(x: 1, y: -1)
ctx.translateBy(x: 0, y: Double(-dimension))
}
+
+ if let backgroundColor = backgroundColor {
+ ctx.usingGState { c in
+ c.setFillColor(backgroundColor)
+ c.fill(CGRect(origin: .zero, size: CGSize(width: ctx.width, height: ctx.height)))
+ }
+ }
+
block(ctx)
guard let img = ctx.makeImage() else {