123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316317318319320321322323324325326327328329330331332333334335336337338339340341342343344345346347348349350351352353354355356357358359360361362363364365366367368369370371372373374375376377378379380381382383384385386387388389390391392393394395396397398399400401402403404405406407408409410411412413414415416417418419420421422423424425426427428429430431432433434435436437438439440441442443444445446447448449450451452453454455456457458459460461462463464465466467468469470471472473474475476477478479480481482483484485486487488489490491492493494495496497498499500501502503504505506507508 |
- //
- // CStampPreview.swift
- // ComPDFKit_Tools
- //
- // Copyright © 2014-2024 PDF Technologies, Inc. All Rights Reserved.
- //
- // THIS SOURCE CODE AND ANY ACCOMPANYING DOCUMENTATION ARE PROTECTED BY INTERNATIONAL COPYRIGHT LAW
- // AND MAY NOT BE RESOLD OR REDISTRIBUTED. USAGE IS BOUND TO THE ComPDFKit LICENSE AGREEMENT.
- // UNAUTHORIZED REPRODUCTION OR DISTRIBUTION IS SUBJECT TO CIVIL AND CRIMINAL PENALTIES.
- // This notice may not be removed from this file.
- //
- import UIKit
- enum TextStampType: Int {
- case center = 0
- case left
- case right
- case none
- }
- enum TextStampColorType: Int {
- case black = 0
- case red
- case green
- case blue
- }
- class CStampPreview: UIView {
- var colors: [Double] = [0.0, 0.0, 0.0]
- var textStampStyle: TextStampType = .center
- var textStampColorStyle: TextStampColorType = .black {
- didSet {
- if .red == textStampColorStyle {
- colors[0] = 0.57
- colors[1] = 0.06
- colors[2] = 0.02
- } else if .green == textStampColorStyle {
- colors[0] = 0.25
- colors[1] = 0.42
- colors[2] = 0.13
- } else if .blue == textStampColorStyle {
- colors[0] = 0.09
- colors[1] = 0.15
- colors[2] = 0.39
- } else if .black == textStampColorStyle {
- colors[0] = 0
- colors[1] = 0
- colors[2] = 0
- }
- }
- }
- var textStampHaveDate: Bool = false
- var textStampHaveTime: Bool = false
- var textStampText: String?
- var dateTime: String?
- var stampBounds: CGRect = .zero
- var scale: Float = 0.0
- var leftMargin: CGFloat = 0.0
- var color: UIColor?
-
- let kStampPreview_OnlyText_Size: CGFloat = 48.0
- let kStampPreview_Text_Size: CGFloat = 30.0
- let kStampPreview_Date_Size: CGFloat = 20.0
-
- override init(frame: CGRect) {
- super.init(frame: frame)
- scale = (UIScreen.main.scale == 2.0) ? 2.0 : 1.0
- }
-
- required init?(coder: NSCoder) {
- fatalError("init(coder:) has not been implemented")
- }
-
- func getDateTime() -> String {
- let timename = TimeZone.current
- let outputFormatter = DateFormatter()
- outputFormatter.timeZone = timename
- var tDate: String? = nil
-
- if textStampHaveDate && !textStampHaveTime {
- outputFormatter.dateFormat = "yyyy/MM/dd"
- tDate = outputFormatter.string(from: Date())
- } else if textStampHaveTime && !textStampHaveDate {
- outputFormatter.dateFormat = "HH:mm:ss"
- tDate = outputFormatter.string(from: Date())
- } else if textStampHaveDate && textStampHaveTime {
- outputFormatter.dateFormat = "yyyy/MM/dd HH:mm"
- tDate = outputFormatter.string(from: Date())
- }
-
- return tDate ?? ""
-
- }
-
- // Calculate Rect based on text
-
- func fitStampRect() {
- var tTextFont: UIFont?
- var tTimeFont: UIFont?
- var drawText: String?
- var dateText: String?
- if (textStampText?.count ?? 0 < 1) && (dateTime?.count ?? 0 < 1) {
- drawText = "StampText"
- tTextFont = UIFont(name: "Helvetica", size: kStampPreview_OnlyText_Size)
- } else if (textStampText?.count ?? 0 > 0) && (dateTime?.count ?? 0 > 0) {
- tTextFont = UIFont(name: "Helvetica", size: kStampPreview_Text_Size)
- tTimeFont = UIFont(name: "Helvetica", size: kStampPreview_Date_Size)
- drawText = textStampText
- dateText = dateTime
- } else {
- if ((dateTime?.count ?? 0 > 0)) {
- drawText = dateTime
- } else {
- drawText = textStampText
- }
- tTextFont = UIFont(name: "Helvetica", size: kStampPreview_OnlyText_Size)
- }
-
- let tTextSize = drawText?.size(withAttributes: [.font: tTextFont as Any]) ?? .zero
- var tTimeSize = CGSize.zero
- if let tTimeFont = tTimeFont {
- tTimeSize = dateText?.size(withAttributes: [.font: tTimeFont]) ?? .zero
- }
-
- var w = max(tTextSize.width, tTimeSize.width)
- var count:CGFloat = 0
- if let drawText = drawText {
- for i in 0..<drawText.count {
- let aStr = String(drawText[drawText.index(drawText.startIndex, offsetBy: i)])
- if aStr == " " {
- count += 1
- }
- }
- }
- if tTextSize.width < tTimeSize.width {
- w += 15
- } else {
- w += 13.0 + 5 * count
- }
-
- var h = tTextSize.height + 5
- if let _ = dateText {
- h = tTextSize.height + tTimeSize.height + 8.011
- }
-
- if textStampStyle == .left {
- w = CGFloat(Int(Double(w) + Double(h) * 0.618033))
- } else if textStampStyle == .right {
- w = CGFloat(Int(Double(w) + Double(h) * 0.618033))
- }
-
- var x: CGFloat = 0.0
- var y: CGFloat = 0.0
-
- scale = 1.0
- let maxW: CGFloat = 300 - leftMargin
- if CGFloat(w) > maxW {
- scale = Float(maxW / CGFloat(w))
- h = CGFloat(Int(Double(h) * Double(scale)))
- x = frame.size.width / 2.0 - maxW / 2.0
- y = frame.size.height / 2.0 - CGFloat(h) / 2.0
- stampBounds = CGRect(x: x + leftMargin, y: y, width: maxW, height: h)
- } else {
- x = frame.size.width / 2.0 - CGFloat(w) / 2.0
- y = frame.size.height / 2.0 - CGFloat(h) / 2.0
- stampBounds = CGRect(x: x + leftMargin, y: y, width: CGFloat(w), height: h)
- }
-
- }
-
- // Only override drawRect: if you perform custom drawing.
- // An empty implementation adversely affects performance during animation.
-
- override func draw(_ rect: CGRect) {
- dateTime = getDateTime()
- fitStampRect()
- guard let context = UIGraphicsGetCurrentContext() else {
- return
- }
-
- context.setFillColor(CPDFColorUtils.CAnnotationSampleDrawBackgoundColor().cgColor)
- context.fill(bounds)
-
- if textStampStyle != .none {
- drawBounder(context: context)
- }
-
- drawText(context)
- }
-
- func drawBounder(context: CGContext?) {
- guard let context = context else {
- return
- }
- context.saveGState()
- var c01 = 1.0, c02 = 1.0, c03 = 1.0, c11 = 1.0, c12 = 1.0, c13 = 1.0
- if colors[0] > colors[1] && colors[0] > colors[2] {
- c01 = 1.0
- c02 = 0.78
- c03 = 0.78
-
- c11 = 0.98
- c12 = 0.92
- c13 = 0.91
- } else if colors[1] > colors[0] && colors[1] > colors[2] {
- c01 = 0.81
- c02 = 0.88
- c03 = 0.78
-
- c11 = 0.95
- c12 = 0.95
- c13 = 0.95
- } else if colors[2] > colors[0] && colors[2] > colors[1] {
- c01 = 0.79
- c02 = 0.81
- c03 = 0.89
-
- c11 = 0.90
- c12 = 0.95
- c13 = 1.0
- }
- let colorSpace = CGColorSpaceCreateDeviceRGB()
- let colors: [CGFloat] = [
- c01, c02, c03, 0.9,
- c11, c12, c13, 0.9
- ]
- guard let gradient = CGGradient(colorSpace: colorSpace, colorComponents: colors, locations: nil, count: colors.count/4) else {
- return
- }
- let startPoint = CGPoint(x: stampBounds.origin.x + stampBounds.size.width * 0.75, y: stampBounds.origin.y + stampBounds.size.width * 0.25)
- let endPoint = CGPoint(x: stampBounds.origin.x + stampBounds.size.width * 0.25, y: stampBounds.origin.y + stampBounds.size.width * 0.75)
-
- if textStampStyle == TextStampType.center {
- drawNormalRect(context: context)
- } else if textStampStyle == TextStampType.left {
- drawLeftBounder(context)
- } else if textStampStyle == TextStampType.right {
- drawRightBounder(context)
- }
- context.clip()
-
- context.saveGState()
- if let context = UIGraphicsGetCurrentContext() {
- context.saveGState()
- context.addRect(stampBounds)
- context.clip()
- context.drawLinearGradient(gradient, start: startPoint, end: endPoint, options: [.drawsBeforeStartLocation, .drawsAfterEndLocation])
- context.restoreGState()
- }
-
- if textStampStyle == TextStampType.center {
- drawNormalRect(context: context)
- } else if textStampStyle == TextStampType.left {
- drawLeftBounder(context)
- } else if textStampStyle == TextStampType.right {
- drawRightBounder(context)
- }
- context.strokePath()
-
- }
-
- func drawNormalRect(context: CGContext) {
- let tmpHeight = 11.0 * stampBounds.size.height/50
- let tmpWidth = 3.0 * stampBounds.size.height/50
- let hw1 = 5.54492 * stampBounds.size.height/50
- let hw2 = 4.40039 * stampBounds.size.height/50
- context.beginPath()
-
- context.move(to: CGPoint(x: stampBounds.origin.x+tmpWidth, y: stampBounds.origin.y+stampBounds.size.height-tmpHeight))
-
- context.addCurve(to: CGPoint(x: stampBounds.origin.x+tmpHeight, y: stampBounds.origin.y+stampBounds.size.height-tmpWidth),
- control1: CGPoint(x: stampBounds.origin.x+tmpWidth, y: stampBounds.origin.y+stampBounds.size.height-tmpHeight+hw2),
- control2: CGPoint(x: stampBounds.origin.x+tmpHeight-hw1, y: stampBounds.origin.y+stampBounds.size.height-tmpWidth))
-
- context.addLine(to: CGPoint(x: stampBounds.origin.x+stampBounds.size.width-tmpHeight, y: stampBounds.origin.y+stampBounds.size.height-tmpWidth))
-
- context.addCurve(to: CGPoint(x: stampBounds.origin.x+stampBounds.size.width-tmpWidth, y: stampBounds.origin.y+stampBounds.size.height-tmpHeight),
- control1: CGPoint(x: stampBounds.origin.x+stampBounds.size.width-tmpHeight+hw1, y: stampBounds.origin.y+stampBounds.size.height-tmpWidth),
- control2: CGPoint(x: stampBounds.origin.x+stampBounds.size.width-tmpWidth, y: stampBounds.origin.y+stampBounds.size.height-tmpHeight+hw2))
-
- context.addLine(to: CGPoint(x: stampBounds.origin.x+stampBounds.size.width-tmpWidth, y: stampBounds.origin.y+tmpHeight))
-
- context.addCurve(to: CGPoint(x: stampBounds.origin.x+stampBounds.size.width-tmpHeight, y: stampBounds.origin.y+tmpWidth),
- control1: CGPoint(x: stampBounds.origin.x+stampBounds.size.width-tmpWidth, y: stampBounds.origin.y+tmpHeight-hw2),
- control2: CGPoint(x: stampBounds.origin.x+stampBounds.size.width-tmpHeight+hw1, y: stampBounds.origin.y+tmpWidth))
-
- context.addLine(to: CGPoint(x: stampBounds.origin.x+tmpHeight, y: stampBounds.origin.y+tmpWidth))
-
- context.addCurve(to: CGPoint(x: stampBounds.origin.x+tmpWidth, y: stampBounds.origin.y+tmpHeight),
- control1: CGPoint(x: stampBounds.origin.x+tmpHeight-hw1, y: stampBounds.origin.y+tmpWidth),
- control2: CGPoint(x: stampBounds.origin.x+tmpWidth, y: stampBounds.origin.y+tmpHeight-hw2))
-
- context.addLine(to: CGPoint(x: stampBounds.origin.x+tmpWidth, y: stampBounds.origin.y+stampBounds.size.height-tmpHeight))
-
- context.closePath()
-
- }
-
- func drawLeftBounder(_ context: CGContext) {
- let tmpHeight = 11.0 * stampBounds.size.height/50
- let tmpWidth = 3.0 * stampBounds.size.height/50
- let hw1 = 5.54492 * stampBounds.size.height/50
- let hw2 = 4.40039 * stampBounds.size.height/50
- let x0 = stampBounds.origin.x + stampBounds.size.height * 0.618033
- let y0 = stampBounds.origin.y
-
- let x1 = stampBounds.origin.x + stampBounds.size.width
- let y1 = stampBounds.origin.y + stampBounds.size.height
-
- let xp = stampBounds.origin.x
- let yp = stampBounds.origin.y + stampBounds.size.height / 2.0
-
- context.beginPath()
-
- context.move(to: CGPoint(x: x0 + tmpHeight, y: y1 - tmpWidth))
- context.addLine(to: CGPoint(x: x1 - tmpHeight, y: y1 - tmpWidth))
- context.addCurve(to: CGPoint(x: x1 - tmpWidth, y: y1 - tmpHeight),
- control1: CGPoint(x: x1 - tmpHeight + hw1, y: y1 - tmpWidth),
- control2: CGPoint(x: x1 - tmpWidth, y: y1 - tmpHeight + hw2))
- context.addLine(to: CGPoint(x: x1 - tmpWidth, y: y0 + tmpHeight))
- context.addCurve(to: CGPoint(x: x1 - tmpHeight, y: y0 + tmpWidth),
- control1: CGPoint(x: x1 - tmpWidth, y: y0 + tmpHeight - hw2),
- control2: CGPoint(x: x1 - tmpHeight + hw1, y: y0 + tmpWidth))
- context.addLine(to: CGPoint(x: x0 + tmpHeight, y: y0 + tmpWidth))
- context.addLine(to: CGPoint(x: xp + tmpHeight, y: yp))
- context.addLine(to: CGPoint(x: x0 + tmpHeight, y: y1 - tmpWidth))
-
- context.closePath()
-
- }
-
- func drawRightBounder(_ context: CGContext) {
- let tmpHeight = 11.0 * stampBounds.size.height/50
- let tmpWidth = 3.0 * stampBounds.size.height/50
- let hw1 = 5.54492 * stampBounds.size.height/50
- let hw2 = 4.40039 * stampBounds.size.height/50
- let x0 = stampBounds.origin.x
- let y0 = stampBounds.origin.y
-
- let x1 = stampBounds.origin.x + stampBounds.size.width - stampBounds.size.height * 0.618033
- let y1 = stampBounds.origin.y + stampBounds.size.height
-
- let xp = stampBounds.origin.x + stampBounds.size.width
- let yp = stampBounds.origin.y + stampBounds.size.height / 2.0
-
- context.beginPath()
-
- context.move(to: CGPoint(x: x0 + tmpWidth, y: y1 - tmpHeight))
- context.addCurve(to: CGPoint(x: x0 + tmpHeight, y: y1 - tmpWidth),
- control1: CGPoint(x: x0 + tmpWidth, y: y1 - tmpHeight + hw2),
- control2: CGPoint(x: x0 + tmpHeight - hw1, y: y1 - tmpWidth))
- context.addLine(to: CGPoint(x: x1 - tmpHeight, y: y1 - tmpWidth))
- context.addLine(to: CGPoint(x: xp - tmpHeight, y: yp))
- context.addLine(to: CGPoint(x: x1 - tmpHeight, y: y0 + tmpWidth))
- context.addLine(to: CGPoint(x: x0 + tmpHeight, y: y0 + tmpWidth))
- context.addCurve(to: CGPoint(x: x0 + tmpWidth, y: y0 + tmpHeight),
- control1: CGPoint(x: x0 + tmpHeight - hw1, y: y0 + tmpWidth),
- control2: CGPoint(x: x0 + tmpWidth, y: y0 + tmpHeight - hw2))
- context.addLine(to: CGPoint(x: x0 + tmpWidth, y: y1 - tmpHeight))
-
- context.closePath()
-
- }
-
- func drawText(_ context: CGContext?) {
- guard let context = context else {
- return
- }
-
- context.textMatrix = CGAffineTransform(scaleX: 1.0, y: -1.0)
- var drawText: String?
- var dateText: String?
- if (textStampText?.count ?? 0 < 1) && (dateTime?.count ?? 0 < 1) {
- drawText = "StampText"
- } else if (textStampText?.count ?? 0 > 0) && (dateTime?.count ?? 0 > 0) {
- drawText = textStampText
- dateText = dateTime
- }else {
- if((dateTime?.count ?? 0 > 0)) {
- drawText = dateTime
- } else {
- drawText = textStampText
- }
- }
-
- if (dateText?.count ?? 0 < 1) {
- let fontsize = Float(kStampPreview_OnlyText_Size) * scale
- let font = UIFont(name: "Helvetica", size: CGFloat(fontsize))
- var rt = stampBounds.insetBy(dx: 0, dy: 0)
- rt.origin.x += CGFloat(8.093 * scale)
-
- if textStampStyle == .left {
- rt.origin.x += rt.size.height * 0.618033
- }
-
- UIGraphicsPushContext(context)
-
- let attributes: [NSAttributedString.Key: Any] = [
- .font: font as Any,
- .paragraphStyle: NSParagraphStyle.default,
- .foregroundColor: UIColor(red: colors[0], green: colors[1], blue: colors[2], alpha: 1)
- ]
- drawText?.draw(in: rt, withAttributes: attributes)
- UIGraphicsPopContext()
-
- } else {
- var tFontSize = Float(kStampPreview_Text_Size) * Float(scale)
- var tFont = UIFont(name: "Helvetica", size: CGFloat(tFontSize))
-
- var tTextRT = stampBounds.insetBy(dx: 0, dy: 0)
- tTextRT.origin.x += CGFloat(8.093 * scale)
-
- if textStampStyle == .left {
- tTextRT.origin.x += tTextRT.size.height * 0.618033
- }
-
- UIGraphicsPushContext(context)
- UIColor(red: colors[0], green: colors[1], blue: colors[2], alpha: 1).set()
-
- if !(drawText?.isEmpty == true) {
- let attributes: [NSAttributedString.Key: Any] = [
- .font: tFont as Any,
- .paragraphStyle: NSParagraphStyle.default,
- .foregroundColor: UIColor(red: colors[0], green: colors[1], blue: colors[2], alpha: 1)
- ]
- drawText?.draw(in: tTextRT, withAttributes: attributes)
-
- var tDateRT = stampBounds.insetBy(dx: 0, dy: 0)
- tDateRT.origin.x += CGFloat(8.093 * Float(scale))
-
- if textStampStyle == .left {
- tDateRT.origin.x += tDateRT.size.height * 0.618033
- }
-
- tDateRT.origin.y = tDateRT.origin.y + CGFloat(tFontSize) + CGFloat(6.103 * scale)
-
- tFontSize = Float(kStampPreview_Date_Size) * Float(scale)
- tFont = UIFont(name: "Helvetica", size: CGFloat(tFontSize))
-
- let attributess: [NSAttributedString.Key: Any] = [
- .font: tFont as Any,
- .paragraphStyle: NSParagraphStyle.default,
- .foregroundColor: UIColor(red: colors[0], green: colors[1], blue: colors[2], alpha: 1)
- ]
- dateText?.draw(in: tDateRT, withAttributes: attributess)
- } else {
- let fontsize = Float(kStampPreview_Date_Size) * Float(scale)
- let font = UIFont(name: "Helvetica", size: CGFloat(tFontSize))
-
- var rt = stampBounds.insetBy(dx: 0, dy: 0)
- rt.origin.x += CGFloat(8.093 * scale)
-
- if textStampStyle == .left {
- rt.origin.x += rt.size.height * 0.618033
- }
-
- let attributes: [NSAttributedString.Key: Any] = [
- .font: font as Any,
- .paragraphStyle: NSParagraphStyle.default,
- .foregroundColor: UIColor(red: colors[0], green: colors[1], blue: colors[2], alpha: 1)
- ]
- dateText?.draw(in: rt, withAttributes: attributes)
- }
-
- UIGraphicsPopContext()
- }
-
- }
-
-
- func renderImage() -> UIImage? {
- // Implementation for rendering an image
- let image = renderImageFromView(self)
- return image
- }
-
- /* Convert UIView to UIImage */
- func renderImageFromView(_ view: UIView) -> UIImage? {
- UIGraphicsBeginImageContextWithOptions(view.bounds.size, false, 1.0)
- guard let context = UIGraphicsGetCurrentContext() else { return nil }
- context.translateBy(x: 1.0, y: 1.0)
-
- view.layer.render(in: context)
-
- let image = UIGraphicsGetImageFromCurrentImageContext()
- UIGraphicsEndImageContext()
-
- return image
-
- }
-
-
- }
|