Xcode 8.0が登場しました。
旧プロジェクトをXcode 8.0で開くと、Swift 3.0(あるいはSwift 2.4)に変換するよう促すダイアログが出現しました。
CoreGraphicsコードをSwift 3.0への自動コンバートにかけたところ、変換されない部分が残りました。
let pathRef = CGMutablePath()
CGPathMoveToPoint(pathRef, nil, 20, 0)
CGPathAddLineToPoint(pathRef, nil, 200, 0)
CGPathAddCurveToPoint(pathRef, nil, 205.523, 0, 210, 4.435, 210, 10)
CGPathAddLineToPoint(pathRef, nil, 210, 122)
CGPathAddCurveToPoint(pathRef, nil, 210, 127.565, 205.523, 132, 200, 132)
CGPathAddLineToPoint(pathRef, nil, 10, 132)
CGPathAddCurveToPoint(pathRef, nil, 4.477, 132, -0, 127.565, -0, 122)
CGPathAddLineToPoint(pathRef, nil, -0, 20)
CGPathAddCurveToPoint(pathRef, nil, -0, 9.087, 9.081, 0, 20, 0)
pathRef.closeSubpath()
変換後、このようなコードになったのですが最終的には
let pathRef = CGMutablePath()
pathRef.move(to: CGPoint(x: 20, y: 0))
pathRef.addLine(to: CGPoint(x: 200, y: 0))
pathRef.addCurve(to: CGPoint(x: 210, y: 10), control1: CGPoint(x: 205.523, y: 0), control2: CGPoint(x: 210, y: 4.435))
pathRef.addLine(to: CGPoint(x: 210, y: 122))
pathRef.addCurve(to: CGPoint(x: 200, y: 132), control1: CGPoint(x: 210, y: 127.565), control2: CGPoint(x: 205.523, y: 132))
pathRef.addLine(to: CGPoint(x: 10, y: 132))
pathRef.addCurve(to: CGPoint(x: -0, y: 122), control1: CGPoint(x: 4.477, y: 132), control2: CGPoint(x: -0, y: 127.565))
pathRef.addLine(to: CGPoint(x: -0, y: 20))
pathRef.addCurve(to: CGPoint(x: 20, y: 0), control1: CGPoint(x: -0, y: 9.087), control2: CGPoint(x: 9.081, y: 0))
pathRef.closeSubpath()
と変換したい。
文字列の処理がやりやすいのはなにかしらと考えて、急遽Rubyを学ぶことにしました。
文字列操作とファイル操作の基本的なやりかたを知ったので、以下の変換プログラム converter.rbを書きました。
CGPathMoveToPoint(pathRef, nil, 20, 0)
を
pathRef.move(to: CGPoint(x: 20, y: 0))
CGPathAddLineToPoint(pathRef, nil, 200, 0)
を
pathRef.addLine(to: CGPoint(x: 200, y: 0))
CGPathAddCurveToPoint(pathRef, nil, 205.523, 0, 210, 4.435, 210, 10)
を
pathRef.addCurve(to: CGPoint(x: 210, y: 10), control1: CGPoint(x: 205.523, y: 0), control2: CGPoint(x: 210, y: 4.435))
と変換するものです。
converter.rb
class Converter
def convert()
loop do
print "Filename? "
fileName = gets.chomp
if fileName == ""
break
end
# Backup
from = fileName
to = "_" + fileName + ".bak"
copy(from, to)
# Conversion
array = []
File.open(fileName) do |file|
file.each_line do |line|
line = convertCoreGraphicsCode(line)
array.push(line)
end
end
# Writing
File.open(fileName, "w") do |file|
file.puts(array)
puts fileName + " 変換終了"
end
end
end
def copy(from, to)
File.open(from) do |input|
File.open(to, "w") do |output|
output.write(input.read)
end
end
end
def convertCoreGraphicsCode(line)
if line.include?("CGPathMoveToPoint")
return convertMoveToPoint(line)
elsif line.include?("CGPathAddLineToPoint")
return convertAddLineToPoint(line)
elsif line.include?("CGPathAddCurveToPoint")
return convertAddCurveToPoint(line)
else
return line
end
end
# CGPathMoveToPoint(clipPath, nil, 240, 122)
# to
# clipPath.move(to: CGPoint(x: 240, y: 122))
def convertMoveToPoint(line)
# indentを取得
index = line.index("CGPathMoveToPoint")
indent = line[0, index]
# path名を含むかたまりを取得("CGPathMoveToPoint(clipPath,")
pathStr = line.match(/CGPathMoveToPoint\(\w+,/)
# path名を取得("clipPath")
pathName = pathStr[0].sub("CGPathMoveToPoint\(", "").chop
# puts pathName
# 数値
figuresStr = line.sub(/CGPathMoveToPoint\(\w+, nil,/, "").chomp.chop.lstrip
figuresStr = " " + figuresStr
figures = figuresStr.split(",")
# puts figures
dstStr = "%s%s.move(to: CGPoint(x:%s, y:%s))" % [indent, pathName, figures[0], figures[1]]
# puts dstStr
return dstStr
end
# CGPathAddLineToPoint(clipPath, nil, 240, 122)
# to
# clipPath.addLine(to: CGPoint(x: 240, y: 122))
def convertAddLineToPoint(line)
# indentを取得
index = line.index("CGPathAddLineToPoint")
indent = line[0, index]
# path名を含むかたまりを取得("CGPathAddLineToPoint(clipPath,")
pathStr = line.match(/CGPathAddLineToPoint\(\w+,/)
# path名を取得("clipPath")
pathName = pathStr[0].sub("CGPathAddLineToPoint\(", "").chop
# puts pathName
# 数値
figuresStr = line.sub(/CGPathAddLineToPoint\(\w+, nil,/, "").chomp.chop.lstrip
figuresStr = " " + figuresStr
figures = figuresStr.split(",")
# puts figures
dstStr = "%s%s.addLine(to: CGPoint(x:%s, y:%s))" % [indent, pathName, figures[0], figures[1]]
# puts dstStr
return dstStr
end
# CGPathAddCurveToPoint(pathRef2, nil, 4.477, 132, 0, 127.565, 0, 122)
# to
# pathRef2.addCurve(to: CGPoint(x: 0, y: 122), control1: CGPoint(x: 4.477, y: 132), control2: CGPoint(x: 0, y: 127.565))
def convertAddCurveToPoint(line)
# indentを取得
index = line.index("CGPathAddCurveToPoint")
indent = line[0, index]
# path名を含むかたまりを取得("CGPathAddCurveToPoint(pathRef2,")
pathStr = line.match(/CGPathAddCurveToPoint\(\w+,/)
# path名を取得("pathRef2")
pathName = pathStr[0].sub("CGPathAddCurveToPoint\(", "").chop
# puts pathName
# 数値を取得
figuresStr = line.sub(/CGPathAddCurveToPoint\(\w+, nil,/, "").chomp.chop.lstrip
figuresStr = " " + figuresStr
figures = figuresStr.split(",")
# puts figures
dstStr = "%s%s.addCurve(to: CGPoint(x:%s, y:%s), control1: CGPoint(x:%s, y:%s), control2: CGPoint(x:%s, y:%s))" % [indent, pathName, figures[4], figures[5], figures[0], figures[1], figures[2], figures[3]]
# puts dstStr
return dstStr
end
end
converter = Converter.new
converter.convert()
変換したいswiftファイルがあるフォルダに、converter.rbをおき、Terminalでそのフォルダへ移動した後、
ruby converter.rb
と入力するとプログラムが実行されます。
実行すると、
FileName?
とたずねられるので、そこで変換したいファイル名を入力すると変換が行われます。
(このさい、”_元ファイル名.bak”というバックアップファイルも作成します。)
ファイル名を入力せずにreturnキーを押すと、プログラムは終了します。
関連
Autodesk Graphic(旧iDraw)はCore Graphicsのコードを生成できる – nackpan Blog