mirror of
https://github.com/exyte/Macaw.git
synced 2024-11-13 13:14:20 +03:00
Apply mask's color, not only form
This commit is contained in:
parent
9fdf3c72ee
commit
4aa568466c
@ -18,13 +18,14 @@ open class Group: Node {
|
||||
}
|
||||
}
|
||||
|
||||
public init(contents: [Node] = [], place: Transform = Transform.identity, opaque: Bool = true, opacity: Double = 1, clip: Locus? = 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: Shape? = nil, effect: Effect? = nil, visible: Bool = true, tag: [String] = []) {
|
||||
self.contentsVar = AnimatableVariable<[Node]>(contents)
|
||||
super.init(
|
||||
place: place,
|
||||
opaque: opaque,
|
||||
opacity: opacity,
|
||||
clip: clip,
|
||||
mask: mask,
|
||||
effect: effect,
|
||||
visible: visible,
|
||||
tag: tag
|
||||
|
@ -26,6 +26,12 @@ open class Node: Drawable {
|
||||
set(val) { clipVar.value = val }
|
||||
}
|
||||
|
||||
open let maskVar: Variable<Shape?>
|
||||
open var mask: Shape? {
|
||||
get { return maskVar.value }
|
||||
set(val) { maskVar.value = val }
|
||||
}
|
||||
|
||||
open let effectVar: Variable<Effect?>
|
||||
open var effect: Effect? {
|
||||
get { return effectVar.value }
|
||||
@ -294,11 +300,12 @@ open class Node: Drawable {
|
||||
return !pinchHandlers.isEmpty
|
||||
}
|
||||
|
||||
public init(place: Transform = Transform.identity, opaque: Bool = true, opacity: Double = 1, clip: Locus? = 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: Shape? = nil, effect: Effect? = nil, visible: Bool = true, tag: [String] = []) {
|
||||
self.placeVar = AnimatableVariable<Transform>(place)
|
||||
self.opaqueVar = Variable<Bool>(opaque)
|
||||
self.opacityVar = AnimatableVariable<Double>(opacity)
|
||||
self.clipVar = Variable<Locus?>(clip)
|
||||
self.maskVar = Variable<Shape?>(mask)
|
||||
self.effectVar = Variable<Effect?>(effect)
|
||||
self.id = NSUUID().uuidString
|
||||
|
||||
|
@ -18,7 +18,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, 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: Shape? = nil, effect: Effect? = nil, visible: Bool = true, tag: [String] = []) {
|
||||
self.formVar = AnimatableVariable<Locus>(form)
|
||||
self.fillVar = AnimatableVariable<Fill?>(fill)
|
||||
self.strokeVar = AnimatableVariable<Stroke?>(stroke)
|
||||
@ -27,6 +27,7 @@ open class Shape: Node {
|
||||
opaque: opaque,
|
||||
opacity: opacity,
|
||||
clip: clip,
|
||||
mask: mask,
|
||||
effect: effect,
|
||||
visible: visible,
|
||||
tag: tag
|
||||
|
@ -35,9 +35,9 @@ class GroupRenderer: NodeRenderer {
|
||||
return group
|
||||
}
|
||||
|
||||
override func doRender(in context: CGContext, force: Bool, opacity: Double, useAlphaOnly: Bool = false) {
|
||||
override func doRender(in context: CGContext, force: Bool, opacity: Double, coloringMode: ColoringMode = .rgb) {
|
||||
renderers.forEach { renderer in
|
||||
renderer.render(in: context, force: force, opacity: opacity, useAlphaOnly: useAlphaOnly)
|
||||
renderer.render(in: context, force: force, opacity: opacity, coloringMode: coloringMode)
|
||||
}
|
||||
}
|
||||
|
||||
|
@ -37,7 +37,7 @@ class ImageRenderer: NodeRenderer {
|
||||
observe(image.hVar)
|
||||
}
|
||||
|
||||
override func doRender(in context: CGContext, force: Bool, opacity: Double, useAlphaOnly: Bool = false) {
|
||||
override func doRender(in context: CGContext, force: Bool, opacity: Double, coloringMode: ColoringMode = .rgb) {
|
||||
guard let image = image else {
|
||||
return
|
||||
}
|
||||
|
@ -11,6 +11,10 @@ struct RenderingInterval {
|
||||
let to: Int
|
||||
}
|
||||
|
||||
enum ColoringMode {
|
||||
case rgb, greyscale, alphaOnly
|
||||
}
|
||||
|
||||
class NodeRenderer {
|
||||
|
||||
let view: MView?
|
||||
@ -71,7 +75,7 @@ class NodeRenderer {
|
||||
fatalError("Unsupported")
|
||||
}
|
||||
|
||||
final public func render(in context: CGContext, force: Bool, opacity: Double, useAlphaOnly: Bool = false) {
|
||||
final public func render(in context: CGContext, force: Bool, opacity: Double, coloringMode: ColoringMode = .rgb) {
|
||||
context.saveGState()
|
||||
defer {
|
||||
context.restoreGState()
|
||||
@ -84,16 +88,23 @@ class NodeRenderer {
|
||||
context.concatenate(node.place.toCG())
|
||||
applyClip(in: context)
|
||||
|
||||
// draw masked image
|
||||
if let mask = node.mask {
|
||||
let bounds = mask.bounds()!
|
||||
context.draw(getMaskedImage(bounds: bounds), in: bounds.toCG())
|
||||
return
|
||||
}
|
||||
|
||||
// no effects, just draw as usual
|
||||
guard let effect = node.effect else {
|
||||
directRender(in: context, force: force, opacity: newOpacity, useAlphaOnly: useAlphaOnly)
|
||||
directRender(in: context, force: force, opacity: newOpacity, coloringMode: coloringMode)
|
||||
return
|
||||
}
|
||||
|
||||
let (offset, otherEffects) = separateEffects(effect)
|
||||
let useAlphaOnly = otherEffects.contains { effect -> Bool in
|
||||
let effectColoringMode = otherEffects.contains { effect -> Bool in
|
||||
effect is AlphaEffect
|
||||
}
|
||||
} ? ColoringMode.alphaOnly : coloringMode
|
||||
|
||||
// move to offset
|
||||
if let offset = offset {
|
||||
@ -102,10 +113,10 @@ class NodeRenderer {
|
||||
|
||||
if otherEffects.isEmpty {
|
||||
// just draw offset shape
|
||||
directRender(in: context, force: force, opacity: newOpacity, useAlphaOnly: useAlphaOnly)
|
||||
directRender(in: context, force: force, opacity: newOpacity, coloringMode: effectColoringMode)
|
||||
} else {
|
||||
// apply other effects to offset shape and draw it
|
||||
applyEffects(otherEffects, context: context, opacity: opacity, useAlphaOnly: useAlphaOnly)
|
||||
applyEffects(otherEffects, context: context, opacity: opacity, coloringMode: effectColoringMode)
|
||||
}
|
||||
|
||||
if otherEffects.contains(where: { effect -> Bool in
|
||||
@ -119,7 +130,7 @@ class NodeRenderer {
|
||||
}
|
||||
}
|
||||
|
||||
final func directRender(in context: CGContext, force: Bool = true, opacity: Double = 1.0, useAlphaOnly: Bool = false) {
|
||||
final func directRender(in context: CGContext, force: Bool = true, opacity: Double = 1.0, coloringMode: ColoringMode = .rgb) {
|
||||
guard let node = node() else {
|
||||
return
|
||||
}
|
||||
@ -132,7 +143,7 @@ class NodeRenderer {
|
||||
} else {
|
||||
self.addObservers()
|
||||
}
|
||||
doRender(in: context, force: force, opacity: opacity, useAlphaOnly: useAlphaOnly)
|
||||
doRender(in: context, force: force, opacity: opacity, coloringMode: coloringMode)
|
||||
}
|
||||
|
||||
fileprivate func separateEffects(_ effect: Effect) -> (OffsetEffect?, [Effect]) {
|
||||
@ -152,7 +163,7 @@ class NodeRenderer {
|
||||
return (offset, otherEffects.reversed())
|
||||
}
|
||||
|
||||
fileprivate func applyEffects(_ effects: [Effect], context: CGContext, opacity: Double, useAlphaOnly: Bool = false) {
|
||||
fileprivate func applyEffects(_ effects: [Effect], context: CGContext, opacity: Double, coloringMode: ColoringMode = .rgb) {
|
||||
guard let node = node(), let bounds = node.bounds() else {
|
||||
return
|
||||
}
|
||||
@ -163,7 +174,7 @@ class NodeRenderer {
|
||||
}
|
||||
}
|
||||
|
||||
let shapeImage = CIImage(cgImage: renderToImage(bounds: bounds, inset: inset, useAlphaOnly: useAlphaOnly)!.cgImage!)
|
||||
let shapeImage = CIImage(cgImage: renderToImage(bounds: bounds, inset: inset, coloringMode: coloringMode)!.cgImage!)
|
||||
|
||||
var filteredImage = shapeImage
|
||||
for effect in effects {
|
||||
@ -201,7 +212,7 @@ class NodeRenderer {
|
||||
return filter.outputImage!
|
||||
}
|
||||
|
||||
func renderToImage(bounds: Rect, inset: Double, useAlphaOnly: Bool = false) -> MImage? {
|
||||
func renderToImage(bounds: Rect, inset: Double = 0, coloringMode: ColoringMode = .rgb) -> MImage? {
|
||||
MGraphicsBeginImageContextWithOptions(CGSize(width: bounds.w + inset, height: bounds.h + inset), false, 1)
|
||||
|
||||
guard let tempContext = MGraphicsGetCurrentContext() else {
|
||||
@ -211,14 +222,14 @@ class NodeRenderer {
|
||||
// flip y-axis and leave space for the blur
|
||||
tempContext.translateBy(x: CGFloat(inset / 2 - bounds.x), y: CGFloat(bounds.h + inset / 2 + bounds.y))
|
||||
tempContext.scaleBy(x: 1, y: -1)
|
||||
directRender(in: tempContext, force: false, opacity: 1.0, useAlphaOnly: useAlphaOnly)
|
||||
directRender(in: tempContext, force: false, opacity: 1.0, coloringMode: coloringMode)
|
||||
|
||||
let img = MGraphicsGetImageFromCurrentImageContext()
|
||||
MGraphicsEndImageContext()
|
||||
return img
|
||||
}
|
||||
|
||||
func doRender(in context: CGContext, force: Bool, opacity: Double, useAlphaOnly: Bool = false) {
|
||||
func doRender(in context: CGContext, force: Bool, opacity: Double, coloringMode: ColoringMode = .rgb) {
|
||||
fatalError("Unsupported")
|
||||
}
|
||||
|
||||
@ -271,6 +282,35 @@ class NodeRenderer {
|
||||
RenderUtils.toBezierPath(clip).addClip()
|
||||
}
|
||||
|
||||
private func getMaskedImage(bounds: Rect) -> CGImage {
|
||||
let mask = node()!.mask!
|
||||
let image = renderToImage(bounds: bounds)!
|
||||
let nodeRenderer = ShapeRenderer(shape: mask, view: .none, animationCache: animationCache)
|
||||
let maskImage = nodeRenderer.renderToImage(bounds: bounds, coloringMode: .greyscale)!
|
||||
return apply(maskImage: maskImage, to: image)
|
||||
}
|
||||
|
||||
func apply(maskImage: MImage, to image: MImage) -> CGImage {
|
||||
let imageReference = image.cgImage!
|
||||
let maskReference = maskImage.cgImage!
|
||||
|
||||
let decode = [CGFloat(1), CGFloat(0),
|
||||
CGFloat(0), CGFloat(1),
|
||||
CGFloat(0), CGFloat(1),
|
||||
CGFloat(0), CGFloat(1)]
|
||||
|
||||
let invertedMask = CGImage(maskWidth: maskReference.width,
|
||||
height: maskReference.height,
|
||||
bitsPerComponent: maskReference.bitsPerComponent,
|
||||
bitsPerPixel: maskReference.bitsPerPixel,
|
||||
bytesPerRow: maskReference.bytesPerRow,
|
||||
provider: maskReference.dataProvider!,
|
||||
decode: decode,
|
||||
shouldInterpolate: maskReference.shouldInterpolate)!
|
||||
|
||||
return imageReference.masking(invertedMask)!
|
||||
}
|
||||
|
||||
private func addObservers() {
|
||||
if !active {
|
||||
active = true
|
||||
|
@ -31,7 +31,7 @@ class ShapeRenderer: NodeRenderer {
|
||||
observe(shape.strokeVar)
|
||||
}
|
||||
|
||||
override func doRender(in context: CGContext, force: Bool, opacity: Double, useAlphaOnly: Bool = false) {
|
||||
override func doRender(in context: CGContext, force: Bool, opacity: Double, coloringMode: ColoringMode = .rgb) {
|
||||
guard let shape = shape else {
|
||||
return
|
||||
}
|
||||
@ -46,9 +46,12 @@ class ShapeRenderer: NodeRenderer {
|
||||
fillRule = path.fillRule
|
||||
}
|
||||
|
||||
if !useAlphaOnly {
|
||||
switch coloringMode {
|
||||
case .rgb:
|
||||
drawPath(fill: shape.fill, stroke: shape.stroke, ctx: context, opacity: opacity, fillRule: fillRule)
|
||||
} else {
|
||||
case .greyscale:
|
||||
drawPath(fill: shape.fill?.fillUsingGrayscaleNoAlpha(), stroke: shape.stroke?.strokeUsingGrayscaleNoAlpha(), ctx: context, opacity: opacity, fillRule: fillRule)
|
||||
case .alphaOnly:
|
||||
drawPath(fill: shape.fill?.fillUsingAlphaOnly(), stroke: shape.stroke?.strokeUsingAlphaOnly(), ctx: context, opacity: opacity, fillRule: fillRule)
|
||||
}
|
||||
}
|
||||
@ -251,6 +254,9 @@ extension Stroke {
|
||||
func strokeUsingAlphaOnly() -> Stroke {
|
||||
return Stroke(fill: fill.fillUsingAlphaOnly(), width: width, cap: cap, join: join, dashes: dashes, offset: offset)
|
||||
}
|
||||
func strokeUsingGrayscaleNoAlpha() -> Stroke {
|
||||
return Stroke(fill: fill.fillUsingGrayscaleNoAlpha(), width: width, cap: cap, join: join, dashes: dashes, offset: offset)
|
||||
}
|
||||
}
|
||||
|
||||
extension Fill {
|
||||
@ -266,10 +272,28 @@ extension Fill {
|
||||
let linear = self as! LinearGradient
|
||||
return LinearGradient(x1: linear.x1, y1: linear.y1, x2: linear.x2, y2: linear.y2, userSpace: linear.userSpace, stops: newStops)
|
||||
}
|
||||
|
||||
func fillUsingGrayscaleNoAlpha() -> Fill {
|
||||
if let color = self as? Color {
|
||||
return color.toGrayscaleNoAlpha()
|
||||
}
|
||||
let gradient = self as! Gradient
|
||||
let newStops = gradient.stops.map { Stop(offset: $0.offset, color: $0.color.toGrayscaleNoAlpha()) }
|
||||
if let radial = self as? RadialGradient {
|
||||
return RadialGradient(cx: radial.cx, cy: radial.cy, fx: radial.fx, fy: radial.fy, r: radial.r, userSpace: radial.userSpace, stops: newStops)
|
||||
}
|
||||
let linear = self as! LinearGradient
|
||||
return LinearGradient(x1: linear.x1, y1: linear.y1, x2: linear.x2, y2: linear.y2, userSpace: linear.userSpace, stops: newStops)
|
||||
}
|
||||
}
|
||||
|
||||
extension Color {
|
||||
func colorUsingAlphaOnly() -> Color {
|
||||
return Color.black.with(a: Double(a()) / 255.0)
|
||||
}
|
||||
|
||||
func toGrayscaleNoAlpha() -> Color {
|
||||
let grey = Int(0.21 * Double(r()) + 0.72 * Double(g()) + 0.07 * Double(b()))
|
||||
return Color.rgb(r: grey, g: grey, b: grey)
|
||||
}
|
||||
}
|
||||
|
@ -33,7 +33,7 @@ class TextRenderer: NodeRenderer {
|
||||
observe(text.baselineVar)
|
||||
}
|
||||
|
||||
override func doRender(in context: CGContext, force: Bool, opacity: Double, useAlphaOnly: Bool = false) {
|
||||
override func doRender(in context: CGContext, force: Bool, opacity: Double, coloringMode: ColoringMode = .rgb) {
|
||||
guard let text = text else {
|
||||
return
|
||||
}
|
||||
|
@ -34,7 +34,7 @@ open class SVGParser {
|
||||
}
|
||||
|
||||
let availableStyleAttributes = ["stroke", "stroke-width", "stroke-opacity", "stroke-dasharray", "stroke-dashoffset", "stroke-linecap", "stroke-linejoin", "stroke-miterlimit",
|
||||
"fill", "fill-rule", "fill-opacity", "clip-path",
|
||||
"fill", "fill-rule", "fill-opacity", "clip-path", "mask",
|
||||
"opacity", "color", "stop-color", "stop-opacity",
|
||||
"font-family", "font-size", "font-weight", "text-anchor",
|
||||
"visibility"]
|
||||
@ -262,31 +262,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), 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: styleAttributes), 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), 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: styleAttributes), 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), 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: styleAttributes), 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), 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: styleAttributes), 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), 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: styleAttributes), 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), 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: styleAttributes), 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), 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: styleAttributes), tag: getTag(element))
|
||||
}
|
||||
case "image":
|
||||
return parseImage(node, opacity: getOpacity(styleAttributes), pos: position, clip: getClipPath(styleAttributes, locus: nil))
|
||||
@ -339,29 +339,25 @@ open class SVGParser {
|
||||
var groupNodes: [Node] = []
|
||||
let style = getStyleAttributes(groupStyle, element: element)
|
||||
let position = getPosition(element)
|
||||
var mask: TransformedLocus?
|
||||
var mask: Shape?
|
||||
if let maskId = element.allAttributes["mask"]?.text
|
||||
.replacingOccurrences(of: "url(#", with: "")
|
||||
.replacingOccurrences(of: ")", with: "") {
|
||||
let maskShape = defMasks[maskId]
|
||||
mask = TransformedLocus(locus: maskShape!.form, transform: maskShape!.place)
|
||||
mask = defMasks[maskId]
|
||||
}
|
||||
group.children.forEach { child in
|
||||
if let node = parseNode(child, groupStyle: style) {
|
||||
groupNodes.append(node)
|
||||
}
|
||||
}
|
||||
return Group(contents: groupNodes, place: position, clip: mask, tag: getTag(element))
|
||||
return Group(contents: groupNodes, place: position, mask: mask, tag: getTag(element))
|
||||
}
|
||||
|
||||
fileprivate func getMask(mask: String) -> Locus? {
|
||||
if let maskIdenitifierMatcher = SVGParserRegexHelper.getMaskIdenitifierMatcher() {
|
||||
let fullRange = NSRange(location: 0, length: mask.count)
|
||||
if let match = maskIdenitifierMatcher.firstMatch(in: mask, options: .reportCompletion, range: fullRange), let maskReferenceNode = self.defMasks[(mask as NSString).substring(with: match.range(at: 1))] {
|
||||
return maskReferenceNode.form
|
||||
}
|
||||
fileprivate func getMask(styleAttributes: [String: String]) -> Shape? {
|
||||
guard let mask = styleAttributes["mask"], let id = parseIdFromUrl(mask) else {
|
||||
return .none
|
||||
}
|
||||
return .none
|
||||
return defMasks[id]
|
||||
}
|
||||
|
||||
fileprivate func getPosition(_ element: SWXMLHash.XMLElement) -> Transform {
|
||||
@ -994,12 +990,8 @@ open class SVGParser {
|
||||
if let line = stroke {
|
||||
shape.stroke = line
|
||||
}
|
||||
if let maskIdenitifierMatcher = SVGParserRegexHelper.getMaskIdenitifierMatcher() {
|
||||
let fullRange = NSRange(location: 0, length: mask.count)
|
||||
if let match = maskIdenitifierMatcher.firstMatch(in: mask, options: .reportCompletion, range: fullRange), let maskReferenceNode = self.defMasks[(mask as NSString).substring(with: match.range(at: 1))] {
|
||||
shape.clip = maskReferenceNode.form
|
||||
shape.fill = .none
|
||||
}
|
||||
if let id = parseIdFromUrl(mask), let mask = defMasks[id] {
|
||||
shape.mask = mask
|
||||
}
|
||||
return shape
|
||||
}
|
||||
@ -1112,9 +1104,6 @@ open class SVGParser {
|
||||
}
|
||||
|
||||
fileprivate func parseMask(_ mask: XMLIndexer) -> Shape? {
|
||||
guard let element = mask.element else {
|
||||
return .none
|
||||
}
|
||||
var node: Node?
|
||||
mask.children.forEach { indexer in
|
||||
let position = getPosition(indexer.element!)
|
||||
@ -1127,22 +1116,8 @@ open class SVGParser {
|
||||
guard let shape = node as? Shape else {
|
||||
return .none
|
||||
}
|
||||
let maskShape: Shape
|
||||
if let circle = shape.form as? Circle {
|
||||
maskShape = Shape(form: circle.arc(shift: 0, extent: degreesToRadians(360)), tag: getTag(element))
|
||||
} else {
|
||||
maskShape = Shape(form: shape.form, place: node!.place, tag: getTag(element))
|
||||
}
|
||||
let maskStyleAttributes = getStyleAttributes([:], element: element)
|
||||
maskShape.fill = getFillColor(maskStyleAttributes)
|
||||
|
||||
if let id = mask.element?.allAttributes["id"]?.text {
|
||||
maskShape.place = node!.place
|
||||
defMasks[id] = maskShape
|
||||
return .none
|
||||
}
|
||||
|
||||
return maskShape
|
||||
return shape
|
||||
}
|
||||
|
||||
fileprivate func parseLinearGradient(_ gradient: XMLIndexer, groupStyle: [String: String] = [:]) -> Fill? {
|
||||
|
Loading…
Reference in New Issue
Block a user