skia2/gm/twopointradial.cpp
reed@google.com cb7be694c3 Add new gradient to support HTML Canvas2D two-point-radial-gradient. Ours is
called (for now at least) TwoPointConical, to distinguish it from the
existing one (TwoPointRadial), and to reflect its odd behavior where it draws
transparent outside the boundary of the "cone" between the two circles.

This impl is unsupported by GPU and Printing at the moment, and Chrome does not
yet invoke it.
Review URL: https://codereview.appspot.com/6299051

git-svn-id: http://skia.googlecode.com/svn/trunk@4197 2bbb7eff-a529-9590-31e7-b0007b416f81
2012-06-06 20:31:56 +00:00

113 lines
3.5 KiB
C++

/*
* Copyright 2012 Google Inc.
*
* Use of this source code is governed by a BSD-style license that can be
* found in the LICENSE file.
*/
#include "gm.h"
#include "SkCanvas.h"
#include "SkPaint.h"
#include "SkGradientShader.h"
static void intToScalars(SkScalar dst[], const int src[], int n) {
for (int i = 0; i < n; ++i) {
dst[i] = SkIntToScalar(src[i]);
}
}
static void drawGrad(SkCanvas* canvas, const SkScalar d0[], const SkScalar d1[]) {
const SkRect bounds = SkRect::MakeXYWH(SkIntToScalar(-50),
SkIntToScalar(-50),
SkIntToScalar(200),
SkIntToScalar(100));
SkPoint c0 = { d0[0], d0[1] };
SkScalar r0 = d0[2];
SkPoint c1 = { d1[0], d1[1] };
SkScalar r1 = d1[2];
SkColor colors[] = { SK_ColorGREEN, SK_ColorRED };
SkPaint paint;
paint.setAntiAlias(true);
SkString str;
str.printf("%g,%g,%g %g,%g,%g",
SkScalarToFloat(c0.fX), SkScalarToFloat(c0.fY), SkScalarToFloat(r0),
SkScalarToFloat(c1.fX), SkScalarToFloat(c1.fY), SkScalarToFloat(r1));
canvas->drawText(str.c_str(), str.size(),
bounds.fLeft, bounds.fTop - paint.getTextSize()/2, paint);
paint.setShader(SkGradientShader::CreateTwoPointConical(c0, r0, c1, r1,
colors, NULL, 2,
SkShader::kClamp_TileMode))->unref();
canvas->drawRect(bounds, paint);
paint.setShader(NULL);
paint.setColor(0x66000000);
paint.setStyle(SkPaint::kStroke_Style);
canvas->drawCircle(c0.fX, c0.fY, r0, paint);
canvas->drawCircle(c1.fX, c1.fY, r1, paint);
canvas->drawRect(bounds, paint);
}
class TwoPointRadialGM : public skiagm::GM {
public:
TwoPointRadialGM() {}
protected:
SkString onShortName() {
return SkString("twopointconical");
}
SkISize onISize() { return skiagm::make_isize(480, 780); }
// BUG: PDF code (at least on mac) fails when we run this
virtual uint32_t onGetFlags() const SK_OVERRIDE { return kSkipPDF_Flag; }
virtual void onDraw(SkCanvas* canvas) {
if (false) {
SkPaint paint;
paint.setColor(SK_ColorBLUE);
canvas->drawRect(SkRect::MakeWH(this->getISize().fWidth, this->getISize().fHeight), paint);
}
SkPaint paint;
const int R0 = 20;
const int R1 = 40;
const SkScalar DX = SkIntToScalar(250);
const SkScalar DY = SkIntToScalar(130);
canvas->translate(SkIntToScalar(60), SkIntToScalar(70));
static const int gData[] = {
0, 0, R0, 0, 0, R1,
0, 0, R0, 20, 0, R1,
0, 0, R0, 25, 0, R1,
0, 0, R0, 100, 0, R1,
0, 0, R0, 25, 0, R0,
0, 0, R0, 100, 0, R0,
};
int count = SK_ARRAY_COUNT(gData) / 6;
for (int i = 0; i < count; ++i) {
SkScalar data[6];
intToScalars(data, &gData[i * 6], 6);
int n = canvas->save();
drawGrad(canvas, &data[0], &data[3]);
canvas->translate(DX, 0);
drawGrad(canvas, &data[3], &data[0]);
canvas->restoreToCount(n);
canvas->translate(0, DY);
}
}
};
//////////////////////////////////////////////////////////////////////////////
static skiagm::GM* F(void*) { return new TwoPointRadialGM; }
static skiagm::GMRegistry gR(F);