1
1
mirror of https://github.com/exyte/Macaw.git synced 2024-11-11 01:42:35 +03:00

Merge pull request #194 from exyte/bug/fix-complex-transform

Bug/fix complex transform
This commit is contained in:
Yuriy Kashnikov 2017-10-09 17:35:31 +07:00 committed by GitHub
commit 5b13b90311
2 changed files with 28 additions and 5 deletions

View File

@ -12,8 +12,16 @@ class MacawSVGTests: XCTestCase {
// Put teardown code here. This method is called after the invocation of each test method in the class.
super.tearDown()
}
func testTextBasicTransform() {
let referenceContent = "<svg xmlns=\"http://www.w3.org/2000/svg\" xmlns:xlink=\"http://www.w3.org/1999/xlink\" version=\"1.1\" ><g><g transform=\"translate(100,100)\" ><text y=\"0\" x=\"0\" fill=\"black\" transform=\"matrix(0.707106781186548,-0.707106781186547,0.707106781186547,0.707106781186548,0.0,0.0)\" >Point</text></g></g></svg>"
let text1 = Text(text: "Point")
text1.place = Transform(m11: cos(Double.pi/4.0), m12: -sin(Double.pi/4.0), m21: sin(Double.pi/4.0), m22: cos(Double.pi/4.0), dx: 0, dy: 0)
let group1 = Group(contents: [text1])
group1.place = Transform(dx: 100, dy: 100)
let node = Group(contents: [group1])
XCTAssert(SVGSerializer.serialize(node: node) == referenceContent)
}
func testClip() {
let clipReferenceContent = "<svg xmlns=\"http://www.w3.org/2000/svg\" xmlns:xlink=\"http://www.w3.org/1999/xlink\" version=\"1.1\" ><defs><clipPath id=\"clipPath1\"><rect height=\"90\" x=\"10\" y=\"10\" width=\"90\" /></clipPath><clipPath id=\"clipPath2\"><rect height=\"190\" x=\"110\" y=\"110\" width=\"190\" /></clipPath></defs><g><circle r=\"20\" cy=\"20\" cx=\"20\" clip-path=\"url(#clipPath1)\" fill=\"red\"/><circle r=\"20\" cy=\"120\" cx=\"120\" clip-path=\"url(#clipPath2)\" fill=\"green\"/></g></svg>"

View File

@ -53,6 +53,7 @@ open class SVGSerializer {
fileprivate let indentPrefixSymbol = " "
fileprivate let SVGClipPathName = "clipPath"
fileprivate let SVGEpsilon:Double = 0.00001
fileprivate func indentTextWithOffset(_ text: String, _ offset: Int) -> String {
if self.indent != 0 {
@ -73,7 +74,7 @@ open class SVGSerializer {
}
fileprivate func arcToSVG(_ arc: Arc) -> String {
if (arc.shift == 0.0 && abs(arc.extent - Double.pi * 2.0) < 0.00001) {
if (arc.shift == 0.0 && abs(arc.extent - Double.pi * 2.0) < SVGEpsilon) {
return tag(SVGEllipseOpenTag, ["cx":att(arc.ellipse.cx), "cy":att(arc.ellipse.cy), "rx":att(arc.ellipse.rx), "ry":att(arc.ellipse.ry)])
} else {
let rx = arc.ellipse.rx
@ -217,15 +218,29 @@ open class SVGSerializer {
return result
}
fileprivate func isSignificantMatrixTransform(_ t: Transform) -> Bool {
if ([t.m11, t.m12, t.m21, t.m22, t.dx, t.dy].map{ Int($0) } == [1, 0, 0, 1, 0, 0]) {
return false
}
for k in [t.m11, t.m12, t.m21, t.m22, t.dx, t.dy] {
if abs(k) > SVGEpsilon {
return true
}
}
return false
}
fileprivate func transformToSVG(_ shape: Node) -> String {
if ([shape.place.dx, shape.place.dy].map{ Int($0) } != [0, 0]) {
if ([shape.place.m11, shape.place.m12, shape.place.m21, shape.place.m22].map { Int($0) } == [1, 0, 0, 1]) {
return " transform=\"translate(\(Int(shape.place.dx)),\(Int(shape.place.dy)))\" "
} else {
let matrixArgs = [shape.place.m11, shape.place.m12, shape.place.m21, shape.place.m22, shape.place.dx, shape.place.dy].map{ String($0) }.joined(separator: ",")
return " transform=\"matrix(\(matrixArgs))\" "
}
}
if isSignificantMatrixTransform(shape.place) {
let matrixArgs = [shape.place.m11, shape.place.m12, shape.place.m21, shape.place.m22, shape.place.dx, shape.place.dy].map{ String($0) }.joined(separator: ",")
return " transform=\"matrix(\(matrixArgs))\" "
}
return ""
}