From 2b5f671d60abb8eea83eaa415d5bf2dd7517a35a Mon Sep 17 00:00:00 2001 From: Andrew Romanov Date: Thu, 28 Feb 2019 13:53:40 +0700 Subject: [PATCH 1/3] added support of kerning to Text. Added example for text rendering. --- .../Example-macOS.xcodeproj/project.pbxproj | 17 ++++++- .../Example-macOS/Base.lproj/Main.storyboard | 32 +++++++++++-- Example/Example.xcodeproj/project.pbxproj | 12 +++++ Example/Example/Base.lproj/Main.storyboard | 34 +++++++++++++- .../Examples/Text/TextsExampleView.swift | 46 +++++++++++++++++++ Example/Example/MenuViewController.swift | 3 +- Source/model/scene/Text.swift | 10 +++- Source/render/TextRenderer.swift | 13 +++++- 8 files changed, 157 insertions(+), 10 deletions(-) create mode 100644 Example/Example/Examples/Text/TextsExampleView.swift diff --git a/Example-macOS/Example-macOS.xcodeproj/project.pbxproj b/Example-macOS/Example-macOS.xcodeproj/project.pbxproj index 2de1a47a..fa69904f 100644 --- a/Example-macOS/Example-macOS.xcodeproj/project.pbxproj +++ b/Example-macOS/Example-macOS.xcodeproj/project.pbxproj @@ -7,6 +7,7 @@ objects = { /* Begin PBXBuildFile section */ + 49265C832227BB7A00923A66 /* TextsExampleView.swift in Sources */ = {isa = PBXBuildFile; fileRef = 49265C822227BB7A00923A66 /* TextsExampleView.swift */; }; 970AB811D179560D74930D39 /* Pods_Example_macOS.framework in Frameworks */ = {isa = PBXBuildFile; fileRef = 5184A00051CAC5E360198B48 /* Pods_Example_macOS.framework */; }; A715CA7D215E472800EE7651 /* ExampleViewController.swift in Sources */ = {isa = PBXBuildFile; fileRef = A715CA7C215E472800EE7651 /* ExampleViewController.swift */; }; A72862CB1F4308A50033893D /* AnimationsViewController.swift in Sources */ = {isa = PBXBuildFile; fileRef = A72862CA1F4308A50033893D /* AnimationsViewController.swift */; }; @@ -25,6 +26,7 @@ /* End PBXBuildFile section */ /* Begin PBXFileReference section */ + 49265C822227BB7A00923A66 /* TextsExampleView.swift */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.swift; path = TextsExampleView.swift; sourceTree = ""; }; 5184A00051CAC5E360198B48 /* Pods_Example_macOS.framework */ = {isa = PBXFileReference; explicitFileType = wrapper.framework; includeInIndex = 0; path = Pods_Example_macOS.framework; sourceTree = BUILT_PRODUCTS_DIR; }; A715CA7C215E472800EE7651 /* ExampleViewController.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = ExampleViewController.swift; sourceTree = ""; }; A72862CA1F4308A50033893D /* AnimationsViewController.swift */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.swift; name = AnimationsViewController.swift; path = Examples/Animations/AnimationsViewController.swift; sourceTree = ""; }; @@ -66,6 +68,15 @@ name = Frameworks; sourceTree = ""; }; + 49265C812227BB7A00923A66 /* Text */ = { + isa = PBXGroup; + children = ( + 49265C822227BB7A00923A66 /* TextsExampleView.swift */, + ); + name = Text; + path = ../../Example/Example/Examples/Text; + sourceTree = ""; + }; 4F8946156C3F28DC7B262776 /* Pods */ = { isa = PBXGroup; children = ( @@ -110,6 +121,7 @@ A759399F1F41C51A000CE329 /* Examples */ = { isa = PBXGroup; children = ( + 49265C812227BB7A00923A66 /* Text */, A715CA7C215E472800EE7651 /* ExampleViewController.swift */, A75939A01F41C544000CE329 /* Shapes */, A75939A61F41C58D000CE329 /* Transform */, @@ -281,7 +293,7 @@ files = ( ); inputPaths = ( - "${PODS_ROOT}/Target Support Files/Pods-Example-macOS/Pods-Example-macOS-frameworks.sh", + "${SRCROOT}/Pods/Target Support Files/Pods-Example-macOS/Pods-Example-macOS-frameworks.sh", "${BUILT_PRODUCTS_DIR}/Macaw/Macaw.framework", "${BUILT_PRODUCTS_DIR}/SWXMLHash/SWXMLHash.framework", ); @@ -292,7 +304,7 @@ ); runOnlyForDeploymentPostprocessing = 0; shellPath = /bin/sh; - shellScript = "\"${PODS_ROOT}/Target Support Files/Pods-Example-macOS/Pods-Example-macOS-frameworks.sh\"\n"; + shellScript = "\"${SRCROOT}/Pods/Target Support Files/Pods-Example-macOS/Pods-Example-macOS-frameworks.sh\"\n"; showEnvVarsInLog = 0; }; /* End PBXShellScriptBuildPhase section */ @@ -310,6 +322,7 @@ A768EAD81F42C98E00F22A17 /* EventsExampleController.swift in Sources */, A72862CE1F430DF00033893D /* EasingViewController.swift in Sources */, A72862CB1F4308A50033893D /* AnimationsViewController.swift in Sources */, + 49265C832227BB7A00923A66 /* TextsExampleView.swift in Sources */, A768EADE1F42CCBC00F22A17 /* AnimationsView.swift in Sources */, A75939A81F41C5A8000CE329 /* TransformExampleView.swift in Sources */, A768EADC1F42CC7C00F22A17 /* EasingView.swift in Sources */, diff --git a/Example-macOS/Example-macOS/Base.lproj/Main.storyboard b/Example-macOS/Example-macOS/Base.lproj/Main.storyboard index 3809006d..07ae1950 100644 --- a/Example-macOS/Example-macOS/Base.lproj/Main.storyboard +++ b/Example-macOS/Example-macOS/Base.lproj/Main.storyboard @@ -1,8 +1,8 @@ - + - + @@ -111,7 +111,7 @@ - + @@ -120,6 +120,7 @@ + @@ -138,6 +139,7 @@ + @@ -345,5 +347,29 @@ + + + + + + + + + + + + + + + + + + + + + + + + diff --git a/Example/Example.xcodeproj/project.pbxproj b/Example/Example.xcodeproj/project.pbxproj index 04fc2ac4..dcb8c18f 100644 --- a/Example/Example.xcodeproj/project.pbxproj +++ b/Example/Example.xcodeproj/project.pbxproj @@ -8,6 +8,7 @@ /* Begin PBXBuildFile section */ 48BC2FE8BD3BF26100D04E07 /* Pods_Example.framework in Frameworks */ = {isa = PBXBuildFile; fileRef = 0A92F90D3D20D2A289BED45F /* Pods_Example.framework */; }; + 49265C802227B1EB00923A66 /* TextsExampleView.swift in Sources */ = {isa = PBXBuildFile; fileRef = 49265C7F2227B1EB00923A66 /* TextsExampleView.swift */; }; 5747F9BD1E38B683004E338F /* MorphingView.swift in Sources */ = {isa = PBXBuildFile; fileRef = 5747F9BC1E38B683004E338F /* MorphingView.swift */; }; 574EC43E1CB7DE7F0063F317 /* ShapesExampleView.swift in Sources */ = {isa = PBXBuildFile; fileRef = 574EC4341CB7DE7F0063F317 /* ShapesExampleView.swift */; }; 574EC4411CB7E2440063F317 /* MenuViewController.swift in Sources */ = {isa = PBXBuildFile; fileRef = 574EC4401CB7E2440063F317 /* MenuViewController.swift */; }; @@ -41,6 +42,7 @@ /* Begin PBXFileReference section */ 0A92F90D3D20D2A289BED45F /* Pods_Example.framework */ = {isa = PBXFileReference; explicitFileType = wrapper.framework; includeInIndex = 0; path = Pods_Example.framework; sourceTree = BUILT_PRODUCTS_DIR; }; 131DDFA4A9D164CC4B64C3E8 /* Pods-Example.release.xcconfig */ = {isa = PBXFileReference; includeInIndex = 1; lastKnownFileType = text.xcconfig; name = "Pods-Example.release.xcconfig"; path = "Pods/Target Support Files/Pods-Example/Pods-Example.release.xcconfig"; sourceTree = ""; }; + 49265C7F2227B1EB00923A66 /* TextsExampleView.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = TextsExampleView.swift; sourceTree = ""; }; 5747F9BC1E38B683004E338F /* MorphingView.swift */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.swift; path = MorphingView.swift; sourceTree = ""; }; 574EC4341CB7DE7F0063F317 /* ShapesExampleView.swift */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.swift; path = ShapesExampleView.swift; sourceTree = ""; }; 574EC4401CB7E2440063F317 /* MenuViewController.swift */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.swift; name = MenuViewController.swift; path = Example/MenuViewController.swift; sourceTree = SOURCE_ROOT; }; @@ -82,6 +84,14 @@ name = Pods; sourceTree = ""; }; + 49265C7E2227B1B200923A66 /* Text */ = { + isa = PBXGroup; + children = ( + 49265C7F2227B1EB00923A66 /* TextsExampleView.swift */, + ); + path = Text; + sourceTree = ""; + }; 5747F9BB1E38B660004E338F /* Morphing */ = { isa = PBXGroup; children = ( @@ -93,6 +103,7 @@ 574EC4271CB7DE7F0063F317 /* Examples */ = { isa = PBXGroup; children = ( + 49265C7E2227B1B200923A66 /* Text */, 574EC4331CB7DE7F0063F317 /* Shapes */, 6699B7CE1DFFE8B90072585E /* Transform */, 574EC4421CBB607E0063F317 /* Animations */, @@ -353,6 +364,7 @@ 5BAE3CB120C54E3D006BEF51 /* FiltersViewController.swift in Sources */, 57AF398C1E67E9DB00F0BFE2 /* EventsExampleController.swift in Sources */, B04416FA1E041A420016BC50 /* EasingView.swift in Sources */, + 49265C802227B1EB00923A66 /* TextsExampleView.swift in Sources */, 574EC4411CB7E2440063F317 /* MenuViewController.swift in Sources */, 574EC43E1CB7DE7F0063F317 /* ShapesExampleView.swift in Sources */, B04416FC1E04282A0016BC50 /* EasingExampleController.swift in Sources */, diff --git a/Example/Example/Base.lproj/Main.storyboard b/Example/Example/Base.lproj/Main.storyboard index 8059167b..ee523c93 100644 --- a/Example/Example/Base.lproj/Main.storyboard +++ b/Example/Example/Base.lproj/Main.storyboard @@ -1,11 +1,11 @@ - + - + @@ -353,5 +353,35 @@ + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + diff --git a/Example/Example/Examples/Text/TextsExampleView.swift b/Example/Example/Examples/Text/TextsExampleView.swift new file mode 100644 index 00000000..bea97afc --- /dev/null +++ b/Example/Example/Examples/Text/TextsExampleView.swift @@ -0,0 +1,46 @@ +// +// TextsExampleView.swift +// Example +// +// Created by Andrew Romanov on 28/02/2019. +// Copyright © 2019 Exyte. All rights reserved. +// + +import Macaw + +class TextsExampleView: MacawView { + + required init?(coder aDecoder: NSCoder) { + let text1 = TextsExampleView.newText("Font", .move(dx: 100, dy: 40)) + text1.font = Font(name: "Helvetica", size: 20, weight: "normal") + + let text2 = TextsExampleView.newText("Stroke", .move(dx: 100, dy: 200)) + text2.font = Font(name: "Helvetica", size: 40, weight: "normal") + text2.fill = Color(val: 0xFF0000); + text2.stroke = Stroke(fill: Color(val: 0x00FF00), width: 20.0); + + let text4 = TextsExampleView.newText("Stroke", .move(dx: 100, dy: 200)) + text4.font = Font(name: "Helvetica", size: 40, weight: "normal") + text4.fill = Color(val: 0xFF0000); + + let text3 = TextsExampleView.newText("Kern inc", .move(dx: 100, dy: 250)) + text3.kern = 3.0 + + let text5 = TextsExampleView.newText("Kern dec", .move(dx: 100, dy: 300)) + text5.kern = -1.0 + + let group = Group( + contents: [ + text1, text2, text3, text4, text5 + ] + ) + + super.init(node: group, coder: aDecoder) + } + + fileprivate static func newText(_ text: String, _ place: Transform, baseline: Baseline = .bottom) -> Text { + return Text(text: text, fill: Color.black, align: .mid, baseline: baseline, place: place) + } + +} + diff --git a/Example/Example/MenuViewController.swift b/Example/Example/MenuViewController.swift index 26ec5f96..e0c55692 100644 --- a/Example/Example/MenuViewController.swift +++ b/Example/Example/MenuViewController.swift @@ -12,7 +12,8 @@ open class MenuViewController: UIViewController, UITableViewDataSource, UITableV "EasingExampleController", "MorphingExampleController", "EventsExampleController", - "FiltersViewController" + "FiltersViewController", + "TextsViewController" ].map { UIStoryboard(name: "Main", bundle: .none).instantiateViewController(withIdentifier: $0) } diff --git a/Source/model/scene/Text.swift b/Source/model/scene/Text.swift index d9899eb9..2d389217 100644 --- a/Source/model/scene/Text.swift +++ b/Source/model/scene/Text.swift @@ -41,14 +41,21 @@ open class Text: Node { get { return baselineVar.value } set(val) { baselineVar.value = val } } + + public let kernVar: Variable + open var kern: Float { + get { return kernVar.value } + set(val) { kernVar.value = val} + } - public init(text: String, font: Font? = nil, fill: Fill? = Color.black, stroke: Stroke? = nil, align: Align = .min, baseline: Baseline = .top, place: Transform = Transform.identity, opaque: Bool = true, opacity: Double = 1, clip: Locus? = nil, mask: Node? = nil, effect: Effect? = nil, visible: Bool = true, tag: [String] = []) { + public init(text: String, font: Font? = nil, fill: Fill? = Color.black, stroke: Stroke? = nil, align: Align = .min, baseline: Baseline = .top, kern: Float = 0.0, place: Transform = Transform.identity, opaque: Bool = true, opacity: Double = 1, clip: Locus? = nil, mask: Node? = nil, effect: Effect? = nil, visible: Bool = true, tag: [String] = []) { self.textVar = Variable(text) self.fontVar = Variable(font) self.fillVar = Variable(fill) self.strokeVar = Variable(stroke) self.alignVar = Variable(align) self.baselineVar = Variable(baseline) + self.kernVar = Variable(kern) super.init( place: place, opaque: opaque, @@ -75,6 +82,7 @@ open class Text: Node { } var stringAttributes: [NSAttributedString.Key: AnyObject] = [:] stringAttributes[NSAttributedString.Key.font] = font + stringAttributes[NSAttributedString.Key.kern] = NSNumber(value: self.kern) let size = (text as NSString).size(withAttributes: stringAttributes) return Rect( x: calculateAlignmentOffset(font: font), diff --git a/Source/render/TextRenderer.swift b/Source/render/TextRenderer.swift index 6f19a29f..9a79ba77 100644 --- a/Source/render/TextRenderer.swift +++ b/Source/render/TextRenderer.swift @@ -35,6 +35,7 @@ class TextRenderer: NodeRenderer { observe(text.strokeVar) observe(text.alignVar) observe(text.baselineVar) + observe(text.kernVar) } override func doRender(in context: CGContext, force: Bool, opacity: Double, coloringMode: ColoringMode = .rgb) { @@ -65,6 +66,10 @@ class TextRenderer: NodeRenderer { } attributes[NSAttributedString.Key.strokeWidth] = width as NSObject? } + if text.kern != 0.0 { + attributes[NSAttributedString.Key.kern] = NSNumber(value: text.kern) + } + if attributes.count > 1 { MGraphicsPushContext(context) message.draw(in: getBounds(font), withAttributes: attributes) @@ -129,7 +134,13 @@ class TextRenderer: NodeRenderer { return .zero } - let textAttributes = [NSAttributedString.Key.font: font] + var textAttributes : [NSAttributedString.Key: Any] = [NSAttributedString.Key.font: font] + if (text.kern != 0.0){ + textAttributes[NSAttributedString.Key.kern] = NSNumber(value: text.kern) + } + if let stroke = text.stroke { + textAttributes[NSAttributedString.Key.strokeWidth] = NSNumber(value: stroke.width) + } let textSize = NSString(string: text.text).size(withAttributes: textAttributes) return CGRect(x: calculateAlignmentOffset(text, font: font), y: calculateBaselineOffset(text, font: font), From ca6588062181026d76e8b37f26f6a34589fce494 Mon Sep 17 00:00:00 2001 From: Andrew Romanov Date: Fri, 1 Mar 2019 21:31:59 +0700 Subject: [PATCH 2/3] property kern renamed to kerning --- Example/Example/Examples/Text/TextsExampleView.swift | 4 ++-- Source/model/scene/Text.swift | 12 ++++++------ Source/render/TextRenderer.swift | 10 +++++----- 3 files changed, 13 insertions(+), 13 deletions(-) diff --git a/Example/Example/Examples/Text/TextsExampleView.swift b/Example/Example/Examples/Text/TextsExampleView.swift index bea97afc..cf61d46c 100644 --- a/Example/Example/Examples/Text/TextsExampleView.swift +++ b/Example/Example/Examples/Text/TextsExampleView.swift @@ -24,10 +24,10 @@ class TextsExampleView: MacawView { text4.fill = Color(val: 0xFF0000); let text3 = TextsExampleView.newText("Kern inc", .move(dx: 100, dy: 250)) - text3.kern = 3.0 + text3.kerning = 3.0 let text5 = TextsExampleView.newText("Kern dec", .move(dx: 100, dy: 300)) - text5.kern = -1.0 + text5.kerning = -1.0 let group = Group( contents: [ diff --git a/Source/model/scene/Text.swift b/Source/model/scene/Text.swift index 2d389217..c9fce75e 100644 --- a/Source/model/scene/Text.swift +++ b/Source/model/scene/Text.swift @@ -42,10 +42,10 @@ open class Text: Node { set(val) { baselineVar.value = val } } - public let kernVar: Variable - open var kern: Float { - get { return kernVar.value } - set(val) { kernVar.value = val} + public let kerningVar: Variable + open var kerning: Float { + get { return kerningVar.value } + set(val) { kerningVar.value = val} } public init(text: String, font: Font? = nil, fill: Fill? = Color.black, stroke: Stroke? = nil, align: Align = .min, baseline: Baseline = .top, kern: Float = 0.0, place: Transform = Transform.identity, opaque: Bool = true, opacity: Double = 1, clip: Locus? = nil, mask: Node? = nil, effect: Effect? = nil, visible: Bool = true, tag: [String] = []) { @@ -55,7 +55,7 @@ open class Text: Node { self.strokeVar = Variable(stroke) self.alignVar = Variable(align) self.baselineVar = Variable(baseline) - self.kernVar = Variable(kern) + self.kerningVar = Variable(kern) super.init( place: place, opaque: opaque, @@ -82,7 +82,7 @@ open class Text: Node { } var stringAttributes: [NSAttributedString.Key: AnyObject] = [:] stringAttributes[NSAttributedString.Key.font] = font - stringAttributes[NSAttributedString.Key.kern] = NSNumber(value: self.kern) + stringAttributes[NSAttributedString.Key.kern] = NSNumber(value: self.kerning) let size = (text as NSString).size(withAttributes: stringAttributes) return Rect( x: calculateAlignmentOffset(font: font), diff --git a/Source/render/TextRenderer.swift b/Source/render/TextRenderer.swift index 9a79ba77..f9876f10 100644 --- a/Source/render/TextRenderer.swift +++ b/Source/render/TextRenderer.swift @@ -35,7 +35,7 @@ class TextRenderer: NodeRenderer { observe(text.strokeVar) observe(text.alignVar) observe(text.baselineVar) - observe(text.kernVar) + observe(text.kerningVar) } override func doRender(in context: CGContext, force: Bool, opacity: Double, coloringMode: ColoringMode = .rgb) { @@ -66,8 +66,8 @@ class TextRenderer: NodeRenderer { } attributes[NSAttributedString.Key.strokeWidth] = width as NSObject? } - if text.kern != 0.0 { - attributes[NSAttributedString.Key.kern] = NSNumber(value: text.kern) + if text.kerning != 0.0 { + attributes[NSAttributedString.Key.kern] = NSNumber(value: text.kerning) } if attributes.count > 1 { @@ -135,8 +135,8 @@ class TextRenderer: NodeRenderer { } var textAttributes : [NSAttributedString.Key: Any] = [NSAttributedString.Key.font: font] - if (text.kern != 0.0){ - textAttributes[NSAttributedString.Key.kern] = NSNumber(value: text.kern) + if (text.kerning != 0.0){ + textAttributes[NSAttributedString.Key.kern] = NSNumber(value: text.kerning) } if let stroke = text.stroke { textAttributes[NSAttributedString.Key.strokeWidth] = NSNumber(value: stroke.width) From 14db8659e3343697f323c57f8dda9a8d42fa03c7 Mon Sep 17 00:00:00 2001 From: Andrew Romanov Date: Fri, 1 Mar 2019 23:42:01 +0700 Subject: [PATCH 3/3] renamed kern to kerning, fixed tests for kerning attribute --- MacawTests/Bounds/NodeBoundsTests.swift | 19 +++++++++++++++++++ Source/MCAMediaTimingFunctionName_macOS.swift | 2 -- Source/model/scene/Text.swift | 14 ++++++++------ Source/render/TextRenderer.swift | 12 ++++++------ 4 files changed, 33 insertions(+), 14 deletions(-) diff --git a/MacawTests/Bounds/NodeBoundsTests.swift b/MacawTests/Bounds/NodeBoundsTests.swift index 69e32ea3..f7cbb4d2 100644 --- a/MacawTests/Bounds/NodeBoundsTests.swift +++ b/MacawTests/Bounds/NodeBoundsTests.swift @@ -168,6 +168,25 @@ class NodeBoundsTests: XCTestCase { } } + + func testTextWithKerning() { + let texts = ["", "Hello, World", "Hello,\nWorld", "\nHello\n,\nWorld"] + let kernings : [Float] = [-1.0, -0.5, 0.5, 1.0] + + texts.forEach { (text) in + kernings.forEach({ (kerning) in + let text = Text(text: text, kerning: kerning) + + let stringAttributes = [NSAttributedString.Key.font: MFont.systemFont(ofSize: MFont.systemFontSize), + NSAttributedString.Key.kern: NSNumber(value: kerning)] + let size = text.text.size(withAttributes: stringAttributes) + let targetRect = Rect(x: 0.0, y: 0.0, w: size.width.doubleValue, h: size.height.doubleValue) + + checkBounds(rect1: text.bounds, rect2: targetRect) + }) + } + } + // MARK: - Group func testSimpleGroupZeroBounds() { diff --git a/Source/MCAMediaTimingFunctionName_macOS.swift b/Source/MCAMediaTimingFunctionName_macOS.swift index bf96a3fe..129ccca3 100644 --- a/Source/MCAMediaTimingFunctionName_macOS.swift +++ b/Source/MCAMediaTimingFunctionName_macOS.swift @@ -8,8 +8,6 @@ import Foundation -import Foundation - #if os(OSX) import AppKit diff --git a/Source/model/scene/Text.swift b/Source/model/scene/Text.swift index c9fce75e..440225ab 100644 --- a/Source/model/scene/Text.swift +++ b/Source/model/scene/Text.swift @@ -41,21 +41,21 @@ open class Text: Node { get { return baselineVar.value } set(val) { baselineVar.value = val } } - + public let kerningVar: Variable open var kerning: Float { - get { return kerningVar.value } - set(val) { kerningVar.value = val} + get { return kerningVar.value } + set(val) { kerningVar.value = val } } - public init(text: String, font: Font? = nil, fill: Fill? = Color.black, stroke: Stroke? = nil, align: Align = .min, baseline: Baseline = .top, kern: Float = 0.0, place: Transform = Transform.identity, opaque: Bool = true, opacity: Double = 1, clip: Locus? = nil, mask: Node? = nil, effect: Effect? = nil, visible: Bool = true, tag: [String] = []) { + public init(text: String, font: Font? = nil, fill: Fill? = Color.black, stroke: Stroke? = nil, align: Align = .min, baseline: Baseline = .top, kerning: Float = 0.0, place: Transform = Transform.identity, opaque: Bool = true, opacity: Double = 1, clip: Locus? = nil, mask: Node? = nil, effect: Effect? = nil, visible: Bool = true, tag: [String] = []) { self.textVar = Variable(text) self.fontVar = Variable(font) self.fillVar = Variable(fill) self.strokeVar = Variable(stroke) self.alignVar = Variable(align) self.baselineVar = Variable(baseline) - self.kerningVar = Variable(kern) + self.kerningVar = Variable(kerning) super.init( place: place, opaque: opaque, @@ -82,7 +82,9 @@ open class Text: Node { } var stringAttributes: [NSAttributedString.Key: AnyObject] = [:] stringAttributes[NSAttributedString.Key.font] = font - stringAttributes[NSAttributedString.Key.kern] = NSNumber(value: self.kerning) + if self.kerning != 0.0 { + stringAttributes[NSAttributedString.Key.kern] = NSNumber(value: self.kerning) + } let size = (text as NSString).size(withAttributes: stringAttributes) return Rect( x: calculateAlignmentOffset(font: font), diff --git a/Source/render/TextRenderer.swift b/Source/render/TextRenderer.swift index f9876f10..8883647a 100644 --- a/Source/render/TextRenderer.swift +++ b/Source/render/TextRenderer.swift @@ -67,9 +67,9 @@ class TextRenderer: NodeRenderer { attributes[NSAttributedString.Key.strokeWidth] = width as NSObject? } if text.kerning != 0.0 { - attributes[NSAttributedString.Key.kern] = NSNumber(value: text.kerning) + attributes[NSAttributedString.Key.kern] = NSNumber(value: text.kerning) } - + if attributes.count > 1 { MGraphicsPushContext(context) message.draw(in: getBounds(font), withAttributes: attributes) @@ -134,12 +134,12 @@ class TextRenderer: NodeRenderer { return .zero } - var textAttributes : [NSAttributedString.Key: Any] = [NSAttributedString.Key.font: font] - if (text.kerning != 0.0){ - textAttributes[NSAttributedString.Key.kern] = NSNumber(value: text.kerning) + var textAttributes: [NSAttributedString.Key: Any] = [NSAttributedString.Key.font: font] + if text.kerning != 0.0 { + textAttributes[NSAttributedString.Key.kern] = NSNumber(value: text.kerning) } if let stroke = text.stroke { - textAttributes[NSAttributedString.Key.strokeWidth] = NSNumber(value: stroke.width) + textAttributes[NSAttributedString.Key.strokeWidth] = NSNumber(value: stroke.width) } let textSize = NSString(string: text.text).size(withAttributes: textAttributes) return CGRect(x: calculateAlignmentOffset(text, font: font),