gpt4 book ai didi

objective-c - 如何解决由 CALayer 支持的文本中糟糕的文本渲染

转载 作者:太空狗 更新时间:2023-10-30 03:26:48 33 4
gpt4 key购买 nike

我在 NSTextField 中有一些可变文本,它呈现在 CALayer 背景 View 上。由于 CALayer 不支持对其上的任何文本进行文本渲染的子像素别名,因此该文本看起来很垃圾。

一些谷歌搜索揭示了原因,并且该文本必须呈现在不透明的背景上才能启用 SPA。在这种情况下,如果可能的话,渲染到不透明的背景是我想避免的事情。有更好的解决方法吗?

我完全愿意自己将文本渲染成 NSImage,如果这有帮助的话,但我找不到任何确认的报告。

它在 Interface Builder 中看起来非常好,所以我知道 secret 就在这台计算机内部的某个地方,正竭尽全力地想出去。

最佳答案

找到解决方法。看起来,Quartz 中没有任何东西可以在透明背景上渲染带有子像素别名的文本。但是,您可以将文本渲染到屏幕外位图缓冲区,前提是该屏幕外位图缓冲区已以正确的方式创建。此缓冲区的背景必须是不透明的。

我的 View 以前有一个略微透明的 PNG 背景。我本可以简单地让这个背景不透明并毫无问题地渲染它,但是由于这个 View 需要淡入和淡出,它需要 CALayer 支持,所以文本正确渲染一次,然后在没有子像素别名的情况下渲染.

这是我的代码。它看起来非常冗长,如果有人能帮助我减少它,我会很高兴。它假定您有一个名为 _title 的 NSImageView 和一个名为 title 的 NSString。

// Create the attributed string
NSMutableAttributedString *attStr = [[[NSMutableAttributedString alloc] initWithString: title] autorelease];

NSRange strRange = NSMakeRange(0, [attStr length]);
NSFont *font = [NSFont systemFontOfSize:[NSFont systemFontSizeForControlSize: NSSmallControlSize]];

[attStr addAttribute: NSForegroundColorAttributeName value: [NSColor whiteColor] range: strRange];
[attStr addAttribute: NSFontAttributeName value: font range: strRange];

NSMutableParagraphStyle *paraStyle = [[[NSParagraphStyle defaultParagraphStyle] mutableCopy] autorelease];
[paraStyle setAlignment: NSCenterTextAlignment];
[paraStyle setLineBreakMode: NSLineBreakByTruncatingMiddle];
[attStr addAttribute: NSParagraphStyleAttributeName value: paraStyle range: strRange];

// Set up the image context
NSUInteger bytesPerPixel = 4;
NSUInteger bytesPerRow = bytesPerPixel * [_title frame].size.width;
NSUInteger bitsPerComponent = 8;
CGColorSpaceRef colorSpace = CGColorSpaceCreateDeviceRGB();
// These constants are necessary to enable sub-pixel aliasing.
CGBitmapInfo bitmapInfo = kCGImageAlphaPremultipliedFirst | kCGBitmapByteOrder32Host;

// Create the memory buffer to be used as the context's workspace
unsigned char *contextBuffer = malloc([_title frame].size.height * [_title frame].size.width * 4);

CGContextRef context = CGBitmapContextCreate(contextBuffer,
[_title frame].size.width,
[_title frame].size.height,
bitsPerComponent,
bytesPerRow,
colorSpace,
bitmapInfo);


[NSGraphicsContext saveGraphicsState];

[NSGraphicsContext setCurrentContext:[NSGraphicsContext graphicsContextWithGraphicsPort:context flipped:NO]];


CGContextSetFillColorWithColor(context, CGColorGetConstantColor(kCGColorBlack));
CGRect rectangle = CGRectMake(0, 0, [_title frame].size.width,[_title frame].size.height);
CGContextAddRect(context, rectangle);
CGContextFillPath(context);

CTLineRef line = CTLineCreateWithAttributedString((CFAttributedStringRef)attStr);

CGContextSetTextPosition(context, 10.0, 10.0);
CTLineDraw(line, context);
CFRelease(line);

// Create a data provider from the context buffer in memory
CGDataProviderRef dataProvider = CGDataProviderCreateWithData(NULL, contextBuffer, bytesPerRow * [_title frame].size.height, NULL);

// Create an image from the data provider
CGImageRef imageRef = CGImageCreate ([_title frame].size.width,
[_title frame].size.height,
bitsPerComponent,
bytesPerPixel * 8,
bytesPerRow,
colorSpace,
bitmapInfo,
dataProvider,
NULL,
false,
kCGRenderingIntentDefault
);

// Turn it into an NSImage
NSImage *newImage = [[[NSImage alloc] initWithCGImage:imageRef size: NSZeroSize] autorelease];

CGDataProviderRelease(dataProvider);
CGColorSpaceRelease(colorSpace);
CGContextRelease(context);
CGImageRelease(imageRef);

free(contextBuffer);

[NSGraphicsContext restoreGraphicsState];

[_title setImage: newImage];

关于objective-c - 如何解决由 CALayer 支持的文本中糟糕的文本渲染,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/4293487/

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