Ugly looking text when drawing NSAttributedString in CGContext

北城余情 提交于 2019-11-27 16:20:28

问题


I want to display strings inside CoreAnimation layers, but unfortunately CATextLayer is not enough, mostly because it's difficult to use when using constraints and you want to wrap the text.

I am using NSLayoutManager, using the following code (PyObjC):

NSGraphicsContext.saveGraphicsState()

# THIS SOLVES THIS ISSUE
CGContextSetShouldSmoothFonts(ctx, False)

graphics = NSGraphicsContext.graphicsContextWithGraphicsPort_flipped_(ctx, True)
NSGraphicsContext.setCurrentContext_(graphics)

height = size.height
xform = NSAffineTransform.transform();
xform.translateXBy_yBy_(0.0, height)
xform.scaleXBy_yBy_(1.0, -1.0)
xform.concat()

self.textContainer.setContainerSize_(size)

glyphRange = self.layoutManager.glyphRangeForTextContainer_(self.textContainer)

self.layoutManager.drawBackgroundForGlyphRange_atPoint_(glyphRange, topLeft)
self.layoutManager.drawGlyphsForGlyphRange_atPoint_(glyphRange, topLeft)

NSGraphicsContext.restoreGraphicsState()

This is all fine and working, but the only issue is that it produces bad-looking text (although it is antialised).

Here's the CATextLayer version:

And here's the NSLayoutManager version:

Anything I'm missing?


回答1:


I'm answering this because the coretext-dev archives are not searchable, and Aki Inoue from Apple just answered my question:

Since CALayer cannot represent subpixel color (aka font smoothing), you need to disable it. I believe CATextLayer does it by default.

Do CGContextSetShouldSmoothFonts(context, false).

Thanks, Aki!

Another comment by Milen Dzhumerov:

I don't believe this is accurate. We're drawing text into CALayers with subpixel anti-aliasing. You just have to make sure that you've drawn behind the text before drawing the text itself. See http://www.cocoabuilder.com/archive/message/cocoa/2008/3/28/202581 for references.

Milen is correct, in case you know the background colour beforehand, you can do:

CGContextSetRGBFillColor(ctx, r, g, b, a)
CGContextFillRect(ctx, (topLeft, size))
CGContextSetShouldSmoothFonts(ctx, True)

And you get pretty sub-pixel anti-aliased text. However, if you don't know the background colour, you need to turn off font smoothing or you'll get garbled results.



来源:https://stackoverflow.com/questions/715750/ugly-looking-text-when-drawing-nsattributedstring-in-cgcontext

易学教程内所有资源均来自网络或用户发布的内容,如有违反法律规定的内容欢迎反馈
该文章没有解决你所遇到的问题?点击提问,说说你的问题,让更多的人一起探讨吧!