skia2/samplecode/SampleAll.cpp
reed@google.com fd4be26c42 Change patheffect to take a (new) StrokeRec object, which encapsulates the fill
or stroke parameters for a path.

Today, the patheffect only sees if the caller was going to stroke or fill, and
if stroke, it just sees the width. With this change, the effect can see all of the
related parameters (e.g. cap/join/miter). No other change is intended at this
time.

After this change, I hope to use this additional data to allow SkDashPathEffect
to, at times, apply the stroke as part of its effect, which may be much more
efficient than first dashing, and then reading that and stroking it.

Most of these files changed just because of the new parameter to filterPath. The
key changes are in SkPathEffect.[h,cpp], SkPaint.cpp and SkScalerContext.cpp
Review URL: https://codereview.appspot.com/6250051

git-svn-id: http://skia.googlecode.com/svn/trunk@4048 2bbb7eff-a529-9590-31e7-b0007b416f81
2012-05-25 01:04:12 +00:00

690 lines
24 KiB
C++

/*
* Copyright 2011 Google Inc.
*
* Use of this source code is governed by a BSD-style license that can be
* found in the LICENSE file.
*/
#include "SampleCode.h"
#include "SkCanvas.h"
#include "SkView.h"
#include "Sk1DPathEffect.h"
#include "Sk2DPathEffect.h"
#include "SkAvoidXfermode.h"
#include "SkBlurMaskFilter.h"
#include "SkColorFilter.h"
#include "SkColorPriv.h"
#include "SkCornerPathEffect.h"
#include "SkDashPathEffect.h"
#include "SkDiscretePathEffect.h"
#include "SkEmbossMaskFilter.h"
#include "SkGradientShader.h"
#include "SkImageDecoder.h"
#include "SkLayerRasterizer.h"
#include "SkMath.h"
#include "SkPath.h"
#include "SkRegion.h"
#include "SkShader.h"
#include "SkComposeShader.h"
#include "SkCornerPathEffect.h"
#include "SkPathMeasure.h"
#include "SkPicture.h"
#include "SkRandom.h"
#include "SkTransparentShader.h"
#include "SkTypeface.h"
#include "SkUnitMappers.h"
#include "SkUtils.h"
#include "SkXfermode.h"
#include <math.h>
static inline SkPMColor rgb2gray(SkPMColor c) {
unsigned r = SkGetPackedR32(c);
unsigned g = SkGetPackedG32(c);
unsigned b = SkGetPackedB32(c);
unsigned x = (r * 5 + g * 7 + b * 4) >> 4;
return SkPackARGB32(0, x, x, x) | (c & (SK_A32_MASK << SK_A32_SHIFT));
}
class SkGrayScaleColorFilter : public SkColorFilter {
public:
virtual void filterSpan(const SkPMColor src[], int count, SkPMColor result[]) {
for (int i = 0; i < count; i++)
result[i] = rgb2gray(src[i]);
}
};
class SkChannelMaskColorFilter : public SkColorFilter {
public:
SkChannelMaskColorFilter(U8CPU redMask, U8CPU greenMask, U8CPU blueMask) {
fMask = SkPackARGB32(0xFF, redMask, greenMask, blueMask);
}
virtual void filterSpan(const SkPMColor src[], int count, SkPMColor result[]) {
SkPMColor mask = fMask;
for (int i = 0; i < count; i++) {
result[i] = src[i] & mask;
}
}
private:
SkPMColor fMask;
};
///////////////////////////////////////////////////////////
static void r0(SkLayerRasterizer* rast, SkPaint& p) {
p.setMaskFilter(SkBlurMaskFilter::Create(SkIntToScalar(3),
SkBlurMaskFilter::kNormal_BlurStyle))->unref();
rast->addLayer(p, SkIntToScalar(3), SkIntToScalar(3));
p.setMaskFilter(NULL);
p.setStyle(SkPaint::kStroke_Style);
p.setStrokeWidth(SK_Scalar1);
rast->addLayer(p);
p.setAlpha(0x11);
p.setStyle(SkPaint::kFill_Style);
p.setXfermodeMode(SkXfermode::kSrc_Mode);
rast->addLayer(p);
}
static void r1(SkLayerRasterizer* rast, SkPaint& p) {
rast->addLayer(p);
p.setAlpha(0x40);
p.setXfermodeMode(SkXfermode::kSrc_Mode);
p.setStyle(SkPaint::kStroke_Style);
p.setStrokeWidth(SK_Scalar1*2);
rast->addLayer(p);
}
static void r2(SkLayerRasterizer* rast, SkPaint& p) {
p.setStyle(SkPaint::kStrokeAndFill_Style);
p.setStrokeWidth(SK_Scalar1*4);
rast->addLayer(p);
p.setStyle(SkPaint::kStroke_Style);
p.setStrokeWidth(SK_Scalar1*3/2);
p.setXfermodeMode(SkXfermode::kClear_Mode);
rast->addLayer(p);
}
static void r3(SkLayerRasterizer* rast, SkPaint& p) {
p.setStyle(SkPaint::kStroke_Style);
p.setStrokeWidth(SK_Scalar1*3);
rast->addLayer(p);
p.setAlpha(0x20);
p.setStyle(SkPaint::kFill_Style);
p.setXfermodeMode(SkXfermode::kSrc_Mode);
rast->addLayer(p);
}
static void r4(SkLayerRasterizer* rast, SkPaint& p) {
p.setAlpha(0x60);
rast->addLayer(p, SkIntToScalar(3), SkIntToScalar(3));
p.setAlpha(0xFF);
p.setXfermodeMode(SkXfermode::kClear_Mode);
rast->addLayer(p, SK_Scalar1*3/2, SK_Scalar1*3/2);
p.setXfermode(NULL);
rast->addLayer(p);
}
static void r5(SkLayerRasterizer* rast, SkPaint& p) {
rast->addLayer(p);
p.setPathEffect(new SkDiscretePathEffect(SK_Scalar1*4, SK_Scalar1*3))->unref();
p.setXfermodeMode(SkXfermode::kSrcOut_Mode);
rast->addLayer(p);
}
static void r6(SkLayerRasterizer* rast, SkPaint& p) {
rast->addLayer(p);
p.setAntiAlias(false);
SkLayerRasterizer* rast2 = new SkLayerRasterizer;
r5(rast2, p);
p.setRasterizer(rast2)->unref();
p.setXfermodeMode(SkXfermode::kClear_Mode);
rast->addLayer(p);
}
class Dot2DPathEffect : public Sk2DPathEffect {
public:
Dot2DPathEffect(SkScalar radius, const SkMatrix& matrix)
: Sk2DPathEffect(matrix), fRadius(radius) {}
SK_DECLARE_PUBLIC_FLATTENABLE_DESERIALIZATION_PROCS(Dot2DPathEffect)
protected:
virtual void next(const SkPoint& loc, int u, int v, SkPath* dst) {
dst->addCircle(loc.fX, loc.fY, fRadius);
}
Dot2DPathEffect(SkFlattenableReadBuffer& buffer) : INHERITED(buffer) {
fRadius = buffer.readScalar();
}
virtual void flatten(SkFlattenableWriteBuffer& buffer) const SK_OVERRIDE {
this->INHERITED::flatten(buffer);
buffer.writeScalar(fRadius);
}
private:
SkScalar fRadius;
typedef Sk2DPathEffect INHERITED;
};
static void r7(SkLayerRasterizer* rast, SkPaint& p) {
SkMatrix lattice;
lattice.setScale(SK_Scalar1*6, SK_Scalar1*6, 0, 0);
lattice.postSkew(SK_Scalar1/3, 0, 0, 0);
p.setPathEffect(new Dot2DPathEffect(SK_Scalar1*4, lattice))->unref();
rast->addLayer(p);
}
static void r8(SkLayerRasterizer* rast, SkPaint& p) {
rast->addLayer(p);
SkMatrix lattice;
lattice.setScale(SK_Scalar1*6, SK_Scalar1*6, 0, 0);
lattice.postSkew(SK_Scalar1/3, 0, 0, 0);
p.setPathEffect(new Dot2DPathEffect(SK_Scalar1*2, lattice))->unref();
p.setXfermodeMode(SkXfermode::kClear_Mode);
rast->addLayer(p);
p.setPathEffect(NULL);
p.setXfermode(NULL);
p.setStyle(SkPaint::kStroke_Style);
p.setStrokeWidth(SK_Scalar1);
rast->addLayer(p);
}
class Line2DPathEffect : public Sk2DPathEffect {
public:
Line2DPathEffect(SkScalar width, const SkMatrix& matrix)
: Sk2DPathEffect(matrix), fWidth(width) {}
virtual bool filterPath(SkPath* dst, const SkPath& src, SkStrokeRec* rec) SK_OVERRIDE {
if (this->INHERITED::filterPath(dst, src, rec)) {
rec->setStrokeStyle(fWidth);
return true;
}
return false;
}
SK_DECLARE_PUBLIC_FLATTENABLE_DESERIALIZATION_PROCS(Line2DPathEffect)
protected:
virtual void nextSpan(int u, int v, int ucount, SkPath* dst) {
if (ucount > 1) {
SkPoint src[2], dstP[2];
src[0].set(SkIntToScalar(u) + SK_ScalarHalf,
SkIntToScalar(v) + SK_ScalarHalf);
src[1].set(SkIntToScalar(u+ucount) + SK_ScalarHalf,
SkIntToScalar(v) + SK_ScalarHalf);
this->getMatrix().mapPoints(dstP, src, 2);
dst->moveTo(dstP[0]);
dst->lineTo(dstP[1]);
}
}
Line2DPathEffect(SkFlattenableReadBuffer& buffer) : INHERITED(buffer) {
fWidth = buffer.readScalar();
}
virtual void flatten(SkFlattenableWriteBuffer& buffer) const SK_OVERRIDE {
this->INHERITED::flatten(buffer);
buffer.writeScalar(fWidth);
}
private:
SkScalar fWidth;
typedef Sk2DPathEffect INHERITED;
};
static void r9(SkLayerRasterizer* rast, SkPaint& p) {
rast->addLayer(p);
SkMatrix lattice;
lattice.setScale(SK_Scalar1, SK_Scalar1*6, 0, 0);
lattice.postRotate(SkIntToScalar(30), 0, 0);
p.setPathEffect(new Line2DPathEffect(SK_Scalar1*2, lattice))->unref();
p.setXfermodeMode(SkXfermode::kClear_Mode);
rast->addLayer(p);
p.setPathEffect(NULL);
p.setXfermode(NULL);
p.setStyle(SkPaint::kStroke_Style);
p.setStrokeWidth(SK_Scalar1);
rast->addLayer(p);
}
typedef void (*raster_proc)(SkLayerRasterizer*, SkPaint&);
static const raster_proc gRastProcs[] = {
r0, r1, r2, r3, r4, r5, r6, r7, r8, r9
};
static const struct {
SkColor fMul, fAdd;
} gLightingColors[] = {
{ 0x808080, 0x800000 }, // general case
{ 0x707070, 0x707070 }, // no-pin case
{ 0xFFFFFF, 0x800000 }, // just-add case
{ 0x808080, 0x000000 }, // just-mul case
{ 0xFFFFFF, 0x000000 } // identity case
};
static void apply_shader(SkPaint* paint, int index) {
raster_proc proc = gRastProcs[index];
if (proc) {
SkPaint p;
SkLayerRasterizer* rast = new SkLayerRasterizer;
p.setAntiAlias(true);
proc(rast, p);
paint->setRasterizer(rast)->unref();
}
#if 1
SkScalar dir[] = { SK_Scalar1, SK_Scalar1, SK_Scalar1 };
paint->setMaskFilter(SkBlurMaskFilter::CreateEmboss(dir, SK_Scalar1/4, SkIntToScalar(4), SkIntToScalar(3)))->unref();
paint->setColor(SK_ColorBLUE);
#endif
}
class DemoView : public SampleView {
public:
DemoView() {}
protected:
// overrides from SkEventSink
virtual bool onQuery(SkEvent* evt) {
if (SampleCode::TitleQ(*evt)) {
SampleCode::TitleR(evt, "Demo");
return true;
}
return this->INHERITED::onQuery(evt);
}
virtual bool onClick(Click* click) {
return this->INHERITED::onClick(click);
}
void makePath(SkPath& path) {
path.addCircle(SkIntToScalar(20), SkIntToScalar(20), SkIntToScalar(20),
SkPath::kCCW_Direction);
for (int index = 0; index < 10; index++) {
SkScalar x = SkFloatToScalar(cos(index / 10.0f * 2 * 3.1415925358f));
SkScalar y = SkFloatToScalar(sin(index / 10.0f * 2 * 3.1415925358f));
x *= index & 1 ? 7 : 14;
y *= index & 1 ? 7 : 14;
x += SkIntToScalar(20);
y += SkIntToScalar(20);
if (index == 0)
path.moveTo(x, y);
else
path.lineTo(x, y);
}
path.close();
}
virtual void onDrawContent(SkCanvas* canvas) {
canvas->save();
drawPicture(canvas, 0);
canvas->restore();
{
SkPicture picture;
SkCanvas* record = picture.beginRecording(320, 480);
drawPicture(record, 120);
canvas->translate(0, SkIntToScalar(120));
SkRect clip;
clip.set(0, 0, SkIntToScalar(160), SkIntToScalar(160));
do {
canvas->save();
canvas->clipRect(clip);
picture.draw(canvas);
canvas->restore();
if (clip.fRight < SkIntToScalar(320))
clip.offset(SkIntToScalar(160), 0);
else if (clip.fBottom < SkIntToScalar(480))
clip.offset(-SkIntToScalar(320), SkIntToScalar(160));
else
break;
} while (true);
}
}
void drawPicture(SkCanvas* canvas, int spriteOffset) {
SkMatrix matrix; matrix.reset();
SkPaint paint;
SkPath path;
SkPoint start = {0, 0};
SkPoint stop = { SkIntToScalar(40), SkIntToScalar(40) };
SkRect rect = {0, 0, SkIntToScalar(40), SkIntToScalar(40) };
SkRect rect2 = {0, 0, SkIntToScalar(65), SkIntToScalar(20) };
SkScalar left = 0, top = 0, x = 0, y = 0;
size_t index;
char ascii[] = "ascii...";
size_t asciiLength = sizeof(ascii) - 1;
char utf8[] = "utf8" "\xe2\x80\xa6";
short utf16[] = {'u', 't', 'f', '1', '6', 0x2026 };
short utf16simple[] = {'u', 't', 'f', '1', '6', '!' };
makePath(path);
SkTDArray<SkPoint>(pos);
pos.setCount(asciiLength);
for (index = 0; index < asciiLength; index++)
pos[index].set(SkIntToScalar((unsigned int)index * 10),
SkIntToScalar((unsigned int)index * 2));
SkTDArray<SkPoint>(pos2);
pos2.setCount(asciiLength);
for (index = 0; index < asciiLength; index++)
pos2[index].set(SkIntToScalar((unsigned int)index * 10),
SkIntToScalar(20));
// shaders
SkPoint linearPoints[] = { { 0, 0, }, { SkIntToScalar(40), SkIntToScalar(40) } };
SkColor linearColors[] = { SK_ColorRED, SK_ColorBLUE };
SkScalar* linearPos = NULL;
int linearCount = 2;
SkShader::TileMode linearMode = SkShader::kMirror_TileMode;
SkUnitMapper* linearMapper = new SkDiscreteMapper(3);
SkAutoUnref unmapLinearMapper(linearMapper);
SkShader* linear = SkGradientShader::CreateLinear(linearPoints,
linearColors, linearPos, linearCount, linearMode, linearMapper);
SkPoint radialCenter = { SkIntToScalar(25), SkIntToScalar(25) };
SkScalar radialRadius = SkIntToScalar(25);
SkColor radialColors[] = { SK_ColorGREEN, SK_ColorGRAY, SK_ColorRED };
SkScalar radialPos[] = { 0, SkIntToScalar(3) / 5, SkIntToScalar(1)};
int radialCount = 3;
SkShader::TileMode radialMode = SkShader::kRepeat_TileMode;
SkUnitMapper* radialMapper = new SkCosineMapper();
SkAutoUnref unmapRadialMapper(radialMapper);
SkShader* radial = SkGradientShader::CreateRadial(radialCenter,
radialRadius, radialColors, radialPos, radialCount,
radialMode, radialMapper);
SkTransparentShader* transparentShader = new SkTransparentShader();
SkEmbossMaskFilter::Light light;
light.fDirection[0] = SK_Scalar1/2;
light.fDirection[1] = SK_Scalar1/2;
light.fDirection[2] = SK_Scalar1/3;
light.fAmbient = 0x48;
light.fSpecular = 0x80;
SkScalar radius = SkIntToScalar(12)/5;
SkEmbossMaskFilter* embossFilter = new SkEmbossMaskFilter(light,
radius);
SkXfermode* xfermode = SkXfermode::Create(SkXfermode::kXor_Mode);
SkColorFilter* lightingFilter = SkColorFilter::CreateLightingFilter(
0xff89bc45, 0xff112233);
canvas->save();
canvas->translate(SkIntToScalar(0), SkIntToScalar(5));
paint.setFlags(SkPaint::kAntiAlias_Flag | SkPaint::kFilterBitmap_Flag);
// !!! draw through a clip
paint.setColor(SK_ColorLTGRAY);
paint.setStyle(SkPaint::kFill_Style);
SkRect clip = {0, 0, SkIntToScalar(320), SkIntToScalar(120)};
canvas->clipRect(clip);
paint.setShader(SkShader::CreateBitmapShader(fTx,
SkShader::kMirror_TileMode, SkShader::kRepeat_TileMode))->unref();
canvas->drawPaint(paint);
canvas->save();
// line (exercises xfermode, colorShader, colorFilter, filterShader)
paint.setColor(SK_ColorGREEN);
paint.setStrokeWidth(SkIntToScalar(10));
paint.setStyle(SkPaint::kStroke_Style);
paint.setXfermode(xfermode)->unref();
paint.setColorFilter(lightingFilter)->unref();
canvas->drawLine(start.fX, start.fY, stop.fX, stop.fY, paint); // should not be green
paint.setXfermode(NULL);
paint.setColorFilter(NULL);
// rectangle
paint.setStyle(SkPaint::kFill_Style);
canvas->translate(SkIntToScalar(50), 0);
paint.setColor(SK_ColorYELLOW);
paint.setShader(linear)->unref();
paint.setPathEffect(pathEffectTest())->unref();
canvas->drawRect(rect, paint);
paint.setPathEffect(NULL);
// circle w/ emboss & transparent (exercises 3dshader)
canvas->translate(SkIntToScalar(50), 0);
paint.setMaskFilter(embossFilter)->unref();
canvas->drawOval(rect, paint);
canvas->translate(SkIntToScalar(10), SkIntToScalar(10));
paint.setShader(transparentShader)->unref();
canvas->drawOval(rect, paint);
canvas->translate(0, SkIntToScalar(-10));
// path
canvas->translate(SkIntToScalar(50), 0);
paint.setColor(SK_ColorRED);
paint.setStyle(SkPaint::kStroke_Style);
paint.setStrokeWidth(SkIntToScalar(5));
paint.setShader(radial)->unref();
paint.setMaskFilter(NULL);
canvas->drawPath(path, paint);
paint.setShader(NULL);
// bitmap, sprite
canvas->translate(SkIntToScalar(50), 0);
paint.setStyle(SkPaint::kFill_Style);
canvas->drawBitmap(fBug, left, top, &paint);
canvas->translate(SkIntToScalar(30), 0);
canvas->drawSprite(fTb,
SkScalarRound(canvas->getTotalMatrix().getTranslateX()),
spriteOffset + 10, &paint);
canvas->translate(-SkIntToScalar(30), SkIntToScalar(30));
paint.setShader(shaderTest())->unref(); // test compose shader
canvas->drawRect(rect2, paint);
paint.setShader(NULL);
canvas->restore();
// text
canvas->translate(0, SkIntToScalar(60));
canvas->save();
paint.setColor(SK_ColorGRAY);
canvas->drawPosText(ascii, asciiLength, pos.begin(), paint);
canvas->drawPosText(ascii, asciiLength, pos2.begin(), paint);
canvas->translate(SkIntToScalar(50), 0);
paint.setColor(SK_ColorCYAN);
canvas->drawText(utf8, sizeof(utf8) - 1, x, y, paint);
canvas->translate(SkIntToScalar(30), 0);
paint.setColor(SK_ColorMAGENTA);
paint.setTextEncoding(SkPaint::kUTF16_TextEncoding);
matrix.setTranslate(SkIntToScalar(10), SkIntToScalar(10));
canvas->drawTextOnPath((void*) utf16, sizeof(utf16), path, &matrix, paint);
canvas->translate(0, SkIntToScalar(20));
canvas->drawTextOnPath((void*) utf16simple, sizeof(utf16simple), path, &matrix, paint);
canvas->restore();
canvas->translate(0, SkIntToScalar(60));
paint.setTextEncoding(SkPaint::kUTF8_TextEncoding);
canvas->restore();
}
/*
./SkColorFilter.h:25:class SkColorFilter : public SkFlattenable { -- abstract
static SkColorFilter* CreatXfermodeFilter() *** untested ***
static SkColorFilter* CreatePorterDuffFilter() *** untested ***
static SkColorFilter* CreateLightingFilter() -- tested
./SkDrawLooper.h:9:class SkDrawLooper : public SkFlattenable { -- virtually abstract
./SkBlurDrawLooper.h:9:class SkBlurDrawLooper : public SkDrawLooper { *** untested ***
./SkMaskFilter.h:41:class SkMaskFilter : public SkFlattenable { -- abstract chmod +w .h
./SkEmbossMaskFilter.h:27:class SkEmbossMaskFilter : public SkMaskFilter { -- tested
./SkPathEffect.h:33:class SkPathEffect : public SkFlattenable { -- abstract
./Sk1DPathEffect.h:27:class Sk1DPathEffect : public SkPathEffect { -- abstract
./Sk1DPathEffect.h:48:class SkPath1DPathEffect : public Sk1DPathEffect { -- tested
./Sk2DPathEffect.h:25:class Sk2DPathEffect : public SkPathEffect { *** untested ***
./SkCornerPathEffect.h:28:class SkCornerPathEffect : public SkPathEffect { *** untested ***
./SkDashPathEffect.h:27:class SkDashPathEffect : public SkPathEffect {
./SkDiscretePathEffect.h:27:class SkDiscretePathEffect : public SkPathEffect {
./SkPaint.h:760:class SkStrokePathEffect : public SkPathEffect {
./SkPathEffect.h:58:class SkPairPathEffect : public SkPathEffect {
./SkPathEffect.h:78:class SkComposePathEffect : public SkPairPathEffect {
./SkPathEffect.h:114:class SkSumPathEffect : public SkPairPathEffect {
./SkRasterizer.h:29:class SkRasterizer : public SkFlattenable {
./SkLayerRasterizer.h:27:class SkLayerRasterizer : public SkRasterizer {
./SkShader.h:36:class SkShader : public SkFlattenable {
./SkColorFilter.h:59:class SkFilterShader : public SkShader {
./SkColorShader.h:26:class SkColorShader : public SkShader {
./SkShaderExtras.h:31:class SkComposeShader : public SkShader {
./SkTransparentShader.h:23:class SkTransparentShader : public SkShader {
./SkUnitMapper.h:24:class SkUnitMapper : public SkFlattenable {
./SkUnitMapper.h:33:class SkDiscreteMapper : public SkUnitMapper {
./SkUnitMapper.h:51:class SkFlipCosineMapper : public SkUnitMapper {
./SkXfermode.h:32:class SkXfermode : public SkFlattenable {
./SkAvoidXfermode.h:28:class SkAvoidXfermode : public SkXfermode { *** not done *** chmod +w .h .cpp
./SkXfermode.h:54:class SkProcXfermode : public SkXfermode {
*/
/*
./SkBlurMaskFilter.h:25:class SkBlurMaskFilter {
chmod +w SkBlurMaskFilter.cpp
./SkGradientShader.h:30:class SkGradientShader {
*/
// save layer, bounder, looper
// matrix
// clip /path/region
// bitmap proc shader ?
/* untested:
SkCornerPathEffect.h:28:class SkCornerPathEffect : public SkPathEffect {
*/
virtual SkView::Click* onFindClickHandler(SkScalar x, SkScalar y) {
fClickPt.set(x, y);
this->inval(NULL);
return this->INHERITED::onFindClickHandler(x, y);
}
SkPathEffect* pathEffectTest() {
static const int gXY[] = { 1, 0, 0, -1, 2, -1, 3, 0, 2, 1, 0, 1 };
SkScalar gPhase = 0;
SkPath path;
path.moveTo(SkIntToScalar(gXY[0]), SkIntToScalar(gXY[1]));
for (unsigned i = 2; i < SK_ARRAY_COUNT(gXY); i += 2)
path.lineTo(SkIntToScalar(gXY[i]), SkIntToScalar(gXY[i+1]));
path.close();
path.offset(SkIntToScalar(-6), 0);
SkPathEffect* outer = new SkPath1DPathEffect(path, SkIntToScalar(12),
gPhase, SkPath1DPathEffect::kRotate_Style);
SkPathEffect* inner = new SkDiscretePathEffect(SkIntToScalar(2),
SkIntToScalar(1)/10); // SkCornerPathEffect(SkIntToScalar(2));
SkPathEffect* result = new SkComposePathEffect(outer, inner);
outer->unref();
inner->unref();
return result;
}
SkShader* shaderTest() {
SkPoint pts[] = { { 0, 0, }, { SkIntToScalar(100), 0 } };
SkColor colors[] = { SK_ColorRED, SK_ColorBLUE };
SkShader* shaderA = SkGradientShader::CreateLinear(pts, colors, NULL,
2, SkShader::kClamp_TileMode);
pts[1].set(0, SkIntToScalar(100));
SkColor colors2[] = {SK_ColorBLACK, SkColorSetARGB(0x80, 0, 0, 0)};
SkShader* shaderB = SkGradientShader::CreateLinear(pts, colors2, NULL,
2, SkShader::kClamp_TileMode);
SkXfermode* mode = SkXfermode::Create(SkXfermode::kDstIn_Mode);
SkShader* result = new SkComposeShader(shaderA, shaderB, mode);
shaderA->unref();
shaderB->unref();
mode->unref();
return result;
}
virtual void startTest() {
SkImageDecoder::DecodeFile("/Users/caryclark/Desktop/bugcirc.gif", &fBug);
SkImageDecoder::DecodeFile("/Users/caryclark/Desktop/tbcirc.gif", &fTb);
SkImageDecoder::DecodeFile("/Users/caryclark/Desktop/05psp04.gif", &fTx);
}
void drawRaster(SkCanvas* canvas) {
for (size_t index = 0; index < SK_ARRAY_COUNT(gRastProcs); index++)
drawOneRaster(canvas);
}
void drawOneRaster(SkCanvas* canvas) {
canvas->save();
SkScalar x = SkIntToScalar(20);
SkScalar y = SkIntToScalar(40);
SkPaint paint;
paint.setAntiAlias(true);
paint.setTextSize(SkIntToScalar(48));
paint.setTypeface(SkTypeface::CreateFromName("sans-serif",
SkTypeface::kBold));
SkString str("GOOGLE");
for (size_t i = 0; i < SK_ARRAY_COUNT(gRastProcs); i++) {
apply_shader(&paint, i);
// paint.setMaskFilter(NULL);
// paint.setColor(SK_ColorBLACK);
#if 01
int index = i % SK_ARRAY_COUNT(gLightingColors);
paint.setColorFilter(SkColorFilter::CreateLightingFilter(
gLightingColors[index].fMul,
gLightingColors[index].fAdd))->unref();
#endif
canvas->drawText(str.c_str(), str.size(), x, y, paint);
SkRect oval = { x, y - SkIntToScalar(40), x + SkIntToScalar(40), y };
paint.setStyle(SkPaint::kStroke_Style);
canvas->drawOval(oval, paint);
paint.setStyle(SkPaint::kFill_Style);
y += paint.getFontSpacing();
}
canvas->restore();
if (1) {
SkAvoidXfermode mode(SK_ColorWHITE, 0xFF,
SkAvoidXfermode::kTargetColor_Mode);
SkPaint paint;
x += SkIntToScalar(20);
SkRect r = { x, 0, x + SkIntToScalar(360), SkIntToScalar(700) };
paint.setXfermode(&mode);
paint.setColor(SK_ColorGREEN);
paint.setAntiAlias(true);
canvas->drawOval(r, paint);
}
}
private:
SkPoint fClickPt;
SkBitmap fBug, fTb, fTx;
typedef SampleView INHERITED;
};
//////////////////////////////////////////////////////////////////////////////
static SkView* MyFactory() { return new DemoView; }
static SkViewRegister reg(MyFactory);