SkPaint
/** \class SkPaint
The SkPaint class holds the style and color information about how to draw
geometries, text and bitmaps.
*/
|
SkPaint 保存繪制 幾何形狀、文本、位圖 的風格和顏色信息。
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/