在重绘时放大混乱的Cairo纹理
我正在使用 python-clutter 1.0
我的问题以挑战的形式提出
写一段代码,让我们可以通过按一个键来放大一个 CairoTexture 对象,放大的步骤要能让这个对象重新绘制(通过 cairo),这样图像保持高清晰度,同时也能按预期缩放,而不是改变这个对象的大小。
可以想象一下 Inkscape,如何在矢量图上进行缩放;在任何放大倍数下,矢量图依然保持清晰。把一条路径(比如一堆 cairo 的 line_to
命令)放到一个 CairoTexture 对象上,然后让同样的效果发生。
更多细节
我想做一个小型的 SVG 编辑器,使用一组对象。每个对象专注于一条路径。我通过使用 SomeGroup.set_depth(z)
来“缩放”,然后让 z 变大或变小。到目前为止都很好。然而,随着对象越来越靠近相机,纹理会被拉伸以适应它们的新大小。
我似乎找不到让 Clutter 同时做到这两点的方法:
- 保持对象的实际大小不变(也就是它最开始的样子)。
- 在放大时,替换它的底层表面为更大的表面,这样我就可以在上面重新绘制路径(并使用 cairo 矩阵来进行上下文的缩放)。
如果我使用 set_size
或 set_surface_size
,对象会变得 更大,这不是我想要的。我只想让它的 表面(底层数据)变大。
(我不太确定这个术语是什么,可能是 mipmapping?)
换句话说:一个多边形变大了,增加它的纹理数组的大小,以便它可以映射到更大的多边形上。
我甚至尝试绕过 clutter,保持一个第二个表面(使用 pycairo),我重新创建它以适应对象的实际大小(get_transformed_size
),然后我使用 clutter 的 set_from_rgb_data
指向我的第二个表面,强制改变表面的大小,但不改变对象的尺寸。
这样做的问题是 a) clutter 忽略了新大小,只在旧的宽度/高度上绘制,b) RGBA 和 ARGB32 的问题导致颜色混乱。
我对任何替代方案持开放态度,希望我在树林里却看不到树!
\d
1 个回答
好吧,尽管我做了很多测试和尝试,但答案其实一直就在我眼前。
感谢Neil在clutter项目列表上的分享,下面是事情的真相:
CT = SomeCairoTextureActor()
# record the old height, once:
old_width, old_height = CT.get_size()
Start a loop:
# Do stuff to the depth of CT (or it's parent)
...
# Get the apparent width and height (absolute size in pixels)
appr_w,appr_h = CT.get_transformed_size()
# Make the new surface to the new size
CT.set_surface_size( appr_w, appr_h )
# Crunch the actor back down to old size
# but leave the texture surface something other!
CT.set_size(old_width, old_height)
loop back again
表面大小和演员的大小不一定要相同。表面大小默认是演员的首选大小。你可以通过直接设置演员的大小来覆盖这个首选大小。如果演员的大小和表面大小不同,那么纹理会被压缩以适应演员的大小(我想这正是你想要的效果)。
很高兴能把这个小谜团解开。谢谢clutter列表!
\d