- android - RelativeLayout 背景可绘制重叠内容
- android - 如何链接 cpufeatures lib 以获取 native android 库?
- java - OnItemClickListener 不起作用,但 OnLongItemClickListener 在自定义 ListView 中起作用
- java - Android 文件转字符串
我有与 question 相关的问题
我设置了 contentsScale 之后,文本看起来不错,但如果我应用 3d 旋转变换,文本就会变得模糊。
图片 here
初始化代码
// init text
textLayer_ = [CATextLayer layer];
…
textLayer_.contentsScale = [[UIScreen mainScreen] scale];
// init body path
pathLayer_ = [CAShapeLayer layer];
…
[pathLayer_ addSublayer:textLayer_];
旋转代码
// make the mirror
pathLayer_.transform = CATransform3DRotate(pathLayer_.transform, M_PI, 0, 1, 0);
textLayer_.transform = CATransform3DRotate(textLayer_.transform, M_PI, 0, 1, 0);
[textLayer_ setNeedsDisplay];
为了测试,我在初始化期间分别旋转了文本。
// init text
textLayer_ = [CATextLayer layer];
…
textLayer_.transform = CATransform3DRotate(textLayer_.transform, M_PI, 0, 1, 0);
textLayer_.contentsScale = [[UIScreen mainScreen] scale];
文本可以旋转并保持清晰
图片 here
最佳答案
这里可能发生的事情是它决定必须将 textLayer 渲染为像素。注意 shouldRasterize in the CALayer Class Reference 的警告:
When the value of this property is NO, the layer is composited directly into the destination whenever possible. The layer may still be rasterized prior to compositing if certain features of the compositing model (such as the inclusion of filters) require it.
因此,CATextLayer 可能会突然决定栅格化。如果它是旋转层的子层,它决定栅格化。所以,不要让这种情况发生。
这会将您带回导致文本颠倒的解决方案。您可以通过关闭文本层上的 doubleSided
来防止这种情况。您的标牌现在在远端是空白的,因此添加第二个文本层,相对于第一个旋转 180 度。
声明两个文本层:
@property (retain) CAShapeLayer *pathLayer;
@property (retain) CATextLayer *textLayerFront;
@property (retain) CATextLayer *textLayerBack;
然后,将它们初始化为单面,背面层旋转180度:
CAShapeLayer *pathLayer = [CAShapeLayer layer];
// Also need to store a UIBezierPath in the pathLayer.
CATextLayer *textLayerFront = [CATextLayer layer];
textLayerFront.doubleSided = NO;
textLayerFront.string = @"Front";
textLayerFront.contentsScale = [[UIScreen mainScreen] scale];
CATextLayer *textLayerBack = [CATextLayer layer];
textLayerBack.doubleSided = NO;
// Eventually both sides will have the same text, but for demonstration purposes we will label them differently.
textLayerBack.string = @"Back";
// Rotate the back layer 180 degrees relative to the front layer.
textLayerBack.transform = CATransform3DRotate(textLayerBack.transform, M_PI, 0, 1, 0);
textLayerBack.contentsScale = [[UIScreen mainScreen] scale];
// Make all the layers siblings. These means they must all be rotated independently of each other.
// The layers can flicker if their Z position is close to the background, so move them forward.
// This will not work if the main layer has a perspective transform on it.
textLayerFront.zPosition = 256;
textLayerBack.zPosition = 256;
// It would make sense to make the text layers siblings of the path layer, but this seems to mean they get pre-rendered, blurring them.
[self.layer addSublayer:pathLayer];
[self.layer addSublayer:textLayerBack];
[self.layer addSublayer:textLayerFront];
// Store the layers constructed at this time for later use.
[self setTextLayerFront:textLayerFront];
[self setTextLayerBack:textLayerBack];
[self setPathLayer:pathLayer];
然后您可以旋转图层。只要您始终旋转相同的量,它们就会显示正确。
CGFloat angle = M_PI;
self.pathLayer.transform = CATransform3DRotate(self.pathLayer.transform, angle, 0, 1, 0);
self.textLayerFront.transform = CATransform3DRotate(self.textLayerFront.transform, angle, 0, 1, 0);
self.textLayerBack.transform = CATransform3DRotate(self.textLayerBack.transform, angle, 0, 1, 0);
然后您应该会发现,您可以将标牌旋转到任意角度,同时文字保持清晰。
如果您真的需要以导致 CATextLayer 栅格化的方式来操纵文本显示,还有一个替代方法:将文本转换为 UIBezierPath
表示。然后可以将其放置在 CAShapeLayer 中。这样做需要深入研究 Core Text,但结果是强大的。例如,您可以 animate the text being drawn .
// - (UIBezierPath*) bezierPathWithString:(NSString*) string font:(UIFont*) font inRect:(CGRect) rect;
// Requires CoreText.framework
// This creates a graphical version of the input screen, line wrapped to the input rect.
// Core Text involves a whole hierarchy of objects, all requiring manual management.
- (UIBezierPath*) bezierPathWithString:(NSString*) string font:(UIFont*) font inRect:(CGRect) rect;
{
UIBezierPath *combinedGlyphsPath = nil;
CGMutablePathRef combinedGlyphsPathRef = CGPathCreateMutable();
if (combinedGlyphsPathRef)
{
// It would be easy to wrap the text into a different shape, including arbitrary bezier paths, if needed.
UIBezierPath *frameShape = [UIBezierPath bezierPathWithRect:rect];
// If the font name wasn't found while creating the font object, the result is a crash.
// Avoid this by falling back to the system font.
CTFontRef fontRef;
if ([font fontName])
fontRef = CTFontCreateWithName((__bridge CFStringRef) [font fontName], [font pointSize], NULL);
else if (font)
fontRef = CTFontCreateUIFontForLanguage(kCTFontUserFontType, [font pointSize], NULL);
else
fontRef = CTFontCreateUIFontForLanguage(kCTFontUserFontType, [UIFont systemFontSize], NULL);
if (fontRef)
{
CGPoint basePoint = CGPointMake(0, CTFontGetAscent(fontRef));
CFStringRef keys[] = { kCTFontAttributeName };
CFTypeRef values[] = { fontRef };
CFDictionaryRef attributesRef = CFDictionaryCreate(NULL, (const void **)&keys, (const void **)&values,
sizeof(keys) / sizeof(keys[0]), &kCFTypeDictionaryKeyCallBacks, &kCFTypeDictionaryValueCallBacks);
if (attributesRef)
{
CFAttributedStringRef attributedStringRef = CFAttributedStringCreate(NULL, (__bridge CFStringRef) string, attributesRef);
if (attributedStringRef)
{
CTFramesetterRef frameSetterRef = CTFramesetterCreateWithAttributedString(attributedStringRef);
if (frameSetterRef)
{
CTFrameRef frameRef = CTFramesetterCreateFrame(frameSetterRef, CFRangeMake(0,0), [frameShape CGPath], NULL);
if (frameRef)
{
CFArrayRef lines = CTFrameGetLines(frameRef);
CFIndex lineCount = CFArrayGetCount(lines);
CGPoint lineOrigins[lineCount];
CTFrameGetLineOrigins(frameRef, CFRangeMake(0, lineCount), lineOrigins);
for (CFIndex lineIndex = 0; lineIndex<lineCount; lineIndex++)
{
CTLineRef lineRef = CFArrayGetValueAtIndex(lines, lineIndex);
CGPoint lineOrigin = lineOrigins[lineIndex];
CFArrayRef runs = CTLineGetGlyphRuns(lineRef);
CFIndex runCount = CFArrayGetCount(runs);
for (CFIndex runIndex = 0; runIndex<runCount; runIndex++)
{
CTRunRef runRef = CFArrayGetValueAtIndex(runs, runIndex);
CFIndex glyphCount = CTRunGetGlyphCount(runRef);
CGGlyph glyphs[glyphCount];
CGSize glyphAdvances[glyphCount];
CGPoint glyphPositions[glyphCount];
CFRange runRange = CFRangeMake(0, glyphCount);
CTRunGetGlyphs(runRef, CFRangeMake(0, glyphCount), glyphs);
CTRunGetPositions(runRef, runRange, glyphPositions);
CTFontGetAdvancesForGlyphs(fontRef, kCTFontDefaultOrientation, glyphs, glyphAdvances, glyphCount);
for (CFIndex glyphIndex = 0; glyphIndex<glyphCount; glyphIndex++)
{
CGGlyph glyph = glyphs[glyphIndex];
// For regular UIBezierPath drawing, we need to invert around the y axis.
CGAffineTransform glyphTransform = CGAffineTransformMakeTranslation(lineOrigin.x+glyphPositions[glyphIndex].x, rect.size.height-lineOrigin.y-glyphPositions[glyphIndex].y);
glyphTransform = CGAffineTransformScale(glyphTransform, 1, -1);
CGPathRef glyphPathRef = CTFontCreatePathForGlyph(fontRef, glyph, &glyphTransform);
if (glyphPathRef)
{
// Finally carry out the appending.
CGPathAddPath(combinedGlyphsPathRef, NULL, glyphPathRef);
CFRelease(glyphPathRef);
}
basePoint.x += glyphAdvances[glyphIndex].width;
basePoint.y += glyphAdvances[glyphIndex].height;
}
}
basePoint.x = 0;
basePoint.y += CTFontGetAscent(fontRef) + CTFontGetDescent(fontRef) + CTFontGetLeading(fontRef);
}
CFRelease(frameRef);
}
CFRelease(frameSetterRef);
}
CFRelease(attributedStringRef);
}
CFRelease(attributesRef);
}
CFRelease(fontRef);
}
// Casting a CGMutablePathRef to a CGPathRef seems to be the only way to convert what was just built into a UIBezierPath.
combinedGlyphsPath = [UIBezierPath bezierPathWithCGPath:(CGPathRef) combinedGlyphsPathRef];
CGPathRelease(combinedGlyphsPathRef);
}
return combinedGlyphsPath;
}
这是旋转轮廓文本,使用上述方法创建。也可以在文本层的 z 位置不明显的情况下添加透视图。
关于ios - CATextLayer 旋转后文本模糊,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/10152574/
表架构 DROP TABLE bla; CREATE TABLE bla (id INTEGER, city INTEGER, year_ INTEGER, month_ INTEGER, val I
我需要拆分字符串/或从具有以下结构的字符串中获取更容易的子字符串。 字符串将来自 window.location.pathname 或 window.location.href,看起来像 text/n
每当将对象添加到数组中时,我都会尝试更新 TextView ,并在 TextView 中显示该文本,如下所示: "object 1" "object 2" 问题是,每次将新对象添加到数组时,它都会覆盖
我目前正在寻找使用 Java 读取网站可见文本并将其存储为纯文本字符串的方法。 换句话说,我想转换成这样: Hello stupid World进入“ Hello World ” 或者类似的东西 Un
我正在尝试以文本和 HTML 格式发送电子邮件,但无法正确发送正确的 header 。特别是,我想设置 Content-Type header ,但我找不到如何为 html 和文本部分单独设置它。 这
我尝试了上面的代码,但我无法绑定(bind)文本,我怎样才能将资源内部文本 bloc
我刚刚完成了 Space Shooter 教程,由于没有 GUIText 对象,所以我创建了 UI.Text 对象并进行了相应的编码。它在统一播放器中有效,但在构建 Web 应用程序后无效。我花了一段
我有这个代码: - (IBAction)setButtonPressed:(id)sender { NSUserDefaults *sharedDefaults = [[NSUserDefau
抱歉标题含糊不清,但我想不出我想在标题中做什么。无论如何,对于图像上的文本,我使用了 JLabel 文本并将其添加到图标中。 JLabel icon = new JLabel(new Imag
关闭。这个问题是not reproducible or was caused by typos .它目前不接受答案。 这个问题是由于错别字或无法再重现的问题引起的。虽然类似的问题可能是on-topi
我在将 Twitter 嵌入到我从 HTML 5 转换的 wordpress 运行网站时遇到问题。 我遇到的问题是推文不是我的自定义字体... 这是我无法使用任何 css 定位的 HTML 代码,我正
我正在尝试找到解决由于使用以下形式的代码而导致的冗余字符串连接问题的最佳方法: logger.debug("Entering loop, arg is: " + arg) // @1 在大多数情况下,
我写了这个测试 @Test public void removeRequestTextFromRouteError() throws Exception { String input = "F
我目前正在创建一个正则表达式来拆分所有匹配以下格式的字符串:&[文本],并且需要获取文本。字符串可能类似于:something &[text] &[text] everything &[text] 等
有没有办法将标题文本从一个词变形为另一个词,同时保留两个词中使用的字母?我看过的许多 css 文本动画大多是视觉的,很少有旋转整个单词的。 我想要做的是从一个词过渡,例如“BEACH”到“CHANGE
总结matplotlib绘图如何设置坐标轴刻度大小和刻度。 上代码: ?
我在容器 (1) 中创建了容器 (2)。你能帮忙如何向容器(1)添加文本吗?下面是我的代码 return Scaffold( body: Padding( padding: c
我似乎找不到任何人或任何人这样做过。我试图限制我们使用的图像数量,并想创建一个带有渐变作为其“颜色”的文本,并在其周围设置渐变轮廓/描边 到目前为止,我还没有看到任何将两者结合在一起的东西。 我可以自
我正在为视频游戏暗黑破坏神 2 使用 discord.py 构建一个不和谐机器人。其中一项功能要求机器人从暗黑破坏神 2 屏幕截图中提取项目的名称和属性。我目前正在为此使用 pytesseract,但
我很难弄清楚如何旋转 strip.text theme 中的属性来自 ggplot2 .我使用的是 R 版本 3.4.2 和 ggplot2 版本 2.2.1。 以下是 MWE 的数据。 > dput
我是一名优秀的程序员,十分优秀!