CTFontCreatePathForGlyph 创建的文本路径被翻转
Text path created by CTFontCreatePathForGlyph is flipped
我正在尝试实现在 CAShapeLayer
中绘制文本。为此,我需要从文本创建 UIBezierPath
。基于 应该一切正常,但遗憾的是我找不到问题所在。
CTFontCreatePathForGlyph(runFont, glyph, nil)
创建的路径从反面绘制了字母。
代码转换为Swift4
func initializeTextLayer() {
let fontName: CFString = "Noteworthy-Light" as CFString
let letters = CGMutablePath()
let font = CTFontCreateWithName(fontName, 50, nil)
let attrString = NSAttributedString(string: "TEST", attributes: [kCTFontAttributeName as NSAttributedStringKey : font])
let line = CTLineCreateWithAttributedString(attrString)
let runArray = CTLineGetGlyphRuns(line)
for runIndex in 0..<CFArrayGetCount(runArray) {
let run : CTRun = unsafeBitCast(CFArrayGetValueAtIndex(runArray, runIndex), to: CTRun.self)
let dictRef : CFDictionary = CTRunGetAttributes(run)
let dict : NSDictionary = dictRef as NSDictionary
let runFont = dict[kCTFontAttributeName as String] as! CTFont
for runGlyphIndex in 0..<CTRunGetGlyphCount(run) {
let thisGlyphRange = CFRangeMake(runGlyphIndex, 1)
var glyph = CGGlyph()
var position = CGPoint.zero
CTRunGetGlyphs(run, thisGlyphRange, &glyph)
CTRunGetPositions(run, thisGlyphRange, &position)
let letter = CTFontCreatePathForGlyph(runFont, glyph, nil)
let t = CGAffineTransform(translationX: position.x, y: position.y)
if let letter = letter {
letters.addPath(letter, transform: t)
}
}
}
let path = UIBezierPath()
path.move(to: CGPoint.zero)
path.append(UIBezierPath(cgPath: letters))
let pathLayer = CAShapeLayer()
pathLayer.path = path.cgPath
self.layer.addSublayer(pathLayer)
}
我能做些什么来镜像它?我找到了一些东西 mirror path 但没有得到任何结果。
正如@Grimxn 所说:我必须进行缩放和平移。
在自定义层的超级视图中draw(in rect: CGRect)
添加了以下代码行。
func updateTextLayerPath() {
if let pth = popupLayer.textLayerPath {
UIColor.red.setStroke()
// glyph path is inverted, so flip vertically
let flipY = CGAffineTransform(scaleX: 1, y: -1.0)
// glyph path may be offset on the x coord, and by the height (because it's flipped)
let translate = CGAffineTransform(translationX: -pth.bounds.origin.x, y: pth.bounds.size.height + pth.bounds.origin.y)
// apply the transforms
pth.apply(flipY)
pth.apply(translate)
// stroke the path
pth.stroke()
}
}
textLayerPath
是自定义 CAShapeLayer
中存储的 属性,它在超级视图的 layoutSubviews
中获取更新。
希望这对其他将要面对这个问题的人有所帮助。
您还可以向 CTFontCreatePathForGlyph
方法提供转换以翻转返回的路径。
// Mirror the glyph about the x-axis so it not upside down
var flipVertically = CGAffineTransform(scaleX: 1, y: -1)
let cgPath = CTFontCreatePathForGlyph(font, glyph, &flipVertically)
我正在尝试实现在 CAShapeLayer
中绘制文本。为此,我需要从文本创建 UIBezierPath
。基于
CTFontCreatePathForGlyph(runFont, glyph, nil)
创建的路径从反面绘制了字母。
代码转换为Swift4
func initializeTextLayer() {
let fontName: CFString = "Noteworthy-Light" as CFString
let letters = CGMutablePath()
let font = CTFontCreateWithName(fontName, 50, nil)
let attrString = NSAttributedString(string: "TEST", attributes: [kCTFontAttributeName as NSAttributedStringKey : font])
let line = CTLineCreateWithAttributedString(attrString)
let runArray = CTLineGetGlyphRuns(line)
for runIndex in 0..<CFArrayGetCount(runArray) {
let run : CTRun = unsafeBitCast(CFArrayGetValueAtIndex(runArray, runIndex), to: CTRun.self)
let dictRef : CFDictionary = CTRunGetAttributes(run)
let dict : NSDictionary = dictRef as NSDictionary
let runFont = dict[kCTFontAttributeName as String] as! CTFont
for runGlyphIndex in 0..<CTRunGetGlyphCount(run) {
let thisGlyphRange = CFRangeMake(runGlyphIndex, 1)
var glyph = CGGlyph()
var position = CGPoint.zero
CTRunGetGlyphs(run, thisGlyphRange, &glyph)
CTRunGetPositions(run, thisGlyphRange, &position)
let letter = CTFontCreatePathForGlyph(runFont, glyph, nil)
let t = CGAffineTransform(translationX: position.x, y: position.y)
if let letter = letter {
letters.addPath(letter, transform: t)
}
}
}
let path = UIBezierPath()
path.move(to: CGPoint.zero)
path.append(UIBezierPath(cgPath: letters))
let pathLayer = CAShapeLayer()
pathLayer.path = path.cgPath
self.layer.addSublayer(pathLayer)
}
我能做些什么来镜像它?我找到了一些东西 mirror path 但没有得到任何结果。
正如@Grimxn 所说:我必须进行缩放和平移。
在自定义层的超级视图中draw(in rect: CGRect)
添加了以下代码行。
func updateTextLayerPath() {
if let pth = popupLayer.textLayerPath {
UIColor.red.setStroke()
// glyph path is inverted, so flip vertically
let flipY = CGAffineTransform(scaleX: 1, y: -1.0)
// glyph path may be offset on the x coord, and by the height (because it's flipped)
let translate = CGAffineTransform(translationX: -pth.bounds.origin.x, y: pth.bounds.size.height + pth.bounds.origin.y)
// apply the transforms
pth.apply(flipY)
pth.apply(translate)
// stroke the path
pth.stroke()
}
}
textLayerPath
是自定义 CAShapeLayer
中存储的 属性,它在超级视图的 layoutSubviews
中获取更新。
希望这对其他将要面对这个问题的人有所帮助。
您还可以向 CTFontCreatePathForGlyph
方法提供转换以翻转返回的路径。
// Mirror the glyph about the x-axis so it not upside down
var flipVertically = CGAffineTransform(scaleX: 1, y: -1)
let cgPath = CTFontCreatePathForGlyph(font, glyph, &flipVertically)