1
1
mirror of https://github.com/exyte/Macaw.git synced 2024-09-11 13:15:35 +03:00
This commit is contained in:
Sroik 2018-09-26 18:16:28 +03:00
parent a32e814dfd
commit d690e118cc
6 changed files with 53 additions and 28 deletions

View File

@ -23,7 +23,7 @@ open class Group: Node {
}
}
public init(contents: [Node] = [], 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(contents: [Node] = [], place: Transform = Transform.identity, opaque: Bool = true, opacity: Double = 1, clip: Locus? = nil, mask: Node? = nil, effect: Effect? = nil, visible: Bool = true, nodeId: String? = nil, tag: [String] = []) {
self.contentsVar = AnimatableVariable<[Node]>(contents)
super.init(
place: place,
@ -33,6 +33,7 @@ open class Group: Node {
mask: mask,
effect: effect,
visible: visible,
nodeId: nodeId,
tag: tag
)
@ -151,7 +152,7 @@ open class Group: Node {
}
public extension Array where Element: Node {
public func group( place: Transform = Transform.identity, opaque: Bool = true, opacity: Double = 1, clip: Locus? = nil, effect: Effect? = nil, visible: Bool = true, tag: [String] = []) -> Group {
return Group(contents: self, place: place, opaque: opaque, opacity: opacity, clip: clip, effect: effect, visible: visible, tag: tag)
public func group( place: Transform = Transform.identity, opaque: Bool = true, opacity: Double = 1, clip: Locus? = nil, effect: Effect? = nil, visible: Bool = true, nodeId: String? = nil, tag: [String] = []) -> Group {
return Group(contents: self, place: place, opaque: opaque, opacity: opacity, clip: clip, effect: effect, visible: visible, nodeId: nodeId, tag: tag)
}
}

View File

@ -46,7 +46,7 @@ open class Image: Node {
private var mImage: MImage?
public init(src: String, xAlign: Align = .min, yAlign: Align = .min, aspectRatio: AspectRatio = .none, w: Int = 0, h: Int = 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(src: String, xAlign: Align = .min, yAlign: Align = .min, aspectRatio: AspectRatio = .none, w: Int = 0, h: Int = 0, place: Transform = Transform.identity, opaque: Bool = true, opacity: Double = 1, clip: Locus? = nil, mask: Node? = nil, effect: Effect? = nil, visible: Bool = true, nodeId: String? = nil, tag: [String] = []) {
self.srcVar = Variable<String>(src)
self.xAlignVar = Variable<Align>(xAlign)
self.yAlignVar = Variable<Align>(yAlign)
@ -61,11 +61,12 @@ open class Image: Node {
mask: mask,
effect: effect,
visible: visible,
nodeId: nodeId,
tag: tag
)
}
public init(image: MImage, xAlign: Align = .min, yAlign: Align = .min, aspectRatio: AspectRatio = .none, w: Int = 0, h: Int = 0, place: Transform = Transform.identity, opaque: Bool = true, opacity: Double = 1, clip: Locus? = nil, effect: Effect? = nil, visible: Bool = true, tag: [String] = []) {
public init(image: MImage, xAlign: Align = .min, yAlign: Align = .min, aspectRatio: AspectRatio = .none, w: Int = 0, h: Int = 0, place: Transform = Transform.identity, opaque: Bool = true, opacity: Double = 1, clip: Locus? = nil, effect: Effect? = nil, visible: Bool = true, nodeId: String? = nil, tag: [String] = []) {
var oldId: String?
for key in imagesMap.keys where image === imagesMap[key] {
@ -88,6 +89,7 @@ open class Image: Node {
clip: clip,
effect: effect,
visible: visible,
nodeId: nodeId,
tag: tag
)
}

View File

@ -38,6 +38,12 @@ open class Node: Drawable {
set(val) { effectVar.value = val }
}
public let nodeIdVar: Variable<String?>
open var nodeId: String? {
get { return nodeIdVar.value }
set(val) { nodeIdVar.value = val }
}
internal var id: String {
didSet {
Node.map.removeObject(forKey: id as NSString)
@ -300,7 +306,7 @@ open class Node: Drawable {
return !pinchHandlers.isEmpty
}
public init(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(place: Transform = Transform.identity, opaque: Bool = true, opacity: Double = 1, clip: Locus? = nil, mask: Node? = nil, effect: Effect? = nil, visible: Bool = true, nodeId: String? = nil, tag: [String] = []) {
self.placeVar = AnimatableVariable<Transform>(place)
self.opaqueVar = Variable<Bool>(opaque)
self.opacityVar = AnimatableVariable<Double>(opacity)
@ -308,6 +314,7 @@ open class Node: Drawable {
self.maskVar = Variable<Node?>(mask)
self.effectVar = Variable<Effect?>(effect)
self.id = NSUUID().uuidString
self.nodeIdVar = Variable<String?>(nodeId)
super.init(
visible: visible,

View File

@ -24,7 +24,7 @@ open class Shape: Node {
set(val) { strokeVar.value = val }
}
public init(form: Locus, fill: Fill? = nil, stroke: Stroke? = nil, 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(form: Locus, fill: Fill? = nil, stroke: Stroke? = nil, place: Transform = Transform.identity, opaque: Bool = true, opacity: Double = 1, clip: Locus? = nil, mask: Node? = nil, effect: Effect? = nil, visible: Bool = true, nodeId: String? = nil, tag: [String] = []) {
self.formVar = AnimatableVariable<Locus>(form)
self.fillVar = AnimatableVariable<Fill?>(fill)
self.strokeVar = AnimatableVariable<Stroke?>(stroke)
@ -36,6 +36,7 @@ open class Shape: Node {
mask: mask,
effect: effect,
visible: visible,
nodeId: nodeId,
tag: tag
)

View File

@ -42,7 +42,7 @@ open class Text: Node {
set(val) { baselineVar.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, place: Transform = Transform.identity, opaque: Bool = true, opacity: Double = 1, clip: Locus? = nil, mask: Node? = nil, effect: Effect? = nil, visible: Bool = true, nodeId: String? = nil, tag: [String] = []) {
self.textVar = Variable<String>(text)
self.fontVar = Variable<Font?>(font)
self.fillVar = Variable<Fill>(fill)
@ -57,6 +57,7 @@ open class Text: Node {
mask: mask,
effect: effect,
visible: visible,
nodeId: nodeId,
tag: tag
)
}

View File

@ -213,7 +213,7 @@ open class SVGParser {
case "g":
result = parseGroup(node, groupStyle: groupStyle)
case "clipPath":
if let id = element.allAttributes["id"]?.text, let clip = parseClip(node) {
if let id = element.idAttribute, let clip = parseClip(node) {
self.defClip[id] = clip
}
case "style", "defs":
@ -271,7 +271,7 @@ open class SVGParser {
}
private func parseDefinition(_ child: XMLIndexer) {
guard let id = child.element?.allAttributes["id"]?.text, let element = child.element else {
guard let id = child.element?.idAttribute, let element = child.element else {
return
}
@ -313,8 +313,8 @@ open class SVGParser {
guard let element = node.element else {
return .none
}
let id = node.element?.allAttributes["id"]?.text
let id = element.idAttribute
let styleAttributes = groupStyle
let position = getPosition(element)
switch element.name {
@ -323,31 +323,31 @@ open class SVGParser {
if let rule = getFillRule(styleAttributes) {
path = Path(segments: path.segments, fillRule: rule)
}
return Shape(form: path, fill: getFillColor(styleAttributes, groupStyle: styleAttributes), stroke: getStroke(styleAttributes, groupStyle: styleAttributes), place: position, opacity: getOpacity(styleAttributes), clip: getClipPath(styleAttributes, locus: path), mask: getMask(styleAttributes, locus: path), tag: getTag(element))
return Shape(form: path, fill: getFillColor(styleAttributes, groupStyle: styleAttributes), stroke: getStroke(styleAttributes, groupStyle: styleAttributes), place: position, opacity: getOpacity(styleAttributes), clip: getClipPath(styleAttributes, locus: path), mask: getMask(styleAttributes, locus: path), nodeId: id, tag: getTag(element))
}
case "line":
if let line = parseLine(node) {
return Shape(form: line, fill: getFillColor(styleAttributes, groupStyle: styleAttributes), stroke: getStroke(styleAttributes, groupStyle: styleAttributes), place: position, opacity: getOpacity(styleAttributes), clip: getClipPath(styleAttributes, locus: line), mask: getMask(styleAttributes, locus: line), tag: getTag(element))
return Shape(form: line, fill: getFillColor(styleAttributes, groupStyle: styleAttributes), stroke: getStroke(styleAttributes, groupStyle: styleAttributes), place: position, opacity: getOpacity(styleAttributes), clip: getClipPath(styleAttributes, locus: line), mask: getMask(styleAttributes, locus: line), nodeId: id, tag: getTag(element))
}
case "rect":
if let rect = parseRect(node) {
return Shape(form: rect, fill: getFillColor(styleAttributes, groupStyle: styleAttributes), stroke: getStroke(styleAttributes, groupStyle: styleAttributes), place: position, opacity: getOpacity(styleAttributes), clip: getClipPath(styleAttributes, locus: rect), mask: getMask(styleAttributes, locus: rect), tag: getTag(element))
return Shape(form: rect, fill: getFillColor(styleAttributes, groupStyle: styleAttributes), stroke: getStroke(styleAttributes, groupStyle: styleAttributes), place: position, opacity: getOpacity(styleAttributes), clip: getClipPath(styleAttributes, locus: rect), mask: getMask(styleAttributes, locus: rect), nodeId: id, tag: getTag(element))
}
case "circle":
if let circle = parseCircle(node) {
return Shape(form: circle, fill: getFillColor(styleAttributes, groupStyle: styleAttributes), stroke: getStroke(styleAttributes, groupStyle: styleAttributes), place: position, opacity: getOpacity(styleAttributes), clip: getClipPath(styleAttributes, locus: circle), mask: getMask(styleAttributes, locus: circle), tag: getTag(element))
return Shape(form: circle, fill: getFillColor(styleAttributes, groupStyle: styleAttributes), stroke: getStroke(styleAttributes, groupStyle: styleAttributes), place: position, opacity: getOpacity(styleAttributes), clip: getClipPath(styleAttributes, locus: circle), mask: getMask(styleAttributes, locus: circle), nodeId: id, tag: getTag(element))
}
case "ellipse":
if let ellipse = parseEllipse(node) {
return Shape(form: ellipse, fill: getFillColor(styleAttributes, groupStyle: styleAttributes), stroke: getStroke(styleAttributes, groupStyle: styleAttributes), place: position, opacity: getOpacity(styleAttributes), clip: getClipPath(styleAttributes, locus: ellipse), mask: getMask(styleAttributes, locus: ellipse), tag: getTag(element))
return Shape(form: ellipse, fill: getFillColor(styleAttributes, groupStyle: styleAttributes), stroke: getStroke(styleAttributes, groupStyle: styleAttributes), place: position, opacity: getOpacity(styleAttributes), clip: getClipPath(styleAttributes, locus: ellipse), mask: getMask(styleAttributes, locus: ellipse), nodeId: id, tag: getTag(element))
}
case "polygon":
if let polygon = parsePolygon(node) {
return Shape(form: polygon, fill: getFillColor(styleAttributes, groupStyle: styleAttributes), stroke: getStroke(styleAttributes, groupStyle: styleAttributes), place: position, opacity: getOpacity(styleAttributes), clip: getClipPath(styleAttributes, locus: polygon), mask: getMask(styleAttributes, locus: polygon), tag: getTag(element))
return Shape(form: polygon, fill: getFillColor(styleAttributes, groupStyle: styleAttributes), stroke: getStroke(styleAttributes, groupStyle: styleAttributes), place: position, opacity: getOpacity(styleAttributes), clip: getClipPath(styleAttributes, locus: polygon), mask: getMask(styleAttributes, locus: polygon), nodeId: id, tag: getTag(element))
}
case "polyline":
if let polyline = parsePolyline(node) {
return Shape(form: polyline, fill: getFillColor(styleAttributes, groupStyle: styleAttributes), stroke: getStroke(styleAttributes, groupStyle: styleAttributes), place: position, opacity: getOpacity(styleAttributes), clip: getClipPath(styleAttributes, locus: polyline), mask: getMask(styleAttributes, locus: polyline), tag: getTag(element))
return Shape(form: polyline, fill: getFillColor(styleAttributes, groupStyle: styleAttributes), stroke: getStroke(styleAttributes, groupStyle: styleAttributes), place: position, opacity: getOpacity(styleAttributes), clip: getClipPath(styleAttributes, locus: polyline), mask: getMask(styleAttributes, locus: polyline), nodeId: id, tag: getTag(element))
}
case "image":
return parseImage(node, opacity: getOpacity(styleAttributes), pos: position, clip: getClipPath(styleAttributes, locus: nil))
@ -404,7 +404,13 @@ open class SVGParser {
groupNodes.append(node)
}
}
return Group(contents: groupNodes, place: getPosition(element), tag: getTag(element))
return Group(
contents: groupNodes,
place: getPosition(element),
nodeId: element.idAttribute,
tag: getTag(element)
)
}
fileprivate func getPosition(_ element: SWXMLHash.XMLElement) -> Transform {
@ -763,7 +769,7 @@ open class SVGParser {
}
fileprivate func getTag(_ element: SWXMLHash.XMLElement) -> [String] {
let id = element.allAttributes["id"]?.text
let id = element.idAttribute
return id != nil ? [id!] : []
}
@ -876,7 +882,7 @@ open class SVGParser {
return .none
}
let position = pos.move(dx: getDoubleValue(element, attribute: "x") ?? 0, dy: getDoubleValue(element, attribute: "y") ?? 0)
return Image(src: link, w: getIntValue(element, attribute: "width") ?? 0, h: getIntValue(element, attribute: "height") ?? 0, place: position, clip: clip, tag: getTag(element))
return Image(src: link, w: getIntValue(element, attribute: "width") ?? 0, h: getIntValue(element, attribute: "height") ?? 0, place: position, clip: clip, nodeId: element.idAttribute, tag: getTag(element))
}
fileprivate func parseText(_ text: XMLIndexer, textAnchor: String?, fill: Fill?, stroke: Stroke?, opacity: Double, fontName: String?, fontSize: Int?, fontWeight: String?, pos: Transform = Transform()) -> Node? {
@ -894,7 +900,7 @@ open class SVGParser {
if let match = matcher.firstMatch(in: elementString, options: .reportCompletion, range: fullRange) {
let tspans = (elementString as NSString).substring(with: match.range(at: 1))
return Group(contents: collectTspans(tspans, textAnchor: textAnchor, fill: fill, stroke: stroke, opacity: opacity, fontName: fontName, fontSize: fontSize, fontWeight: fontWeight, bounds: Rect(x: getDoubleValue(element, attribute: "x") ?? 0, y: getDoubleValue(element, attribute: "y") ?? 0)),
place: pos, tag: getTag(element))
place: pos, nodeId: element.idAttribute, tag: getTag(element))
}
}
return .none
@ -915,7 +921,7 @@ open class SVGParser {
let string = text.text
let position = pos.move(dx: getDoubleValue(text, attribute: "x") ?? 0, dy: getDoubleValue(text, attribute: "y") ?? 0)
return Text(text: string, font: getFont(fontName: fontName, fontWeight: fontWeight, fontSize: fontSize), fill: fill ?? Color.black, stroke: stroke, align: anchorToAlign(textAnchor), baseline: .bottom, place: position, opacity: opacity, tag: getTag(text))
return Text(text: string, font: getFont(fontName: fontName, fontWeight: fontWeight, fontSize: fontSize), fill: fill ?? Color.black, stroke: stroke, align: anchorToAlign(textAnchor), baseline: .bottom, place: position, opacity: opacity, nodeId: text.idAttribute, tag: getTag(text))
}
// REFACTOR
@ -988,7 +994,7 @@ open class SVGParser {
return Text(text: text, font: getFont(attributes, fontName: fontName, fontWeight: fontWeight, fontSize: fontSize),
fill: ((attributes["fill"] != nil) ? getFillColor(attributes)! : fill) ?? Color.black, stroke: stroke ?? getStroke(attributes),
align: anchorToAlign(textAnchor ?? getTextAnchor(attributes)), baseline: .alphabetic,
place: pos, opacity: getOpacity(attributes), tag: getTag(element))
place: pos, opacity: getOpacity(attributes), nodeId: element.idAttribute, tag: getTag(element))
}
fileprivate func getFont(_ attributes: [String: String] = [:], fontName: String?, fontWeight: String?, fontSize: Int?) -> Font {
@ -1531,15 +1537,16 @@ open class SVGParser {
let visible = referenceNode.visible
let clip = referenceNode.clip
let tag = referenceNode.tag
let nodeId = referenceNode.nodeId
if let shape = referenceNode as? Shape {
return Shape(form: shape.form, fill: shape.fill, stroke: shape.stroke, place: pos, opaque: opaque, clip: clip, visible: visible, tag: tag)
return Shape(form: shape.form, fill: shape.fill, stroke: shape.stroke, place: pos, opaque: opaque, clip: clip, visible: visible, nodeId: nodeId, tag: tag)
}
if let text = referenceNode as? Text {
return Text(text: text.text, font: text.font, fill: text.fill, stroke: text.stroke, align: text.align, baseline: text.baseline, place: pos, opaque: opaque, clip: clip, visible: visible, tag: tag)
return Text(text: text.text, font: text.font, fill: text.fill, stroke: text.stroke, align: text.align, baseline: text.baseline, place: pos, opaque: opaque, clip: clip, visible: visible, nodeId: nodeId, tag: tag)
}
if let image = referenceNode as? Image {
return Image(src: image.src, xAlign: image.xAlign, yAlign: image.yAlign, aspectRatio: image.aspectRatio, w: image.w, h: image.h, place: pos, opaque: opaque, clip: clip, visible: visible, tag: tag)
return Image(src: image.src, xAlign: image.xAlign, yAlign: image.yAlign, aspectRatio: image.aspectRatio, w: image.w, h: image.h, place: pos, opaque: opaque, clip: clip, visible: visible, nodeId: nodeId, tag: tag)
}
if let group = referenceNode as? Group {
var contents = [Node]()
@ -1548,7 +1555,7 @@ open class SVGParser {
contents.append(copy)
}
}
return Group(contents: contents, place: pos, opaque: opaque, clip: clip, visible: visible, tag: tag)
return Group(contents: contents, place: pos, opaque: opaque, clip: clip, visible: visible, nodeId: nodeId, tag: tag)
}
return .none
}
@ -1795,3 +1802,9 @@ fileprivate class UserSpaceNode {
self.userSpace = userSpace
}
}
private extension XMLElement {
var idAttribute: String? {
return allAttributes["id"]?.text
}
}