• SkPaint


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

      SkPaint 保存绘制 几何形状、文本、位图 的风格和颜色信息。

     2011-11-10/16:19:03

    http://blog.csdn.net/fangyuanseu/article/details/6619561 skia的 jni接口

    2011-11-22/15:50:37

       setAntiAlias: 设置画笔的锯齿效果。 
       setColor: 设置画笔颜色 
       setARGB:  设置画笔的a,r,p,g值。 
       setAlpha:  设置Alpha值 
       setTextSize: 设置字体尺寸。 
       setStyle:  设置画笔风格,空心或者实心。 
       setStrokeWidth: 设置空心的边框宽度。 
       getColor:  得到画笔的颜色 
       getAlpha:  得到画笔的Alpha值。 
    

      

    1. // 设置Paint为无锯齿
    2.         mPaint.setAntiAlias(true);  
    3. http://byandby.iteye.com/blog/824819  SkPaint基础用法例子。

    2011-11-25/08:49:36:

    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没有效果。

    ezhong的博客园:http://www.cnblogs.com/ezhong/

  • 相关阅读:
    Python全栈-第六课 学习笔记
    python基础 day27 装饰器函数classmethod、staticmethod
    python基础 day26 面向对象-super方法、封装、property装饰器、反射
    python基础 day25 面向对象-继承2
    python基础 day24 面向对象-继承1
    python基础 day23 面向对象2
    python基础 day22 面向对象
    python基础 day21 递归函数、shutil模块
    python基础 day20 re模块、带参数的装饰器
    python基础 day19 正则表达式
  • 原文地址:https://www.cnblogs.com/ezhong/p/2244240.html
Copyright © 2020-2023  润新知