gpt4 book ai didi

macos - CATextLayer 过早地被光栅化并且变得模糊

转载 作者:行者123 更新时间:2023-12-01 05:21:30 26 4
gpt4 key购买 nike

我在使用 CATextLayer 时遇到了一些麻烦,这可能是我造成的,但我没有找到有关此主题的任何帮助。我在 OS X 上(在 iOS 上应该是一样的)。

我创建了一个比例因子 > 1 的 CATextLayer 图层,我得到的是一个模糊的文本。我认为,在应用比例之前,该图层已被栅格化。这是预期的行为吗?我希望它不是,因为它只是没有意义...... CAShapeLayer 在应用其变换矩阵之后被光栅化,为什么 CATextLayer 应该不同?

万一我做错了什么......这是什么?

CATextLayer *layer = [CATextLayer layer];
layer.string = @"I like what I am doing";
layer.font = (__bridge CFTypeRef)[NSFont systemFontOfSize:24];
layer.fontSize = 24;
layer.anchorPoint = CGPointZero;
layer.frame = CGRectMake(0, 0, 400, 100);
layer.foregroundColor = [NSColor blackColor].CGColor;
layer.transform = CATransform3DMakeScale(2., 2., 1.);
layer.shouldRasterize = NO;
[self.layer addSublayer:layer];

我目前使用的解决方案是将图层的 contentsScale 属性设置为比例因子。问题是这个解决方案不能缩放:如果任何父层的比例因子发生变化,那么 contentsScale 也应该更新。我应该编写代码来遍历层树以更新所有 CATextLayers 的 contentsScale 属性......这不完全是我想要做的。

另一个解决方案,这不是真正的解决方案,是将文本转换为形状并使用 CAShapeLayer。但后来我没有看到拥有 CATextLayers 的意义。

CALayer 的自定义子类可以帮助解决这个问题吗?

编辑:在应用其变换矩阵之后,即使 CAGradientLayer 也能够呈现其内容,如 CAShapeLayer。有人可以解释这怎么可能吗?

编辑 2:我的猜测是路径和渐变被渲染为 OpenGL 显示列表,因此它们被 OpenGL 本身以屏幕上的实际大小光栅化。文本由 Core Animation 光栅化,因此它们是 OpenGL 的位图。

我想我暂时会使用 contentsScale 解决方案。也许,将来,我会将文本转换为形状。为了用很少的工作获得最佳结果,这是我现在使用的代码:
[CATransaction setDisableActions:YES];

CGFloat contentsScale = ceilf(scaleOfParentLayer);
// _scalableTextLayer is a CATextLayer
_scalableTextLayer.contentsScale = contentsScale;
[_scalableTextLayer displayIfNeeded];

[CATransaction setDisableActions:NO];

最佳答案

在尝试了所有方法之后,我现在使用的解决方案是 CALayer 的自定义子类。我根本不使用 CATextLayer。

我用这个自定义的 setter 方法覆盖了 contentsScale 属性:

- (void)setContentsScale:(CGFloat)cs
{
CGFloat scale = MAX(ceilf(cs), 1.); // never less than 1, always integer
if (scale != self.contentsScale) {
[super setContentsScale:scale];
[self setNeedsDisplay];
}
}

属性的值总是四舍五入到上整数值。当舍入值发生变化时,必须重新绘制图层。

我的 CALayer 子类的显示方法创建了一个位图图像,其大小乘以 contentScale 因子和屏幕比例因子。
- (void)display
{
CGFloat scale = self.contentsScale * [MyUtils screenScale];

CGFloat width = self.bounds.size.width * scale;
CGFloat height = self.bounds.size.height * scale;

CGContextRef bitmapContext = [MyUtils createBitmapContextWithSize:CGSizeMake(width, height)];

CGContextScaleCTM(bitmapContext, scale, scale);
CGContextSetShouldSmoothFonts(bitmapContext, 0);

CTLineRef line = CTLineCreateWithAttributedString((__bridge CFAttributedStringRef)(_text));

CGContextSetTextPosition(bitmapContext, 0., self.bounds.size.height-_ascender);
CTLineDraw(line, bitmapContext);
CFRelease(line);

CGImageRef image = CGBitmapContextCreateImage(bitmapContext);
self.contents = (__bridge id)(image);
CGImageRelease(image);

CGContextRelease(bitmapContext);
}

当我更改层次结构根层的比例因子时,我会在所有文本层上循环并将 contentsScale 属性设置为相同的因子。仅当比例因子的舍入值发生变化时才调用 display 方法(即,如果以前的值是 1.6,现在我设置为 1.7,则没有任何 react 。但如果新值是 2.1,则重新显示图层)。

重绘速度方面的成本很小。我的测试是连续更改第 3 代上 40 个文本层的层次结构的比例因子。 iPad。它的作用就像黄油。

关于macos - CATextLayer 过早地被光栅化并且变得模糊,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/16355540/

26 4 0
Copyright 2021 - 2024 cfsdn All Rights Reserved 蜀ICP备2022000587号
广告合作:1813099741@qq.com 6ren.com