Skia之二 —— SkPaint 篇


SkPaint 

 

?
/** \class SkPaint
 
     The SkPaint class holds the style and color information about how to draw
     geometries, text and bitmaps.
*/

  SkPaint 保存繪制 幾何形狀、文本、位圖 的風格和顏色信息。

 

 skia的 jni接口

http://blog.csdn.net/fangyuanseu/article/details/6619561 

 

?
setAntiAlias: 設置畫筆的鋸齒效果。
setColor: 設置畫筆顏色
setARGB:  設置畫筆的a,r,p,g值。
setAlpha:  設置Alpha值
setTextSize: 設置字體尺寸。
setStyle:  設置畫筆風格,空心或者實心。
setStrokeWidth: 設置空心的邊框寬度。
getColor:  得到畫筆的顏色
getAlpha:  得到畫筆的Alpha值。

 // 設置Paint為無鋸齒

 mPaint.setAntiAlias(true)

 

 SkPaint基礎用法例子。  

http://byandby.iteye.com/blog/824819

http://code.google.com/p/skia/wiki/SkPaint

 

在使用skia繪制東西的時候,如果想指定顏色、與背景的混合、字體的風格,要在paint中設置這些屬性。

與SkCanvas不一樣,paints不保存內部狀態的堆棧(也就是沒有save/restore),paint是輕量級的,所以用戶可以為每個特殊的用途創建並保存許多paint對象,從canvas中分離顏色和字體等屬性,放在paint中,可以使canvas的save/restore更加有效。這樣canvas所做的就是保存matrix和clip設置的堆棧。

?
SkPaint paint1, paint2, paint3;
 
paint1.setColor(0xFFFF0000:
paint1.setStyle(SkPaint::kFill_Style);
 
paint2.setColor(0x8000FF00);
paint2.setStyle(SkPaint::kStroke_Style); //筆畫
paint2.setStrokeWidth(SkIntToScalar(3)); //筆畫寬度
 
paint3.setColor(0xFF888888);
paint3.setTextSize(SkIntToScalar(24));
paint3.setTextScaleX(SkFloatToScalar(0.75f));

 

以上顯示了3種不同的paint,每個指定一種不同的風格,調用者可以自由的混用他們,也可以在使用的時候修改他們的狀態

?
canvas.drawRect(..., paint1);
canvas.drawRect(..., paint2);
 
paint2.setStrokeWidth(SkIntToScalar(5));
canvas.drawOval(..., paint2);
 
canvas.drawText(..., paint3);
paint3.setColor(0xFF0000FF);
canvas.drawText(..., paint3);

  

除了顏色、筆畫、字體大小這樣的簡單屬性,paint也支持effect,effect是繪圖管線不同方面的子類,(每個effect都是引用計數的)當一個effect被一個paint引用的時候,將會覆蓋paint的繪制管線的一些部分。

例如 ,使用gradient代替單個也是,給paint指定一個SkShader

?
SkShader* shader = SkGradientShader::CreateLinear(...);
paint.setShader(shader);
shader->unref();

  現在,所有使用這個paint繪制的東西都會使用由CreateLiner指定的gradient,CreateLiner返回的Shader對象是引用計數的。當一個像shader這樣的effect對象被指定給一個paint的時候,paint會增加他的引用計數,為了平衡引用計數,上面的例子調用了shader的unref(),現在這個paint就是shader的唯一擁有者,這樣,無論是出了paint作用域或者指定了其他的shader(可以為空),會自動調用shader的unref()。

 

有6種effect可以綁定到paint:

SkPathEffect

SkRasterizer

SkMaskFilter

     SkMaskFilter的使用介紹:http://www.cnblogs.com/ezhong/archive/2011/11/30/2269501.html

SkShader 例如三種過渡色方式(linear,radial,sweep),重復模式(clamp,repeat,mirror)

     linear方式GradientShader的使用介紹: http://www.cnblogs.com/ezhong/archive/2011/11/24/2261856.html

SkColorFilter  

SkXfermode

 

paint也保持SkTypeface的引用,SkTypeface代表指定的字體風格,可以用來測量和繪制文字,也就是說不僅可以用於繪制文本,還可以用來測量文本

?
paint.measureText(...);
paint.getTextBounds(...);
paint.textToGlyphs(...);
paint.getFontMetrics(...);

 

====================================================================== 

                  備注:關於引用計數                                     

?
SkShder 繼承於 SkFlattenable,SkFlattenable繼承於SkRefCnt
 
引用計數fRefCnt在SkRefCnt中定義
 
SkRefCnt 的成員函數 ref()和unref() 分別將fRefCnt遞增1,遞減1
?
void ref() const
{
      SkASSERT(fRefCnt > 0);
      sk_atomic_inc(&fRefCnt);  //遞增1
  }
?
void unref() const
{
     SkASSERT(fRefCnt > 0);
     if (sk_atomic_dec(&fRefCnt) == 1)   //遞減1
{
         fRefCnt = 1;    // so our destructor won't complain
         SkDELETE( this );  //delete this
     }
}

  sk_atomic_dec(&fRefCnt) 返回的是遞減前fRefCnt的值,

 

  也就是如果對象的引用計數已經是1,再調用unref(),則刪除對象。

?
SkRefCnt() : fRefCnt(1) {}

  也就是SkRefCnt構造函數中將fRefCnt賦值為1.(即使此時沒有paint這種對象引用它)

 

  在上面的例子中,SkGradientShader::CreateLinear(...) 返回的SkShader的引用計數已經是1, 

  再由paint.setShader(shader);調用,使shader的引用計數是2.

  此時shader是局部變量,當paint是局部變量,生命周期結束的時候,paint會調用shader的unref(),使shader指向的對象引用計數是1

  也就是shader生命周期結束,但它指向的對象因為引用計數還是1沒有釋放,形成泄露。

  所以在setShader之后,調用unref(),使shader指向的對象引用計數是1,

  當paint生命周期結束的時候,paint 調用shader的unref(),會刪除shader指向的對象。shader生命周期也結束。

  

  有幾個paint對象引用shader對象的時候,shader對象的引用計數就應該是幾。

?
SkShader *shader =NULL;
shader =SkGradientShader::CreateLinear(..);
paint.setShader(shader);
shader->unref();
shader->unref();
printf ( "shader =%d\n" ,shader); //unref刪除shader對象的時候,並沒有將this指空,此時shader仍是原來的地址值
SkRect r = {0,0,SkIntToScalar(800),SkIntToScalar(100)};
pskCanvas->drawRect(r,paint);

  以上shader多調用unref(),已經刪除shader所指向的對象,所以后面的drawRect沒有效果。

 

 


參考:  

  http://www.cnblogs.com/ezhong/tag/skia/

 


免責聲明!

本站轉載的文章為個人學習借鑒使用,本站對版權不負任何法律責任。如果侵犯了您的隱私權益,請聯系本站郵箱yoyou2525@163.com刪除。



 
粵ICP備18138465號   © 2018-2025 CODEPRJ.COM