From 9a84348e225c08f30e70c0207e276cac733a039b Mon Sep 17 00:00:00 2001 From: Peter <> Date: Wed, 3 Oct 2018 01:30:05 +0400 Subject: [PATCH] no message --- .../xcschemes/DisplayMac.xcscheme | 82 ------------- .../xcschemes/DisplayTests.xcscheme | 56 --------- .../xcschemes/xcschememanagement.plist | 12 +- Display/NativeWindowHostView.swift | 27 ++++- Display/TextNode.swift | 112 ++++++++++++------ Display/WindowContent.swift | 4 + 6 files changed, 106 insertions(+), 187 deletions(-) delete mode 100644 Display.xcodeproj/xcuserdata/peter.xcuserdatad/xcschemes/DisplayMac.xcscheme delete mode 100644 Display.xcodeproj/xcuserdata/peter.xcuserdatad/xcschemes/DisplayTests.xcscheme diff --git a/Display.xcodeproj/xcuserdata/peter.xcuserdatad/xcschemes/DisplayMac.xcscheme b/Display.xcodeproj/xcuserdata/peter.xcuserdatad/xcschemes/DisplayMac.xcscheme deleted file mode 100644 index 4c933753f7..0000000000 --- a/Display.xcodeproj/xcuserdata/peter.xcuserdatad/xcschemes/DisplayMac.xcscheme +++ /dev/null @@ -1,82 +0,0 @@ - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - diff --git a/Display.xcodeproj/xcuserdata/peter.xcuserdatad/xcschemes/DisplayTests.xcscheme b/Display.xcodeproj/xcuserdata/peter.xcuserdatad/xcschemes/DisplayTests.xcscheme deleted file mode 100644 index 2ae31f3e32..0000000000 --- a/Display.xcodeproj/xcuserdata/peter.xcuserdatad/xcschemes/DisplayTests.xcscheme +++ /dev/null @@ -1,56 +0,0 @@ - - - - - - - - - - - - - - - - - - - - - - - - - diff --git a/Display.xcodeproj/xcuserdata/peter.xcuserdatad/xcschemes/xcschememanagement.plist b/Display.xcodeproj/xcuserdata/peter.xcuserdatad/xcschemes/xcschememanagement.plist index 17298f558b..5a5ed076ae 100644 --- a/Display.xcodeproj/xcuserdata/peter.xcuserdatad/xcschemes/xcschememanagement.plist +++ b/Display.xcodeproj/xcuserdata/peter.xcuserdatad/xcschemes/xcschememanagement.plist @@ -7,17 +7,7 @@ Display.xcscheme orderHint - 6 - - DisplayMac.xcscheme - - orderHint - 25 - - DisplayTests.xcscheme - - orderHint - 8 + 4 SuppressBuildableAutocreation diff --git a/Display/NativeWindowHostView.swift b/Display/NativeWindowHostView.swift index 918a91fc88..306b4900d8 100644 --- a/Display/NativeWindowHostView.swift +++ b/Display/NativeWindowHostView.swift @@ -11,7 +11,20 @@ private let defaultOrientations: UIInterfaceOrientationMask = { } }() -private class WindowRootViewController: UIViewController { +private final class WindowRootViewControllerView: UIView { + override var frame: CGRect { + get { + return super.frame + } set(value) { + var value = value + value.size.height += value.minY + value.origin.y = 0.0 + super.frame = value + } + } +} + +private final class WindowRootViewController: UIViewController { var presentController: ((UIViewController, PresentationSurfaceLevel, Bool, (() -> Void)?) -> Void)? var transitionToSize: ((CGSize, Double) -> Void)? @@ -62,6 +75,16 @@ private class WindowRootViewController: UIViewController { return orientations } + init() { + super.init(nibName: nil, bundle: nil) + + self.extendedLayoutIncludesOpaqueBars = true + } + + required init?(coder aDecoder: NSCoder) { + fatalError("init(coder:) has not been implemented") + } + override func preferredScreenEdgesDeferringSystemGestures() -> UIRectEdge { return self.gestureEdges } @@ -78,7 +101,7 @@ private class WindowRootViewController: UIViewController { } override func loadView() { - self.view = UIView() + self.view = WindowRootViewControllerView() self.view.isOpaque = false self.view.backgroundColor = nil } diff --git a/Display/TextNode.swift b/Display/TextNode.swift index e2efc66444..ed6a16b36f 100644 --- a/Display/TextNode.swift +++ b/Display/TextNode.swift @@ -25,15 +25,43 @@ public enum TextNodeCutoutPosition { } public struct TextNodeCutout: Equatable { - public let position: TextNodeCutoutPosition - public let size: CGSize + public var topLeft: CGSize? + public var topRight: CGSize? + public var bottomRight: CGSize? - public init(position: TextNodeCutoutPosition, size: CGSize) { - self.position = position - self.size = size + public init(topLeft: CGSize? = nil, topRight: CGSize? = nil, bottomRight: CGSize? = nil) { + self.topLeft = topLeft + self.topRight = topRight + self.bottomRight = bottomRight } } +private func displayLineFrame(frame: CGRect, isRTL: Bool, boundingRect: CGRect, cutout: TextNodeCutout?) -> CGRect { + if frame.width.isEqual(to: boundingRect.width) { + return frame + } + var lineFrame = frame + let intersectionFrame = lineFrame.offsetBy(dx: 0.0, dy: -lineFrame.height) + if isRTL { + lineFrame.origin.x = max(0.0, floor(boundingRect.width - lineFrame.size.width)) + if let topRight = cutout?.topRight { + let topRightRect = CGRect(origin: CGPoint(x: boundingRect.width - topRight.width, y: 0.0), size: topRight) + if intersectionFrame.intersects(topRightRect) { + lineFrame.origin.x -= topRight.width + return lineFrame + } + } + if let bottomRight = cutout?.bottomRight { + let bottomRightRect = CGRect(origin: CGPoint(x: boundingRect.width - bottomRight.width, y: boundingRect.height - bottomRight.height), size: bottomRight) + if intersectionFrame.intersects(bottomRightRect) { + lineFrame.origin.x -= bottomRight.width + return lineFrame + } + } + } + return lineFrame +} + public final class TextNodeLayoutArguments { public let attributedString: NSAttributedString? public let backgroundColor: UIColor? @@ -111,7 +139,6 @@ public final class TextNodeLayout: NSObject { if let attributedString = self.attributedString { let transformedPoint = CGPoint(x: point.x - self.insets.left, y: point.y - self.insets.top) var lineIndex = -1 - let lineCount = self.lines.count for line in self.lines { lineIndex += 1 var lineFrame = CGRect(origin: CGPoint(x: line.frame.origin.x, y: line.frame.origin.y - line.frame.size.height + self.firstLineOffset), size: line.frame.size) @@ -120,11 +147,9 @@ public final class TextNodeLayout: NSObject { lineFrame.origin.x = floor((self.size.width - lineFrame.size.width) / 2.0) case .natural: if line.isRTL { - lineFrame.origin.x = floor(self.size.width - lineFrame.size.width) - if lineIndex == lineCount - 1, let cutout = self.cutout, case .BottomRight = cutout.position { - lineFrame.origin.x -= cutout.size.width - } + lineFrame.origin.x = self.size.width - lineFrame.size.width } + lineFrame = displayLineFrame(frame: lineFrame, isRTL: line.isRTL, boundingRect: CGRect(origin: CGPoint(), size: self.size), cutout: self.cutout) default: break } @@ -155,10 +180,8 @@ public final class TextNodeLayout: NSObject { case .natural: if line.isRTL { lineFrame.origin.x = floor(self.size.width - lineFrame.size.width) - if lineIndex == lineCount - 1, let cutout = self.cutout, case .BottomRight = cutout.position { - lineFrame.origin.x -= cutout.size.width - } } + lineFrame = displayLineFrame(frame: lineFrame, isRTL: line.isRTL, boundingRect: CGRect(origin: CGPoint(), size: self.size), cutout: self.cutout) default: break } @@ -208,10 +231,7 @@ public final class TextNodeLayout: NSObject { let _ = attributedString.attribute(NSAttributedStringKey(rawValue: name), at: index, effectiveRange: &range) if range.length != 0 { var rects: [(CGRect, CGRect)] = [] - var lineIndex = -1 - let lineCount = self.lines.count for line in self.lines { - lineIndex += 1 let lineRange = NSIntersectionRange(range, line.range) if lineRange.length != 0 { var leftOffset: CGFloat = 0.0 @@ -220,12 +240,17 @@ public final class TextNodeLayout: NSObject { } var rightOffset: CGFloat = line.frame.width if lineRange.location + lineRange.length != line.range.length { - rightOffset = ceil(CTLineGetOffsetForStringIndex(line.line, lineRange.location + lineRange.length, nil)) + var secondaryOffset: CGFloat = 0.0 + let rawOffset = CTLineGetOffsetForStringIndex(line.line, lineRange.location + lineRange.length, &secondaryOffset) + rightOffset = ceil(rawOffset) + if !rawOffset.isEqual(to: secondaryOffset) { + rightOffset = ceil(secondaryOffset) + } } var lineFrame = CGRect(origin: CGPoint(x: line.frame.origin.x, y: line.frame.origin.y - line.frame.size.height + self.firstLineOffset), size: line.frame.size) - if lineIndex == lineCount - 1, let cutout = self.cutout, case .BottomRight = cutout.position { - lineFrame.origin.x -= cutout.size.width - } + + lineFrame = displayLineFrame(frame: lineFrame, isRTL: line.isRTL, boundingRect: CGRect(origin: CGPoint(), size: self.size), cutout: self.cutout) + rects.append((lineFrame, CGRect(origin: CGPoint(x: lineFrame.minX + leftOffset + self.insets.left, y: lineFrame.minY + self.insets.top), size: CGSize(width: rightOffset - leftOffset, height: lineFrame.size.height)))) } } @@ -315,14 +340,26 @@ public class TextNode: ASDisplayNode { var cutoutMaxY: CGFloat = 0.0 var cutoutWidth: CGFloat = 0.0 var cutoutOffset: CGFloat = 0.0 - if let cutout = cutout { + + var bottomCutoutEnabled = false + var bottomCutoutSize = CGSize() + + if let topLeft = cutout?.topLeft { cutoutMinY = -fontLineSpacing - cutoutMaxY = cutout.size.height + fontLineSpacing - cutoutWidth = cutout.size.width - if case .TopLeft = cutout.position { - cutoutOffset = cutoutWidth - } + cutoutMaxY = topLeft.height + fontLineSpacing + cutoutWidth = topLeft.width + cutoutOffset = cutoutWidth cutoutEnabled = true + } else if let topRight = cutout?.topRight { + cutoutMinY = -fontLineSpacing + cutoutMaxY = topRight.height + fontLineSpacing + cutoutWidth = topRight.width + cutoutEnabled = true + } + + if let bottomRight = cutout?.bottomRight { + bottomCutoutSize = bottomRight + bottomCutoutEnabled = true } let firstLineOffset = floorToScreenPixels(fontDescent) @@ -437,6 +474,10 @@ public class TextNode: ASDisplayNode { } } + if !lines.isEmpty && bottomCutoutEnabled { + layoutSize.width = max(layoutSize.width, lines[lines.count - 1].frame.width + bottomCutoutSize.width) + } + return TextNodeLayout(attributedString: attributedString, maximumNumberOfLines: maximumNumberOfLines, truncationType: truncationType, constrainedSize: constrainedSize, alignment: alignment, lineSpacing: lineSpacingFactor, cutout: cutout, insets: insets, size: CGSize(width: ceil(layoutSize.width) + insets.left + insets.right, height: ceil(layoutSize.height) + insets.top + insets.bottom), firstLineOffset: firstLineOffset, lines: lines, backgroundColor: backgroundColor) } else { return TextNodeLayout(attributedString: attributedString, maximumNumberOfLines: maximumNumberOfLines, truncationType: truncationType, constrainedSize: constrainedSize, alignment: alignment, lineSpacing: lineSpacingFactor, cutout: cutout, insets: insets, size: CGSize(), firstLineOffset: 0.0, lines: [], backgroundColor: backgroundColor) @@ -483,21 +524,20 @@ public class TextNode: ASDisplayNode { let alignment = layout.alignment let offset = CGPoint(x: layout.insets.left, y: layout.insets.top) - let lineCount = layout.lines.count for i in 0 ..< layout.lines.count { let line = layout.lines[i] - var lineOffset: CGFloat + + var lineFrame = line.frame + lineFrame.origin.y += offset.y + if alignment == .center { - lineOffset = floor((bounds.size.width - line.frame.size.width) / 2.0) + lineFrame.origin.x = offset.x + floor((bounds.size.width - lineFrame.width) / 2.0) } else if alignment == .natural, line.isRTL { - lineOffset = floor(bounds.size.width - line.frame.size.width) - if i == lineCount - 1, let cutout = layout.cutout, case .BottomRight = cutout.position { - lineOffset -= cutout.size.width - } - } else { - lineOffset = 0.0 + lineFrame.origin.x = offset.x + floor(bounds.size.width - lineFrame.width) + + lineFrame = displayLineFrame(frame: lineFrame, isRTL: line.isRTL, boundingRect: CGRect(origin: CGPoint(), size: bounds.size), cutout: layout.cutout) } - context.textPosition = CGPoint(x: line.frame.origin.x + lineOffset + offset.x, y: line.frame.origin.y + offset.y) + context.textPosition = CGPoint(x: lineFrame.minX, y: lineFrame.minY) CTLineDraw(line.line, context) } diff --git a/Display/WindowContent.swift b/Display/WindowContent.swift index 8c5d5b6330..19ea652fe6 100644 --- a/Display/WindowContent.swift +++ b/Display/WindowContent.swift @@ -554,6 +554,10 @@ public class Window1 { } public func hitTest(_ point: CGPoint, with event: UIEvent?) -> UIView? { + if let coveringView = self.coveringView, !coveringView.isHidden, coveringView.superview != nil, coveringView.frame.contains(point) { + return coveringView.hitTest(point, with: event) + } + for view in self.hostView.eventView.subviews.reversed() { if NSStringFromClass(type(of: view)) == "UITransitionView" { if let result = view.hitTest(point, with: event) {