CTFontDrawGlyphs绘制编辑时间不正确的位置
:我代替我的原代码存根与自足版本CTFontDrawGlyphs绘制编辑时间不正确的位置
我使用Quartz2D画音乐符号的CGContext上。我正在使用Swift 4在Playground中做这件事。
音符由用于音符的单个CGGlyph和用于茎的线原语组成。字形取自音乐字体“bravura”。 书写笔字形的x位置正好位于其左边缘。茎必须完全对齐这个原点,因此它的X位置必须是纸头的X位置+茎的厚度/ 2.
我有一个函数,它将CGFloat作为x位置并绘制字形和干到CGContext。当x的值是像30.0这样的四舍五入值时,这可以很好地工作。然而,当值就像是30.9的分数,茎被错位:
很明显,该线正确绘制,但字形忽略CGFloat的小数部分。当我将x值进一步提高到31.0时,两个部分再次同步。
这里是简化代码,这会在你的XCode9游乐场工作:
import PlaygroundSupport import Cocoa
let fontSize = CGFloat(64)
// uncomment the next paragraph if you have added the "Bravura" Font to the ressources folder
/*
let fontURL = Bundle.main.url(forResource: "Bravura", withExtension: "otf")
CTFontManagerRegisterFontsForURL(fontURL! as CFURL, CTFontManagerScope.process, nil)
var font = CTFontCreateWithName("Bravura" as CFString, fontSize, nil)
*/
// comment out the next line if you use Bravura
var font = CTFontCreateWithName("Helvetica" as CFString, fontSize, nil)
func drawAtXPosition(_ posX: CGFloat, inContext context: CGContext) {
// draw font glyph (notehead)
var glyph = CTFontGetGlyphWithName(font, "uniE0A3" as CFString)
var notePosition = CGPoint(x: posX, y: 100)
CTFontDrawGlyphs(font, &glyph, ¬ePosition, 1, context)
// draw line (note stem)
let stemThickness = CGFloat(fontSize/4*0.12)
let x: CGFloat = posX + stemThickness/2
let y: CGFloat = 100 - (0.168 * fontSize/4)
let stemBegin = CGPoint(x:x, y:y)
let stemEnd = CGPoint(x:x, y: y - (3.5 * fontSize/4))
context.setLineWidth(stemThickness)
context.strokeLineSegments(between: [stemBegin, stemEnd])
}
class MyView: NSView {
override func draw(_ rect: CGRect) {
let context = NSGraphicsContext.current!.cgContext
context.setStrokeColor(CGColor.black)
context.setFillColor(CGColor.black)
drawAtXPosition(100, inContext: context) // this draws as expected
drawAtXPosition(200.99, inContext: context) // here the glyph is drawn at x=200, while the line is correctly drawn at 200.99
}
}
var myView = MyView(frame: CGRect(x: 0, y: 0, width: 500, height: 200))
let myViewController = NSViewController()
myViewController.view = myView
PlaygroundPage.current.liveView = myViewController
您可以从下载音乐字体 “炫耀的表现” ......
https://www.smufl.org/fonts/
...但我重写了代码,因此它默认使用Helvetica,这也适用于演示。
作为我原始代码中的解决方法,我在将x值传递给绘图函数之前实现了Foundation的.rounded()方法。这是有效的,但恐怕在小字号(整个代码的写入使得所有的字体都是围绕字体大小)时,这种不准确将会引起人们的注意。
我遇到了CGContext的setShouldSubpixelPositionFonts和setAllowsFontSubpixelPositioning方法,但将它们设置为true并没有做任何改变。
那么,有没有一种方法可以像原始图一样精确绘制字体对象(必须有一个)?或者,我担心将CGFloats四舍五入到Ints是不合理的?
回答:
无尽的挖掘后,我找到了解决办法:
这是不够的设定
context.setShouldSubpixelPositionFonts(true)
您还可以设置
context.setShouldSubpixelQuantizeFonts(false)
,因为后者似乎超越了前者。
以上是 CTFontDrawGlyphs绘制编辑时间不正确的位置 的全部内容, 来源链接: utcz.com/qa/258343.html