// // Copyright (c) 2019 Open Whisper Systems. All rights reserved. // import UIKit @objc public class ImageEditorTextItem: ImageEditorItem { @objc public let text: String @objc public let color: ImageEditorColor @objc public let font: UIFont // In order to render the text at a consistent size // in very differently sized contexts (canvas in // portrait, landscape, in the crop tool, before and // after cropping, while rendering output), // we need to scale the font size to reflect the // view width. // // We use the image's rendering width as the reference value, // since we want to be consistent with regard to the image's // content. @objc public let fontReferenceImageWidth: CGFloat @objc public let unitCenter: ImageEditorSample // Leave some margins against the edge of the image. @objc public static let kDefaultUnitWidth: CGFloat = 0.9 // The max width of the text as a fraction of the image width. // // This provides continuity of text layout before/after cropping. // // NOTE: When you scale the text with with a pinch gesture, that // affects _scaling_, not the _unit width_, since we don't want // to change how the text wraps when scaling. @objc public let unitWidth: CGFloat // 0 = no rotation. // CGFloat.pi * 0.5 = rotation 90 degrees clockwise. @objc public let rotationRadians: CGFloat @objc public static let kMaxScaling: CGFloat = 4.0 @objc public static let kMinScaling: CGFloat = 0.5 @objc public let scaling: CGFloat @objc public init(text: String, color: ImageEditorColor, font: UIFont, fontReferenceImageWidth: CGFloat, unitCenter: ImageEditorSample = ImageEditorSample(x: 0.5, y: 0.5), unitWidth: CGFloat = ImageEditorTextItem.kDefaultUnitWidth, rotationRadians: CGFloat = 0.0, scaling: CGFloat = 1.0) { self.text = text self.color = color self.font = font self.fontReferenceImageWidth = fontReferenceImageWidth self.unitCenter = unitCenter self.unitWidth = unitWidth self.rotationRadians = rotationRadians self.scaling = scaling super.init(itemType: .text) } private init(itemId: String, text: String, color: ImageEditorColor, font: UIFont, fontReferenceImageWidth: CGFloat, unitCenter: ImageEditorSample, unitWidth: CGFloat, rotationRadians: CGFloat, scaling: CGFloat) { self.text = text self.color = color self.font = font self.fontReferenceImageWidth = fontReferenceImageWidth self.unitCenter = unitCenter self.unitWidth = unitWidth self.rotationRadians = rotationRadians self.scaling = scaling super.init(itemId: itemId, itemType: .text) } @objc public class func empty(withColor color: ImageEditorColor, unitWidth: CGFloat, fontReferenceImageWidth: CGFloat, scaling: CGFloat, rotationRadians: CGFloat) -> ImageEditorTextItem { // TODO: Tune the default font size. let font = UIFont.boldSystemFont(ofSize: 30.0) return ImageEditorTextItem(text: "", color: color, font: font, fontReferenceImageWidth: fontReferenceImageWidth, unitWidth: unitWidth, rotationRadians: rotationRadians, scaling: scaling) } @objc public func copy(withText newText: String, color newColor: ImageEditorColor) -> ImageEditorTextItem { return ImageEditorTextItem(itemId: itemId, text: newText, color: newColor, font: font, fontReferenceImageWidth: fontReferenceImageWidth, unitCenter: unitCenter, unitWidth: unitWidth, rotationRadians: rotationRadians, scaling: scaling) } @objc public func copy(unitCenter: CGPoint) -> ImageEditorTextItem { return ImageEditorTextItem(itemId: itemId, text: text, color: color, font: font, fontReferenceImageWidth: fontReferenceImageWidth, unitCenter: unitCenter, unitWidth: unitWidth, rotationRadians: rotationRadians, scaling: scaling) } @objc public func copy(scaling: CGFloat, rotationRadians: CGFloat) -> ImageEditorTextItem { return ImageEditorTextItem(itemId: itemId, text: text, color: color, font: font, fontReferenceImageWidth: fontReferenceImageWidth, unitCenter: unitCenter, unitWidth: unitWidth, rotationRadians: rotationRadians, scaling: scaling) } @objc public func copy(unitWidth: CGFloat) -> ImageEditorTextItem { return ImageEditorTextItem(itemId: itemId, text: text, color: color, font: font, fontReferenceImageWidth: fontReferenceImageWidth, unitCenter: unitCenter, unitWidth: unitWidth, rotationRadians: rotationRadians, scaling: scaling) } @objc public func copy(font: UIFont) -> ImageEditorTextItem { return ImageEditorTextItem(itemId: itemId, text: text, color: color, font: font, fontReferenceImageWidth: fontReferenceImageWidth, unitCenter: unitCenter, unitWidth: unitWidth, rotationRadians: rotationRadians, scaling: scaling) } public override func outputScale() -> CGFloat { return scaling } static func ==(left: ImageEditorTextItem, right: ImageEditorTextItem) -> Bool { return (left.text == right.text && left.color == right.color && left.font.fontName == right.font.fontName && left.font.pointSize.fuzzyEquals(right.font.pointSize) && left.fontReferenceImageWidth.fuzzyEquals(right.fontReferenceImageWidth) && left.unitCenter.fuzzyEquals(right.unitCenter) && left.unitWidth.fuzzyEquals(right.unitWidth) && left.rotationRadians.fuzzyEquals(right.rotationRadians) && left.scaling.fuzzyEquals(right.scaling)) } }