任何时候你要用Skia绘制一些东西,并且要指定颜色、与背景混合的方式、绘制所使用的风格和字体,你都需要在一个paint中来指定那些属性。
不像SkCanvas,paint不维护状态的内部栈(比如,paint没有save/restore)。然而,paints是相对轻量级的,因而客户端可以创建和维护任何数量的paint对象,可以为每种用途设置一个。在canvas状态之外来创建所有的这些颜色和风格属性,放在(多个)paint 对象中,可以使得canvas的save/restore变得高效很多,它们不得不做的所有的事情即是维护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));
此处展示了三个不同的paints,分别为不同风格的绘制而设置。现在调用者可以自由地混合这些paints了,或者直接使用它们,或者在绘制处理时改变它们。
canvas.drawRect(..., paint1);
canvas.drawRect(..., paint2);
paint2.setStrokeWidth(SkIntToScalar(5));
canvas.drawOval(..., paint2);
canvas.drawText(..., paint3);
paint3.setColor(0xFF0000FF);
canvas.drawText(..., paint3);
除了简单的属性,如颜色,笔画,和文本值,paints还支持effects.这些是绘制管线的不同方面的子类,当它们被一个paint引用(它们中的每一个都被引用计数)时,它们会被调用以覆盖绘制管线的某个部分.
比如要用一个梯度以替代单一颜色的绘制,则给paint赋一个SkShader.
SkShader* shader = SkGradientShader::CreateLinear(...);
paint.setShader(shader);
shader->unref();
现在,使用那个paint绘制的所有的东西,在绘制时都伴随有调用
CreateLinear()所创建的那个gradient.返回的shader对象是被引用计数了的.无论何时侯任何effects对象,比如一个shader,被赋给一个paint,它的引用计数就会被paint增加.为了平衡,上面例子中的调用者在把它赋给paint之后立即对shader调用了unref().现在paint是那个shader的仅有的"所有者",这样它就会在paint超出范围或者另一个shader(或null)赋给了它的时候对shader调用unref()。
有6中类型的effects可以被赋给一个paint:
- SkPathEffect - modifications to the geometry (path) before it generates an alpha mask (e.g. dashing)
- SkRasterizer - composing custom mask layers (e.g. shadows)
- SkMaskFilter - modifications to the alpha mask before it is colorized and drawn (e.g. blur, emboss)
- SkShader - e.g. gradients (linear, radial, sweep), bitmap patterns (clamp, repeat, mirror)
- SkColorFilter - modify the source color(s) before applying the xfermode (e.g. color matrix)
- SkXfermode - e.g. porter-duff transfermodes, blend modes
Paints也握有一个对SkTypeface的引用。typeface表示一个特定的字体风格,将被用于测量和绘制文字。可以说,paints不仅仅被用于绘制文本,也可以被用于测量它。
paint.measureText(...);
paint.getTextBounds(...);
paint.textToGlyphs(...);
paint.getFontMetrics(...);
End