mirror of
https://github.com/Swiftgram/Telegram-iOS.git
synced 2025-12-23 14:45:21 +00:00
Various UI fixes
This commit is contained in:
@@ -45,13 +45,33 @@ public func qrCode(string: String, color: UIColor, backgroundColor: UIColor? = n
|
||||
|> map { data, size, bytesPerRow in
|
||||
return { arguments in
|
||||
let context = DrawingContext(size: arguments.drawingSize, scale: arguments.scale ?? 0.0, clear: true)
|
||||
|
||||
let start = CFAbsoluteTimeGetCurrent()
|
||||
|
||||
let mid = Int(size / 2)
|
||||
|
||||
let cutout: (Int, Int)?
|
||||
if case .none = icon {
|
||||
cutout = nil
|
||||
} else {
|
||||
switch size {
|
||||
case 39:
|
||||
cutout = (14, 24)
|
||||
case 43:
|
||||
cutout = (15, 27)
|
||||
case 47:
|
||||
cutout = (17, 29)
|
||||
case 51:
|
||||
cutout = (19, 31)
|
||||
case 55:
|
||||
cutout = (21, 33)
|
||||
case 59:
|
||||
cutout = (22, 36)
|
||||
case 63:
|
||||
cutout = (23, 39)
|
||||
default:
|
||||
cutout = (16, 26)
|
||||
}
|
||||
}
|
||||
func valueAt(x: Int, y: Int) -> Bool {
|
||||
if x >= 0 && x < size && y >= 0 && y < size {
|
||||
if x > (mid - 5) && x < (mid + 5) && y > (mid - 5) && y < (mid + 5) {
|
||||
if let cutout = cutout, x > cutout.0 && x < cutout.1 && y > cutout.0 && y < cutout.1 {
|
||||
return false
|
||||
}
|
||||
|
||||
@@ -67,8 +87,8 @@ public func qrCode(string: String, color: UIColor, backgroundColor: UIColor? = n
|
||||
}
|
||||
}
|
||||
|
||||
let side = Int(floor(arguments.drawingSize.width / CGFloat(size)))
|
||||
let padding: CGFloat = floor((arguments.drawingSize.width - CGFloat(side * size)) / 2.0)
|
||||
let side = floorToScreenPixels(arguments.drawingSize.width / CGFloat(size))
|
||||
let padding: CGFloat = floor((arguments.drawingSize.width - CGFloat(side * CGFloat(size))) / 2.0)
|
||||
|
||||
let squareSize = CGSize(width: side, height: side)
|
||||
let tmpContext = DrawingContext(size: CGSize(width: squareSize.width * 4.0, height: squareSize.height), scale: arguments.scale ?? 0.0, clear: true)
|
||||
@@ -106,14 +126,14 @@ public func qrCode(string: String, color: UIColor, backgroundColor: UIColor? = n
|
||||
let halfLen = scaledSquareSize * 4 / 2
|
||||
let blockLen = scaledSquareSize * 4 * 2
|
||||
|
||||
func drawAt(x: Int, y: Int, black: Bool, corners: UIRectCorner) {
|
||||
if !black && corners.isEmpty {
|
||||
func drawAt(x: Int, y: Int, fill: Bool, corners: UIRectCorner) {
|
||||
if !fill && corners.isEmpty {
|
||||
return
|
||||
}
|
||||
|
||||
for i in 0 ..< scaledSquareSize {
|
||||
var dst = context.bytes.advanced(by: (scaledPadding + y * scaledSquareSize + i) * context.bytesPerRow + (scaledPadding + x * scaledSquareSize) * 4)
|
||||
let srcOffset = (black ? 0 : scaledSquareSize * 4)
|
||||
let srcOffset = (fill ? 0 : scaledSquareSize * 4)
|
||||
let src = tmpContext.bytes.advanced(by: i * tmpContext.bytesPerRow + srcOffset)
|
||||
|
||||
if corners.contains(i < scaledSquareSize / 2 ? .topLeft : .bottomLeft) {
|
||||
@@ -169,8 +189,7 @@ public func qrCode(string: String, color: UIColor, backgroundColor: UIColor? = n
|
||||
corners.remove(.topRight)
|
||||
corners.remove(.bottomRight)
|
||||
}
|
||||
|
||||
drawAt(x: x, y: y, black: true, corners: corners)
|
||||
drawAt(x: x, y: y, fill: true, corners: corners)
|
||||
} else {
|
||||
if valueAt(x: x - 1, y: y - 1) && valueAt(x: x - 1, y: y) && valueAt(x: x, y: y - 1) {
|
||||
corners.insert(.topLeft)
|
||||
@@ -184,8 +203,7 @@ public func qrCode(string: String, color: UIColor, backgroundColor: UIColor? = n
|
||||
if valueAt(x: x + 1, y: y + 1) && valueAt(x: x + 1, y: y) && valueAt(x: x, y: y + 1) {
|
||||
corners.insert(.bottomRight)
|
||||
}
|
||||
|
||||
drawAt(x: x, y: y, black: false, corners: corners)
|
||||
drawAt(x: x, y: y, fill: false, corners: corners)
|
||||
}
|
||||
}
|
||||
}
|
||||
@@ -218,30 +236,14 @@ public func qrCode(string: String, color: UIColor, backgroundColor: UIColor? = n
|
||||
let drawingRect = arguments.drawingRect
|
||||
let fittedSize = arguments.imageSize.aspectFilled(arguments.boundingSize).fitted(arguments.imageSize)
|
||||
let fittedRect = CGRect(origin: CGPoint(x: drawingRect.origin.x + (drawingRect.size.width - fittedSize.width) / 2.0, y: drawingRect.origin.y + (drawingRect.size.height - fittedSize.height) / 2.0), size: fittedSize)
|
||||
|
||||
if let backgroundColor = backgroundColor {
|
||||
c.setFillColor(backgroundColor.cgColor)
|
||||
} else {
|
||||
c.setBlendMode(.clear)
|
||||
c.setFillColor(UIColor.clear.cgColor)
|
||||
}
|
||||
|
||||
let codeScale = 43.0 / CGFloat(size)
|
||||
|
||||
let codeScale: CGFloat = 43.0 / 39.0
|
||||
let clipSide = 56.0 * fittedRect.width / 267.0 * codeScale
|
||||
let clipRect = CGRect(x: fittedRect.midX - clipSide / 2.0, y: fittedRect.midY - clipSide / 2.0, width: clipSide, height: clipSide)
|
||||
switch icon {
|
||||
case .cutout, .proxy, .custom:
|
||||
break
|
||||
//c.fill(clipRect)
|
||||
default:
|
||||
break
|
||||
}
|
||||
|
||||
c.setBlendMode(.normal)
|
||||
|
||||
|
||||
switch icon {
|
||||
case .proxy:
|
||||
let iconScale = fittedRect.width / 445.0 * codeScale
|
||||
let iconScale = fittedRect.width / 420.0 * codeScale
|
||||
let iconSize = CGSize(width: 65.0 * iconScale, height: 79.0 * iconScale)
|
||||
let point = CGPoint(x: fittedRect.midX - iconSize.width / 2.0, y: fittedRect.midY - iconSize.height / 2.0)
|
||||
c.translateBy(x: point.x, y: point.y)
|
||||
@@ -275,124 +277,6 @@ public func qrCode(string: String, color: UIColor, backgroundColor: UIColor? = n
|
||||
}
|
||||
}
|
||||
|
||||
let end = CFAbsoluteTimeGetCurrent() - start
|
||||
print(end)
|
||||
|
||||
return context
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
public func aqrCode(string: String, color: UIColor, backgroundColor: UIColor? = nil, icon: QrCodeIcon, ecl: String = "M") -> Signal<(TransformImageArguments) -> DrawingContext?, NoError> {
|
||||
var icon: QrCodeIcon = .none
|
||||
return Signal<CIImage, NoError> { subscriber in
|
||||
if let data = string.data(using: .isoLatin1, allowLossyConversion: false), let filter = CIFilter(name: "CIQRCodeGenerator") {
|
||||
filter.setValue(data, forKey: "inputMessage")
|
||||
filter.setValue(ecl, forKey: "inputCorrectionLevel")
|
||||
|
||||
if let output = filter.outputImage {
|
||||
subscriber.putNext(output)
|
||||
}
|
||||
}
|
||||
subscriber.putCompletion()
|
||||
return EmptyDisposable
|
||||
}
|
||||
|> map { inputImage in
|
||||
return { arguments in
|
||||
let context = DrawingContext(size: arguments.drawingSize, scale: arguments.scale ?? 0.0, clear: true)
|
||||
|
||||
let drawingRect = arguments.drawingRect
|
||||
let fittedSize = arguments.imageSize.aspectFilled(arguments.boundingSize).fitted(arguments.imageSize)
|
||||
let fittedRect = CGRect(origin: CGPoint(x: drawingRect.origin.x + (drawingRect.size.width - fittedSize.width) / 2.0, y: drawingRect.origin.y + (drawingRect.size.height - fittedSize.height) / 2.0), size: fittedSize)
|
||||
|
||||
let scale = arguments.drawingRect.size.width / inputImage.extent.width * context.scale
|
||||
let transformed = inputImage.transformed(by: CGAffineTransform.init(scaleX: scale, y: scale))
|
||||
|
||||
let codeScale = 43.0 / inputImage.extent.width
|
||||
|
||||
let invertFilter = CIFilter(name: "CIColorInvert")
|
||||
invertFilter?.setValue(transformed, forKey: kCIInputImageKey)
|
||||
let alphaFilter = CIFilter(name: "CIMaskToAlpha")
|
||||
alphaFilter?.setValue(invertFilter?.outputImage, forKey: kCIInputImageKey)
|
||||
|
||||
var image: CGImage?
|
||||
let ciContext = CIContext(options: nil)
|
||||
if let finalImage = alphaFilter?.outputImage, let cgImage = ciContext.createCGImage(finalImage, from: finalImage.extent) {
|
||||
image = cgImage
|
||||
}
|
||||
|
||||
context.withContext { c in
|
||||
if let backgroundColor = backgroundColor {
|
||||
c.setFillColor(backgroundColor.cgColor)
|
||||
c.fill(drawingRect)
|
||||
}
|
||||
|
||||
c.setBlendMode(.normal)
|
||||
if let image = image {
|
||||
c.saveGState()
|
||||
c.translateBy(x: fittedRect.midX, y: fittedRect.midY)
|
||||
c.scaleBy(x: 1.0, y: -1.0)
|
||||
c.translateBy(x: -fittedRect.midX, y: -fittedRect.midY)
|
||||
|
||||
c.clip(to: fittedRect, mask: image)
|
||||
c.setFillColor(color.cgColor)
|
||||
c.fill(fittedRect)
|
||||
c.restoreGState()
|
||||
}
|
||||
if let backgroundColor = backgroundColor {
|
||||
c.setFillColor(backgroundColor.cgColor)
|
||||
} else {
|
||||
c.setBlendMode(.clear)
|
||||
c.setFillColor(UIColor.clear.cgColor)
|
||||
}
|
||||
|
||||
let clipSide = 56.0 * fittedRect.width / 267.0 * codeScale
|
||||
let clipRect = CGRect(x: fittedRect.midX - clipSide / 2.0, y: fittedRect.midY - clipSide / 2.0, width: clipSide, height: clipSide)
|
||||
switch icon {
|
||||
case .cutout, .proxy, .custom:
|
||||
c.fill(clipRect)
|
||||
default:
|
||||
break
|
||||
}
|
||||
|
||||
c.setBlendMode(.normal)
|
||||
|
||||
switch icon {
|
||||
case .proxy:
|
||||
let iconScale = fittedRect.width / 445.0 * codeScale
|
||||
let iconSize = CGSize(width: 65.0 * iconScale, height: 79.0 * iconScale)
|
||||
let point = CGPoint(x: fittedRect.midX - iconSize.width / 2.0, y: fittedRect.midY - iconSize.height / 2.0)
|
||||
c.translateBy(x: point.x, y: point.y)
|
||||
c.scaleBy(x: iconScale, y: iconScale)
|
||||
c.setFillColor(color.cgColor)
|
||||
let _ = try? drawSvgPath(c, path: "M0.0,40 C0,20.3664202 20.1230605,0.0 32.5,0.0 C44.8769395,0.0 65,20.3664202 65,40 C65,47.217934 65,55.5505326 65,64.9977957 L32.5,79 L0.0,64.9977957 C0.0,55.0825772 0.0,46.7499786 0.0,40 Z")
|
||||
|
||||
if let backgroundColor = backgroundColor {
|
||||
c.setFillColor(backgroundColor.cgColor)
|
||||
} else {
|
||||
c.setBlendMode(.clear)
|
||||
c.setFillColor(UIColor.clear.cgColor)
|
||||
}
|
||||
let _ = try? drawSvgPath(c, path: "M7.03608247,43.556701 L18.9836689,32.8350515 L32.5,39.871134 L45.8888139,32.8350515 L57.9639175,43.556701 L57.9639175,60.0 L32.5,71.0 L7.03608247,60.0 Z")
|
||||
|
||||
c.setBlendMode(.normal)
|
||||
c.setFillColor(color.cgColor)
|
||||
let _ = try? drawSvgPath(c, path: "M24.1237113,50.5927835 L40.8762887,50.5927835 L40.8762887,60.9793814 L32.5,64.0928525 L24.1237113,60.9793814 Z")
|
||||
case let .custom(image):
|
||||
if let image = image {
|
||||
let fittedSize = image.size.aspectFitted(clipRect.size)
|
||||
let fittedRect = CGRect(origin: CGPoint(x: fittedRect.midX - fittedSize.width / 2.0, y: fittedRect.midY - fittedSize.height / 2.0), size: fittedSize)
|
||||
c.translateBy(x: fittedRect.midX, y: fittedRect.midY)
|
||||
c.scaleBy(x: 1.0, y: -1.0)
|
||||
c.translateBy(x: -fittedRect.midX, y: -fittedRect.midY)
|
||||
c.draw(image.cgImage!, in: fittedRect)
|
||||
}
|
||||
break
|
||||
default:
|
||||
break
|
||||
}
|
||||
}
|
||||
|
||||
return context
|
||||
}
|
||||
}
|
||||
|
||||
Reference in New Issue
Block a user