経緯
以前CoreText
を使って文字の縁のパスを取得し、それをゴニョゴニョして描画するアプリを作ったのですが、最近arm64対応を行ったところ、表示するサイズによって描画結果がちょっとおかしなことになりました。問題の症状と再現コードを残しておきます。
- Xcode6.4 + iOS8 + iPad Air(Simurator)
再現コード
MyView
でパスを描画しています。
スライダーによってスケール値を変えられるようになっています。
ViewController.swift
import UIKit
class MyView: UIView {
var scale: CGFloat = 1
override func drawRect(rect: CGRect) {
let font = CTFontCreateWithName("HiraKakuProN-W6", 40, nil)
let text = "あ";
var glyph: CGGlyph = 0
var unichar: UniChar = text.utf16[text.utf16.startIndex]
CTFontGetGlyphsForCharacters(font, &unichar, &glyph, 1)
var flip = CGAffineTransformMakeTranslation(10, 50)
flip = CGAffineTransformScale(flip, 1, -1)
let path = CTFontCreatePathForGlyph(font, glyph, &flip)
let c = UIGraphicsGetCurrentContext()
UIColor.blueColor().set()
CGContextScaleCTM(c, scale, scale)
CGContextAddPath(c, path)
//CGContextSetLineWidth(c, 4)
CGContextSetLineCap(c, kCGLineCapRound)
CGContextSetLineJoin(c, kCGLineJoinRound)
CGContextSetLineDash(c, 0, nil, 0)
CGContextStrokePath(c)
}
}
class ViewController: UIViewController {
private var myView: MyView!
override func viewDidLoad() {
super.viewDidLoad()
view.backgroundColor = UIColor.whiteColor()
let slider = UISlider(frame: CGRectMake(10, 30, 400, 0))
slider.sizeToFit()
slider.minimumValue = 1
slider.maximumValue = 10
slider.addTarget(self, action: "didChangeScale:", forControlEvents: .ValueChanged)
view.addSubview(slider)
myView = MyView(frame: CGRectMake(10, 80, 700, 700))
myView.backgroundColor = UIColor.yellowColor()
view.addSubview(myView)
}
func didChangeScale(slider: UISlider) {
myView.scale = CGFloat(slider.value)
println(myView.scale)
myView.setNeedsDisplay()
}
}
実行結果
こんな感じでスケール値によっては文字の一部が欠けるような感じになることがあります。
所感
今のところ64bit環境でのみ再現していることから、CGFloat
がdouble
相当になったときにだけ何か計算結果がおかしな事になり、こうした症状が起きているのかな?と予想していますが、詳しい事は分かりません。
とりあえず駄目元でバグレポート出してみます。
また何か判れば追記します。