低级 C - 逐像素显示文本
我正在开发一个小项目,我必须编写一个低级别的应用程序。我想在该应用程序中显示文本,我什至希望它是抗锯齿的(à la ClearType)。不允许使用任何库,我必须逐像素绘制每个字符。
最好的方法是什么?您能推荐一些已知的算法吗?我应该如何存储/读取字体?
谢谢!
I am working on a small project where I have to write a low level app. I'd like to display text in that app, and I would even like it to be anti aliased (à la ClearType). No libraries allowed, I have to draw each char pixel by pixel.
What is the best way to do this? Can you recommend some known algorithms? How should I store/read the fonts?
Thanks!
如果你对这篇内容有疑问,欢迎到本站社区发帖提问 参与讨论,获取更多帮助,或者扫码二维码加入 Web 技术交流群。
绑定邮箱获取回复消息
由于您还没有绑定你的真实邮箱,如果其他用户或者作者回复了您的评论,将不能在第一时间通知您!
发布评论
评论(4)
您的意思是您只想平滑现有位图字体的边缘?如果您的原始字体是 16x32 并且您想以 8x16 或类似的尺寸渲染它,这很容易,但如果您一开始就没有更高分辨率的位图,则平滑是一项非常重要的操作,涉及大量猜测。在这种情况下,我会查找 2xsai 算法(它为此类事情提供了视觉上令人愉悦的结果)并首先执行它以将字体放大到双倍分辨率,然后将其缩小一个区域- 平均算法(即从 4 像素正方形的平均值中获取每个目标像素)。
我还建议保存最终的“抗锯齿”位图字体并在程序中简单地使用它,而不是在运行时执行所有这些工作。
You mean you just want to smooth the edges of an existing bitmapped font? This is easy if your original font is 16x32 and you want to render it at 8x16 or something like that, but if you don't have a higher-resolution bitmap to begin with, smoothing is a highly nontrivial operation involving a lot of guesswork. In that case, I would lookup the
2xsai
algorithm (which gives visually-pleasing results for this kind of thing) and first perform it to upscale the font to double resolution, then scale it back down with a area-averaging algorithm (i.e. take each destination pixel from the average of a 4-pixel square).I would also recommend saving your final "anti-aliased" bitmap font and simply using it in your program, rather than performing all this work at runtime.
总而言之:
字体主要有两种类型:
1) 等宽字体:所有字符都有固定大小,并且您可以为每个字符定义一个位图。不需要抗锯齿(您可以对位图中的灰度进行硬编码)。调整大小后看起来很糟糕。
2) True Type:每个字母由一组贝塞尔曲线参数定义。可以轻松缩放到任何大小,但需要大量的程序逻辑(和处理能力!)。抗锯齿在这里很有用(尤其是子像素渲染技术)。
据我所知,您想使用位图字体并重新缩放?您可以预先计算其中的几个,从而避免复杂的运行时逻辑。
正如 R. 所建议的,将位图保持为更高分辨率的灰度而不是黑白会有所帮助。我建议使用可被大多数小数字整除的大小,以便可以轻松缩小位图。另外,如果这个分辨率足够高,那么您可以将其保持为黑白并缩小为灰度(使用表面积分)。
编辑:请随意编辑它,请不要投票。把所有这些评论放在一起就可以了。
Putting all together:
There are two main types of fonts:
1) Monospaced: all the characters have fixed size, and you define a bitmap for each. No need for Anti Aliasing (you can hardcode the grey levels in the bitmap). Look horrible when resized.
2) True Type: each letter is defined by a set of parameters for Bezier curves. Can be easily scaled to any size, but requires lots of program logic (and processing power!) for that. Anti Aliasing is useful here (and especially the sub-pixel rendering techniquies).
As I see you want to use bitmapped font and rescaling? You could just precompute several of them, thus avoiding complex runtime logic.
As R. suggested, keeping the bitmaps at higher resolution in greyscale instead of BW will help. I'd suggest using size that is divisible by most small numbers, so that the bitmap can be downscaled easily. Also, if this resolution is high enough, then you can keep it in BW and downscale to greyscale (using surface integral).
EDIT: feel free to edit it and please don't vote. Just put all those commentaries together.
构建一个好的字体引擎很困难,特别是当您需要进行缩放和抗锯齿时。因此,我建议您采取简单的方法:
如果您想要更多功能,我建议您在尝试制定自己的解决方案之前先考虑使用像 FreeType 这样的引擎。
It is hard to build a good font engine, especially if you need to do scaling and anti-aliasing. So I suggest you take the easy path:
If you want more features, I suggest you look into using an engine like FreeType before trying to make your own solution.
好吧,只要您了解一些有关光栅化和贝塞尔曲线的知识,读取 TTF(或任何其他)字体并将一些字形渲染到位图中并不困难。不好的一点是,如果你想让文本看起来不错,就需要大量的代码。别名字体很难渲染,我不是在谈论提示。需要有一个用于字距调整、多字符序列的例程,决定哪些字形映射到您的字符以及编码内容,...
您可能需要使用预渲染的位图字体 - 然后是整个渲染操作是简单的图像复制,最终进行一些重采样或旋转;但是,你会失去矢量字体的功能。
我的建议是采用 FreeType 并接受它,它是一个很好的库,专门用于此目的,并且可以很容易地进行静态链接和消除不必要的膨胀。
Well, reading a TTF (or any other) font and rendering some glyph into the bitmap isnt that hard, given you know some stuff about rasterization and bezier curves. The bad point is that if you want the text to look good, it's gonna take a huge amount of code. Aliased font is pretty hard to render, I'm not talking about hinting. There needs to be a routine for kerning, multi-character sequences, something that decides which glyphs map to your characters and also encoding stuff, ...
You might want to use a bitmap font, which comes pre-rendered - then the whole rendering operation is a simple image copy, eventually with some resampling or rotation; but well, you lose the vector font features.
My advice is to take FreeType and live with it, it's a nice library just for this, and can be statically linked and stripped of unnecessary bloat very easily.