gpt4 book ai didi

macos - 为什么 CGContextShowGlyphsAtPositions() 不起作用,而 CGContextShowGlyphsAtPoint() 起作用?

转载 作者:行者123 更新时间:2023-12-03 16:21:26 25 4
gpt4 key购买 nike

我使用 Xcode 4.2 为 Mac OS X (10.7) 编写了一个简单的 Cocoa 应用程序。该应用程序所做的就是创建一个窗口,其中包含可滚动的 subview 数组,每个 subview 代表一个页面,可以在非常低的级别上绘制内容。子View的isFlipped方法传递YES,因此每个子View的原点都是左上角。使用各种 Core Graphics 例程,我能够成功地绘制线条和填充路径以及所有有趣的 PostScripty 内容。

它从给定的字体中绘制字形,这让我感到困惑。

这是从程序中剪切粘贴的 subview -drawRect: 方法的完整代码 --

- (void)drawRect:(NSRect)dirtyRect
{
// Start with background color for any part of this view
[[NSColor whiteColor] set];
NSRectFill( dirtyRect );

// Drop down to Core Graphics world, ensuring there's no side-effects
context = (CGContextRef) [[NSGraphicsContext currentContext] graphicsPort];
CGContextSaveGState(context);
{
//CGFontRef theFont = CGFontCreateWithFontName(CFSTR("American Typewriter"));
//CGContextSetFont(context, theFont);
CGContextSelectFont(context, "American Typewriter", 200, kCGEncodingMacRoman);
CGContextSetFontSize(context, 200);

// Adjust the text transform so the text doesn't draw upside down
CGContextSetTextMatrix(context, CGAffineTransformScale(CGAffineTransformIdentity, 1, -1));

CGContextSetTextDrawingMode(context, kCGTextFillStroke);
CGContextSetRGBFillColor(context, 0.0, .3, 0.8, 1.0);

// Find the center of view's (not dirtyRect's) bounds
// View is 612 x 792 (nominally 8.5" by 11")

CGPoint centerPoint;
CGRect bds = [self bounds];
centerPoint.x = bds.origin.x + bds.size.width / 2;
centerPoint.y = bds.origin.y + bds.size.height / 2;

// Create arrays to hold glyph IDs and the positions at which to draw them.
#define glyphCount 1 // For now, just one glyph
CGGlyph glyphs[glyphCount];
CGPoint positions[glyphCount];

glyphs[0] = 40; // Glyph ID for '@' character in above font
positions[0] = centerPoint;

// Draw above center. This works.
CGContextShowGlyphsAtPoint(context, centerPoint.x, centerPoint.y - 200.0, glyphs, glyphCount);

// Draw at center. This works.
CGContextShowGlyphsAtPoint(context, positions[0].x, positions[0].y, glyphs, glyphCount);

// Draw below center. This fails (draws nothing). Why?
positions[0].y += 200.0;
CGContextShowGlyphsAtPositions(context, glyphs, positions, glyphCount);
}
CGContextRestoreGState(context);
}

让我抓狂的是,使用 CGContextShowGlyphsAtPoint() 的前两次字形绘制调用按预期工作正常,但使用 CGContextShowGlyphsAtPositions() 的第三次尝试从未绘制任何内容。所以页面上只有两个@符号,而不是三个。这种行为差异并不取决于我之前是否使用过 CGContextSetFont() 还是 CGContextSelectFont()。

状态中一定存在一些隐藏的变化,或者在这两个几乎相同的 Core Graphics 字形绘制例程的幕后有一些非常不同的东西,但到目前为止我所有的实验还没有证明这可能是什么.

叹息。我只想在 View 中相应的位置数组处有效地绘制字形数组。

你知道我做错了什么吗?

最佳答案

经过多次实验,通过彼得·霍西的回答(尽管其中有些不太正确,非常感谢!),这是我困惑的根源和我确信是正确的解释(嗯,无论如何,代码正在执行我期望的操作)。

在通常的更高级别的 PostScript 路径/绘图模型中,绘制字符会将当前点(路径末端)更新为下一个字符可能出现的位置,使当前用户空间变换保持不变。但在幕后,文本矩阵变换是按字形的宽度(或更准确地说是前进向量)翻译的,以便下一个要绘制的字符可以从新的字符开始,或者相对于新的字符开始。文本来源。文本矩阵的比例因子在翻译后保持不变。

因此初始设置调用 CGContextSetTextMatrix()翻转文本矩阵的垂直方向仍然是必要的(如果用户空间类似地翻转),因为否则两个字形集合绘制例程都会将字形颠倒w/r/t路径绘制,无论文本在哪里绘图开始或使用哪个绘图例程。

这两个字形集合绘制例程都不会影响当前路径。他们的水平比那低。我发现我可以在路径构造调用之间散布任一例程,而不会影响路径的位置或形状。

在上面发布的代码中,位置数据CGContextShowGlyphsAtPositions()用于绘制字形集合的所有相对都与当前文本矩阵原点对应的用户空间点相关,该原点被转换到先前绘制的“@”字形的右侧。因为我用了这么大的字体,position[0]导致下一个“@”字形在 View 边界之外绘制,因此它不可见,但正在绘制。

但这两个例程之间仍然存在一些细微差别。 CGContextShowGlyphsAtPositions()永远不能用于将字形放置在任何绝对用户空间位置。那么你如何告诉它从哪里开始呢?答案(或至少一个答案)是 CGContextShowGlyphsAtPoint()将文本矩阵的原点更新为给定的用户空间点即使没有要绘制的字形。和CGContextShowGlyphsAtPoint()必须在绘制每个字形之后翻译文本矩阵,因为(可以这么说)在彼此之上绘制整个字形集合有什么意义。

因此可以使用 CGContextShowGlyphsAtPoint() “移动”到用户空间中的非路径点字形计数为 0,然后可以调用 CGContextShowGlyphsAtPositions() (任意次数)带有位置向量,每个位置都将相对于文本矩阵的原点(或者实际上是与其对应的用户空间点)进行处理,而当 CGContextShowGlyphsAtPositions() 时,根本不会更新文本矩阵原点。返回。

最后,请注意提供给 CGContextShowGlyphsAtPositions() 的位置数据位于用户空间坐标中。 Apple 的头文件中对这些例程的注释明确说明了这一点。

关于macos - 为什么 CGContextShowGlyphsAtPositions() 不起作用,而 CGContextShowGlyphsAtPoint() 起作用?,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/17095785/

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