天天看點

Skia深入分析4——skia路徑繪制的實作

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、基本流程

Skia深入分析4——skia路徑繪制的實作

2、填充算法說明

我們跟進最重要的函數 sk_fill_path,如下為代碼:

不考慮 inverse 的情況,主要就是兩步:

(1)生成一系列邊:skedge

(2)周遊渲染各邊所圍出來的區域

凸集的渲染比較簡單,因為可以保證,任意兩條邊+閉合線所圍成區域一定需要渲染:

(1)取初始的兩條邊,分别為:左和右。

(2)渲染左右邊+閉合邊所圍成的區域(一般為三角,當兩邊平行時取矩形)

(3)疊代重新整理左右兩邊(如果是曲線需要重新整理多次)

凹集或者判斷不了凹凸性就比較複雜,需要一條線一條線去渲染,每次渲染還得判斷奇偶性:

代碼如下,不分析了:

3、描線流程

個人認為較簡單,就不介紹了。

三、總結

drawpath是繪制所有不規則形體的函數,帶入bitmap的shader,可以制作不規則形體的圖檔。對于凸集,skia的渲染主要也是切成三角片後渲染,和opengl類似。而對于凹集,則是掃描線了。渲染的實作和繪制圖檔一樣,建構blitter,調用blitter的blit函數族渲染。