From 292a46d025c39406c81ebc807835ad960de7cd24 Mon Sep 17 00:00:00 2001 From: fwcd Date: Tue, 25 Feb 2020 00:08:07 +0100 Subject: [PATCH] Port .drawCodewords and .apply(mask:) to Swift --- swift/Sources/QRCodeGenerator/QRCode.swift | 56 ++++++++++++++++++- .../QRCodeGenerator/QRCodeMiscellaneous.swift | 2 +- 2 files changed, 56 insertions(+), 2 deletions(-) diff --git a/swift/Sources/QRCodeGenerator/QRCode.swift b/swift/Sources/QRCodeGenerator/QRCode.swift index bae32f5..824b479 100644 --- a/swift/Sources/QRCodeGenerator/QRCode.swift +++ b/swift/Sources/QRCodeGenerator/QRCode.swift @@ -207,7 +207,7 @@ struct QRCode { // Compute ECC, draw modules result.drawFunctionPatterns() let allCodeWords = result.addECCAndInterleave(dataCodeWords: dataCodeWords) - result.draw(codewords: allCodeWords) + result.drawCodewords(data: allCodeWords) // Do masking if mask == nil { // Automatically choose best mask @@ -445,4 +445,58 @@ struct QRCode { return result } + + /// Draws the given sequence of 8-bit codewords (data and error correction) onto the entire + /// data area of this QR Code. Function modules need to be marked off before this is called. + private mutating func drawCodewords(data: [UInt8]) { + assert(data.count == QRCode.getNumRawDataModules(version: version) / 8, "Illegal argument") + + var i: Int = 0 // Bit index into the data + // Do the funny zigzag scan + var right: Int = size - 1 + while right >= 1 { // Index of right column in each column pair + if right == 6 { + right = 5 + } + for vert in 0..> 3]), 7 - (Int32(i & 7))) + i += 1 + } + // If this QR code has any remainder bits (0 to 7), they were assigned as + // 0/false/white by the constructor and are left unchanged by this method + } + } + right -= 2 + } + assert(i == data.count * 8) + } + + // XORs the codeword modules in this QR Code with the given mask pattern. + // The function modules must be marked and the codeword bits must be drawn + // before masking. Due to the arithmetic of XOR, calling applyMask() with + // the same mask value a second time will undo the mask. A final well-formed + // QR Code needs exactly one (not zero, two, etc.) mask applied. + private mutating func apply(mask: QRCodeMask) { + for y in 0.. Bool { +func getBit(_ x: UInt32, _ i: Int32) -> Bool { (x >> i) & 1 != 0 }