skia路径绘制代码分析
路径绘制尽管使用频率相对于图像绘制、文本绘制低,但却是非常重要的一个基本特性。所有不规则图形(椭圆、圆角矩形、三角形、简单的文字),最后都避不开路径绘制。
而且,若自己实现一个2d引擎,这块内容是很具有参考意义的,用opengl的话,图像采样等都很少关注了,对对坐标就好。但菱角、圆弧、曲线等如何绘制仍然是一个难题,这时就可以参考skia中drawpath的实现。
由于涉及较多的图形学知识,本章就不讲相关公式了,只讲讲基本的流程。
一、skpath类
在之前的图像绘制并没有介绍skbitmap,因为skbitmap相对而言比较容易理解,网上文章也多。但这次的skpath不同,研究它怎么用是需要一点精力的,因此在这里先做介绍。
1、skpath结构
去除成员函数之后,我们看到skpath包括这几个成员,注释中补充了说明:
关于 ffilltype中 kwinding_filltype和 kevenodd_filltype的区别,可看skpath::contains。这是判断点是否在不规则几何体内的经典代码(),很有参考意义。
skpathref的内容如下:
2、skpath的主要类型:
kmove_verb:表示需要移动起点
kline_verb:直线
kquad_verb:二次曲线
kconic_verb:圆锥曲线
kcubic_verb:三次曲线
kclose_verb:表闭合到某点
kdone_verb:表结束
3、drawpath使用实例
二、drawpath流程
1、基本流程
2、填充算法说明
我们跟进最重要的函数 sk_fill_path,如下为代码:
不考虑 inverse 的情况,主要就是两步:
(1)生成一系列边:skedge
(2)遍历渲染各边所围出来的区域
凸集的渲染比较简单,因为可以保证,任意两条边+闭合线所围成区域一定需要渲染:
(1)取初始的两条边,分别为:左和右。
(2)渲染左右边+闭合边所围成的区域(一般为三角,当两边平行时取矩形)
(3)迭代刷新左右两边(如果是曲线需要刷新多次)
凹集或者判断不了凹凸性就比较复杂,需要一条线一条线去渲染,每次渲染还得判断奇偶性:
代码如下,不分析了:
3、描线流程
个人认为较简单,就不介绍了。
三、总结
drawpath是绘制所有不规则形体的函数,带入bitmap的shader,可以制作不规则形体的图片。对于凸集,skia的渲染主要也是切成三角片后渲染,和opengl类似。而对于凹集,则是扫描线了。渲染的实现和绘制图片一样,构建blitter,调用blitter的blit函数族渲染。