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を学ぶことにしました。
- ドットインストールの一連の講座。
Ruby入門 (全26回) – プログラミングならドットインストール -
正規表現。
Ruby 正規表現の使い方 – Qiita -
たのしい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