gradients.cpp revision e27eefc4844477cee5d32f51ab45ff62020cdb36
180bacfeb4bda06541e8695bd502229727bccfeaJean-Baptiste Queru 280bacfeb4bda06541e8695bd502229727bccfeaJean-Baptiste Queru/* 380bacfeb4bda06541e8695bd502229727bccfeaJean-Baptiste Queru * Copyright 2011 Google Inc. 480bacfeb4bda06541e8695bd502229727bccfeaJean-Baptiste Queru * 580bacfeb4bda06541e8695bd502229727bccfeaJean-Baptiste Queru * Use of this source code is governed by a BSD-style license that can be 680bacfeb4bda06541e8695bd502229727bccfeaJean-Baptiste Queru * found in the LICENSE file. 780bacfeb4bda06541e8695bd502229727bccfeaJean-Baptiste Queru */ 880bacfeb4bda06541e8695bd502229727bccfeaJean-Baptiste Queru#include "gm.h" 980bacfeb4bda06541e8695bd502229727bccfeaJean-Baptiste Queru#include "SkGradientShader.h" 1080bacfeb4bda06541e8695bd502229727bccfeaJean-Baptiste Queru 1180bacfeb4bda06541e8695bd502229727bccfeaJean-Baptiste Querunamespace skiagm { 1280bacfeb4bda06541e8695bd502229727bccfeaJean-Baptiste Queru 1380bacfeb4bda06541e8695bd502229727bccfeaJean-Baptiste Querustruct GradData { 1480bacfeb4bda06541e8695bd502229727bccfeaJean-Baptiste Queru int fCount; 1580bacfeb4bda06541e8695bd502229727bccfeaJean-Baptiste Queru const SkColor* fColors; 1680bacfeb4bda06541e8695bd502229727bccfeaJean-Baptiste Queru const SkScalar* fPos; 1780bacfeb4bda06541e8695bd502229727bccfeaJean-Baptiste Queru}; 1880bacfeb4bda06541e8695bd502229727bccfeaJean-Baptiste Queru 1980bacfeb4bda06541e8695bd502229727bccfeaJean-Baptiste Querustatic const SkColor gColors[] = { 2080bacfeb4bda06541e8695bd502229727bccfeaJean-Baptiste Queru SK_ColorRED, SK_ColorGREEN, SK_ColorBLUE, SK_ColorWHITE, SK_ColorBLACK 2180bacfeb4bda06541e8695bd502229727bccfeaJean-Baptiste Queru}; 2280bacfeb4bda06541e8695bd502229727bccfeaJean-Baptiste Querustatic const SkScalar gPos0[] = { 0, SK_Scalar1 }; 2380bacfeb4bda06541e8695bd502229727bccfeaJean-Baptiste Querustatic const SkScalar gPos1[] = { SK_Scalar1/4, SK_Scalar1*3/4 }; 2480bacfeb4bda06541e8695bd502229727bccfeaJean-Baptiste Querustatic const SkScalar gPos2[] = { 2580bacfeb4bda06541e8695bd502229727bccfeaJean-Baptiste Queru 0, SK_Scalar1/8, SK_Scalar1/2, SK_Scalar1*7/8, SK_Scalar1 2680bacfeb4bda06541e8695bd502229727bccfeaJean-Baptiste Queru}; 2780bacfeb4bda06541e8695bd502229727bccfeaJean-Baptiste Queru 28e27eefc4844477cee5d32f51ab45ff62020cdb36Derek Sollenbergerstatic const SkScalar gPosClamp[] = {0.0f, 0.0f, 1.0f, 1.0f}; 29e27eefc4844477cee5d32f51ab45ff62020cdb36Derek Sollenbergerstatic const SkColor gColorClamp[] = { 30e27eefc4844477cee5d32f51ab45ff62020cdb36Derek Sollenberger SK_ColorRED, SK_ColorGREEN, SK_ColorGREEN, SK_ColorBLUE 31e27eefc4844477cee5d32f51ab45ff62020cdb36Derek Sollenberger}; 32e27eefc4844477cee5d32f51ab45ff62020cdb36Derek Sollenberger 3380bacfeb4bda06541e8695bd502229727bccfeaJean-Baptiste Querustatic const GradData gGradData[] = { 3480bacfeb4bda06541e8695bd502229727bccfeaJean-Baptiste Queru { 2, gColors, NULL }, 3580bacfeb4bda06541e8695bd502229727bccfeaJean-Baptiste Queru { 2, gColors, gPos0 }, 3680bacfeb4bda06541e8695bd502229727bccfeaJean-Baptiste Queru { 2, gColors, gPos1 }, 3780bacfeb4bda06541e8695bd502229727bccfeaJean-Baptiste Queru { 5, gColors, NULL }, 38e27eefc4844477cee5d32f51ab45ff62020cdb36Derek Sollenberger { 5, gColors, gPos2 }, 39e27eefc4844477cee5d32f51ab45ff62020cdb36Derek Sollenberger { 4, gColorClamp, gPosClamp } 4080bacfeb4bda06541e8695bd502229727bccfeaJean-Baptiste Queru}; 4180bacfeb4bda06541e8695bd502229727bccfeaJean-Baptiste Queru 4280bacfeb4bda06541e8695bd502229727bccfeaJean-Baptiste Querustatic SkShader* MakeLinear(const SkPoint pts[2], const GradData& data, 4380bacfeb4bda06541e8695bd502229727bccfeaJean-Baptiste Queru SkShader::TileMode tm, SkUnitMapper* mapper) { 4480bacfeb4bda06541e8695bd502229727bccfeaJean-Baptiste Queru return SkGradientShader::CreateLinear(pts, data.fColors, data.fPos, 4580bacfeb4bda06541e8695bd502229727bccfeaJean-Baptiste Queru data.fCount, tm, mapper); 4680bacfeb4bda06541e8695bd502229727bccfeaJean-Baptiste Queru} 4780bacfeb4bda06541e8695bd502229727bccfeaJean-Baptiste Queru 4880bacfeb4bda06541e8695bd502229727bccfeaJean-Baptiste Querustatic SkShader* MakeRadial(const SkPoint pts[2], const GradData& data, 4980bacfeb4bda06541e8695bd502229727bccfeaJean-Baptiste Queru SkShader::TileMode tm, SkUnitMapper* mapper) { 5080bacfeb4bda06541e8695bd502229727bccfeaJean-Baptiste Queru SkPoint center; 5180bacfeb4bda06541e8695bd502229727bccfeaJean-Baptiste Queru center.set(SkScalarAve(pts[0].fX, pts[1].fX), 5280bacfeb4bda06541e8695bd502229727bccfeaJean-Baptiste Queru SkScalarAve(pts[0].fY, pts[1].fY)); 5380bacfeb4bda06541e8695bd502229727bccfeaJean-Baptiste Queru return SkGradientShader::CreateRadial(center, center.fX, data.fColors, 5480bacfeb4bda06541e8695bd502229727bccfeaJean-Baptiste Queru data.fPos, data.fCount, tm, mapper); 5580bacfeb4bda06541e8695bd502229727bccfeaJean-Baptiste Queru} 5680bacfeb4bda06541e8695bd502229727bccfeaJean-Baptiste Queru 5780bacfeb4bda06541e8695bd502229727bccfeaJean-Baptiste Querustatic SkShader* MakeSweep(const SkPoint pts[2], const GradData& data, 58096defe64d408e54474fe19f418c95bf1a554fc7Derek Sollenberger SkShader::TileMode, SkUnitMapper* mapper) { 5980bacfeb4bda06541e8695bd502229727bccfeaJean-Baptiste Queru SkPoint center; 6080bacfeb4bda06541e8695bd502229727bccfeaJean-Baptiste Queru center.set(SkScalarAve(pts[0].fX, pts[1].fX), 6180bacfeb4bda06541e8695bd502229727bccfeaJean-Baptiste Queru SkScalarAve(pts[0].fY, pts[1].fY)); 6280bacfeb4bda06541e8695bd502229727bccfeaJean-Baptiste Queru return SkGradientShader::CreateSweep(center.fX, center.fY, data.fColors, 6380bacfeb4bda06541e8695bd502229727bccfeaJean-Baptiste Queru data.fPos, data.fCount, mapper); 6480bacfeb4bda06541e8695bd502229727bccfeaJean-Baptiste Queru} 6580bacfeb4bda06541e8695bd502229727bccfeaJean-Baptiste Queru 6680bacfeb4bda06541e8695bd502229727bccfeaJean-Baptiste Querustatic SkShader* Make2Radial(const SkPoint pts[2], const GradData& data, 6780bacfeb4bda06541e8695bd502229727bccfeaJean-Baptiste Queru SkShader::TileMode tm, SkUnitMapper* mapper) { 6880bacfeb4bda06541e8695bd502229727bccfeaJean-Baptiste Queru SkPoint center0, center1; 6980bacfeb4bda06541e8695bd502229727bccfeaJean-Baptiste Queru center0.set(SkScalarAve(pts[0].fX, pts[1].fX), 7080bacfeb4bda06541e8695bd502229727bccfeaJean-Baptiste Queru SkScalarAve(pts[0].fY, pts[1].fY)); 7180bacfeb4bda06541e8695bd502229727bccfeaJean-Baptiste Queru center1.set(SkScalarInterp(pts[0].fX, pts[1].fX, SkIntToScalar(3)/5), 7280bacfeb4bda06541e8695bd502229727bccfeaJean-Baptiste Queru SkScalarInterp(pts[0].fY, pts[1].fY, SkIntToScalar(1)/4)); 7380bacfeb4bda06541e8695bd502229727bccfeaJean-Baptiste Queru return SkGradientShader::CreateTwoPointRadial( 7480bacfeb4bda06541e8695bd502229727bccfeaJean-Baptiste Queru center1, (pts[1].fX - pts[0].fX) / 7, 7580bacfeb4bda06541e8695bd502229727bccfeaJean-Baptiste Queru center0, (pts[1].fX - pts[0].fX) / 2, 7680bacfeb4bda06541e8695bd502229727bccfeaJean-Baptiste Queru data.fColors, data.fPos, data.fCount, tm, mapper); 7780bacfeb4bda06541e8695bd502229727bccfeaJean-Baptiste Queru} 7880bacfeb4bda06541e8695bd502229727bccfeaJean-Baptiste Queru 7980bacfeb4bda06541e8695bd502229727bccfeaJean-Baptiste Querustatic SkShader* Make2Conical(const SkPoint pts[2], const GradData& data, 8080bacfeb4bda06541e8695bd502229727bccfeaJean-Baptiste Queru SkShader::TileMode tm, SkUnitMapper* mapper) { 8180bacfeb4bda06541e8695bd502229727bccfeaJean-Baptiste Queru SkPoint center0, center1; 8280bacfeb4bda06541e8695bd502229727bccfeaJean-Baptiste Queru SkScalar radius0 = SkScalarDiv(pts[1].fX - pts[0].fX, 10); 8380bacfeb4bda06541e8695bd502229727bccfeaJean-Baptiste Queru SkScalar radius1 = SkScalarDiv(pts[1].fX - pts[0].fX, 3); 8480bacfeb4bda06541e8695bd502229727bccfeaJean-Baptiste Queru center0.set(pts[0].fX + radius0, pts[0].fY + radius0); 8580bacfeb4bda06541e8695bd502229727bccfeaJean-Baptiste Queru center1.set(pts[1].fX - radius1, pts[1].fY - radius1); 8680bacfeb4bda06541e8695bd502229727bccfeaJean-Baptiste Queru return SkGradientShader::CreateTwoPointConical(center1, radius1, 8780bacfeb4bda06541e8695bd502229727bccfeaJean-Baptiste Queru center0, radius0, 8880bacfeb4bda06541e8695bd502229727bccfeaJean-Baptiste Queru data.fColors, data.fPos, 8980bacfeb4bda06541e8695bd502229727bccfeaJean-Baptiste Queru data.fCount, tm, mapper); 9080bacfeb4bda06541e8695bd502229727bccfeaJean-Baptiste Queru} 9180bacfeb4bda06541e8695bd502229727bccfeaJean-Baptiste Queru 9280bacfeb4bda06541e8695bd502229727bccfeaJean-Baptiste Querutypedef SkShader* (*GradMaker)(const SkPoint pts[2], const GradData& data, 9380bacfeb4bda06541e8695bd502229727bccfeaJean-Baptiste Queru SkShader::TileMode tm, SkUnitMapper* mapper); 9480bacfeb4bda06541e8695bd502229727bccfeaJean-Baptiste Querustatic const GradMaker gGradMakers[] = { 9580bacfeb4bda06541e8695bd502229727bccfeaJean-Baptiste Queru MakeLinear, MakeRadial, MakeSweep, Make2Radial, Make2Conical 9680bacfeb4bda06541e8695bd502229727bccfeaJean-Baptiste Queru}; 9780bacfeb4bda06541e8695bd502229727bccfeaJean-Baptiste Queru 9880bacfeb4bda06541e8695bd502229727bccfeaJean-Baptiste Queru/////////////////////////////////////////////////////////////////////////////// 9980bacfeb4bda06541e8695bd502229727bccfeaJean-Baptiste Queru 10080bacfeb4bda06541e8695bd502229727bccfeaJean-Baptiste Queruclass GradientsGM : public GM { 10180bacfeb4bda06541e8695bd502229727bccfeaJean-Baptiste Querupublic: 10280bacfeb4bda06541e8695bd502229727bccfeaJean-Baptiste Queru GradientsGM() { 10380bacfeb4bda06541e8695bd502229727bccfeaJean-Baptiste Queru this->setBGColor(0xFFDDDDDD); 10480bacfeb4bda06541e8695bd502229727bccfeaJean-Baptiste Queru } 10580bacfeb4bda06541e8695bd502229727bccfeaJean-Baptiste Queru 10680bacfeb4bda06541e8695bd502229727bccfeaJean-Baptiste Queruprotected: 10780bacfeb4bda06541e8695bd502229727bccfeaJean-Baptiste Queru SkString onShortName() { 10880bacfeb4bda06541e8695bd502229727bccfeaJean-Baptiste Queru return SkString("gradients"); 10980bacfeb4bda06541e8695bd502229727bccfeaJean-Baptiste Queru } 11080bacfeb4bda06541e8695bd502229727bccfeaJean-Baptiste Queru 11180bacfeb4bda06541e8695bd502229727bccfeaJean-Baptiste Queru virtual SkISize onISize() { return make_isize(640, 615); } 11280bacfeb4bda06541e8695bd502229727bccfeaJean-Baptiste Queru 11380bacfeb4bda06541e8695bd502229727bccfeaJean-Baptiste Queru virtual void onDraw(SkCanvas* canvas) { 11480bacfeb4bda06541e8695bd502229727bccfeaJean-Baptiste Queru 11580bacfeb4bda06541e8695bd502229727bccfeaJean-Baptiste Queru SkPoint pts[2] = { 11680bacfeb4bda06541e8695bd502229727bccfeaJean-Baptiste Queru { 0, 0 }, 11780bacfeb4bda06541e8695bd502229727bccfeaJean-Baptiste Queru { SkIntToScalar(100), SkIntToScalar(100) } 11880bacfeb4bda06541e8695bd502229727bccfeaJean-Baptiste Queru }; 11980bacfeb4bda06541e8695bd502229727bccfeaJean-Baptiste Queru SkShader::TileMode tm = SkShader::kClamp_TileMode; 12080bacfeb4bda06541e8695bd502229727bccfeaJean-Baptiste Queru SkRect r = { 0, 0, SkIntToScalar(100), SkIntToScalar(100) }; 12180bacfeb4bda06541e8695bd502229727bccfeaJean-Baptiste Queru SkPaint paint; 12280bacfeb4bda06541e8695bd502229727bccfeaJean-Baptiste Queru paint.setAntiAlias(true); 12380bacfeb4bda06541e8695bd502229727bccfeaJean-Baptiste Queru 12480bacfeb4bda06541e8695bd502229727bccfeaJean-Baptiste Queru canvas->translate(SkIntToScalar(20), SkIntToScalar(20)); 12580bacfeb4bda06541e8695bd502229727bccfeaJean-Baptiste Queru for (size_t i = 0; i < SK_ARRAY_COUNT(gGradData); i++) { 12680bacfeb4bda06541e8695bd502229727bccfeaJean-Baptiste Queru canvas->save(); 12780bacfeb4bda06541e8695bd502229727bccfeaJean-Baptiste Queru for (size_t j = 0; j < SK_ARRAY_COUNT(gGradMakers); j++) { 12880bacfeb4bda06541e8695bd502229727bccfeaJean-Baptiste Queru SkShader* shader = gGradMakers[j](pts, gGradData[i], tm, NULL); 129e27eefc4844477cee5d32f51ab45ff62020cdb36Derek Sollenberger 130e27eefc4844477cee5d32f51ab45ff62020cdb36Derek Sollenberger if (i == 5) { // if the clamp case 131e27eefc4844477cee5d32f51ab45ff62020cdb36Derek Sollenberger SkMatrix scale; 132e27eefc4844477cee5d32f51ab45ff62020cdb36Derek Sollenberger scale.setScale(0.5f, 0.5f); 133e27eefc4844477cee5d32f51ab45ff62020cdb36Derek Sollenberger scale.postTranslate(25.f, 25.f); 134e27eefc4844477cee5d32f51ab45ff62020cdb36Derek Sollenberger shader->setLocalMatrix(scale); 135e27eefc4844477cee5d32f51ab45ff62020cdb36Derek Sollenberger } 136e27eefc4844477cee5d32f51ab45ff62020cdb36Derek Sollenberger 13780bacfeb4bda06541e8695bd502229727bccfeaJean-Baptiste Queru paint.setShader(shader); 13880bacfeb4bda06541e8695bd502229727bccfeaJean-Baptiste Queru canvas->drawRect(r, paint); 13980bacfeb4bda06541e8695bd502229727bccfeaJean-Baptiste Queru shader->unref(); 14080bacfeb4bda06541e8695bd502229727bccfeaJean-Baptiste Queru canvas->translate(0, SkIntToScalar(120)); 14180bacfeb4bda06541e8695bd502229727bccfeaJean-Baptiste Queru } 14280bacfeb4bda06541e8695bd502229727bccfeaJean-Baptiste Queru canvas->restore(); 14380bacfeb4bda06541e8695bd502229727bccfeaJean-Baptiste Queru canvas->translate(SkIntToScalar(120), 0); 14480bacfeb4bda06541e8695bd502229727bccfeaJean-Baptiste Queru } 14580bacfeb4bda06541e8695bd502229727bccfeaJean-Baptiste Queru } 14680bacfeb4bda06541e8695bd502229727bccfeaJean-Baptiste Queru 14780bacfeb4bda06541e8695bd502229727bccfeaJean-Baptiste Queruprivate: 14880bacfeb4bda06541e8695bd502229727bccfeaJean-Baptiste Queru typedef GM INHERITED; 14980bacfeb4bda06541e8695bd502229727bccfeaJean-Baptiste Queru}; 15080bacfeb4bda06541e8695bd502229727bccfeaJean-Baptiste Queru 15180bacfeb4bda06541e8695bd502229727bccfeaJean-Baptiste Queru// Based on the original gradient slide, but with perspective applied to the 15280bacfeb4bda06541e8695bd502229727bccfeaJean-Baptiste Queru// gradient shaders' local matrices 15380bacfeb4bda06541e8695bd502229727bccfeaJean-Baptiste Queruclass GradientsLocalPerspectiveGM : public GM { 15480bacfeb4bda06541e8695bd502229727bccfeaJean-Baptiste Querupublic: 15580bacfeb4bda06541e8695bd502229727bccfeaJean-Baptiste Queru GradientsLocalPerspectiveGM() { 15680bacfeb4bda06541e8695bd502229727bccfeaJean-Baptiste Queru this->setBGColor(0xFFDDDDDD); 15780bacfeb4bda06541e8695bd502229727bccfeaJean-Baptiste Queru } 15880bacfeb4bda06541e8695bd502229727bccfeaJean-Baptiste Queru 15980bacfeb4bda06541e8695bd502229727bccfeaJean-Baptiste Queruprotected: 16080bacfeb4bda06541e8695bd502229727bccfeaJean-Baptiste Queru SkString onShortName() { 16180bacfeb4bda06541e8695bd502229727bccfeaJean-Baptiste Queru return SkString("gradients_local_perspective"); 16280bacfeb4bda06541e8695bd502229727bccfeaJean-Baptiste Queru } 16380bacfeb4bda06541e8695bd502229727bccfeaJean-Baptiste Queru 16480bacfeb4bda06541e8695bd502229727bccfeaJean-Baptiste Queru virtual SkISize onISize() { return make_isize(640, 615); } 16580bacfeb4bda06541e8695bd502229727bccfeaJean-Baptiste Queru 16680bacfeb4bda06541e8695bd502229727bccfeaJean-Baptiste Queru virtual void onDraw(SkCanvas* canvas) { 16780bacfeb4bda06541e8695bd502229727bccfeaJean-Baptiste Queru 16880bacfeb4bda06541e8695bd502229727bccfeaJean-Baptiste Queru SkPoint pts[2] = { 16980bacfeb4bda06541e8695bd502229727bccfeaJean-Baptiste Queru { 0, 0 }, 17080bacfeb4bda06541e8695bd502229727bccfeaJean-Baptiste Queru { SkIntToScalar(100), SkIntToScalar(100) } 17180bacfeb4bda06541e8695bd502229727bccfeaJean-Baptiste Queru }; 17280bacfeb4bda06541e8695bd502229727bccfeaJean-Baptiste Queru SkShader::TileMode tm = SkShader::kClamp_TileMode; 17380bacfeb4bda06541e8695bd502229727bccfeaJean-Baptiste Queru SkRect r = { 0, 0, SkIntToScalar(100), SkIntToScalar(100) }; 17480bacfeb4bda06541e8695bd502229727bccfeaJean-Baptiste Queru SkPaint paint; 17580bacfeb4bda06541e8695bd502229727bccfeaJean-Baptiste Queru paint.setAntiAlias(true); 17680bacfeb4bda06541e8695bd502229727bccfeaJean-Baptiste Queru 17780bacfeb4bda06541e8695bd502229727bccfeaJean-Baptiste Queru canvas->translate(SkIntToScalar(20), SkIntToScalar(20)); 17880bacfeb4bda06541e8695bd502229727bccfeaJean-Baptiste Queru for (size_t i = 0; i < SK_ARRAY_COUNT(gGradData); i++) { 17980bacfeb4bda06541e8695bd502229727bccfeaJean-Baptiste Queru canvas->save(); 18080bacfeb4bda06541e8695bd502229727bccfeaJean-Baptiste Queru for (size_t j = 0; j < SK_ARRAY_COUNT(gGradMakers); j++) { 18180bacfeb4bda06541e8695bd502229727bccfeaJean-Baptiste Queru SkShader* shader = gGradMakers[j](pts, gGradData[i], tm, NULL); 18280bacfeb4bda06541e8695bd502229727bccfeaJean-Baptiste Queru 18380bacfeb4bda06541e8695bd502229727bccfeaJean-Baptiste Queru // apply an increasing y perspective as we move to the right 18480bacfeb4bda06541e8695bd502229727bccfeaJean-Baptiste Queru SkMatrix perspective; 18580bacfeb4bda06541e8695bd502229727bccfeaJean-Baptiste Queru perspective.setIdentity(); 18680bacfeb4bda06541e8695bd502229727bccfeaJean-Baptiste Queru perspective.setPerspY(SkScalarDiv(SkIntToScalar((unsigned) i+1), 18780bacfeb4bda06541e8695bd502229727bccfeaJean-Baptiste Queru SkIntToScalar(500))); 18880bacfeb4bda06541e8695bd502229727bccfeaJean-Baptiste Queru perspective.setSkewX(SkScalarDiv(SkIntToScalar((unsigned) i+1), 18980bacfeb4bda06541e8695bd502229727bccfeaJean-Baptiste Queru SkIntToScalar(10))); 190e27eefc4844477cee5d32f51ab45ff62020cdb36Derek Sollenberger 19180bacfeb4bda06541e8695bd502229727bccfeaJean-Baptiste Queru shader->setLocalMatrix(perspective); 19280bacfeb4bda06541e8695bd502229727bccfeaJean-Baptiste Queru 19380bacfeb4bda06541e8695bd502229727bccfeaJean-Baptiste Queru paint.setShader(shader); 19480bacfeb4bda06541e8695bd502229727bccfeaJean-Baptiste Queru canvas->drawRect(r, paint); 19580bacfeb4bda06541e8695bd502229727bccfeaJean-Baptiste Queru shader->unref(); 19680bacfeb4bda06541e8695bd502229727bccfeaJean-Baptiste Queru canvas->translate(0, SkIntToScalar(120)); 19780bacfeb4bda06541e8695bd502229727bccfeaJean-Baptiste Queru } 19880bacfeb4bda06541e8695bd502229727bccfeaJean-Baptiste Queru canvas->restore(); 19980bacfeb4bda06541e8695bd502229727bccfeaJean-Baptiste Queru canvas->translate(SkIntToScalar(120), 0); 20080bacfeb4bda06541e8695bd502229727bccfeaJean-Baptiste Queru } 20180bacfeb4bda06541e8695bd502229727bccfeaJean-Baptiste Queru } 20280bacfeb4bda06541e8695bd502229727bccfeaJean-Baptiste Queru 20380bacfeb4bda06541e8695bd502229727bccfeaJean-Baptiste Queruprivate: 20480bacfeb4bda06541e8695bd502229727bccfeaJean-Baptiste Queru typedef GM INHERITED; 20580bacfeb4bda06541e8695bd502229727bccfeaJean-Baptiste Queru}; 20680bacfeb4bda06541e8695bd502229727bccfeaJean-Baptiste Queru 20780bacfeb4bda06541e8695bd502229727bccfeaJean-Baptiste Queru// Based on the original gradient slide, but with perspective applied to 20880bacfeb4bda06541e8695bd502229727bccfeaJean-Baptiste Queru// the view matrix 20980bacfeb4bda06541e8695bd502229727bccfeaJean-Baptiste Queruclass GradientsViewPerspectiveGM : public GradientsGM { 21080bacfeb4bda06541e8695bd502229727bccfeaJean-Baptiste Queruprotected: 21180bacfeb4bda06541e8695bd502229727bccfeaJean-Baptiste Queru SkString onShortName() { 21280bacfeb4bda06541e8695bd502229727bccfeaJean-Baptiste Queru return SkString("gradients_view_perspective"); 21380bacfeb4bda06541e8695bd502229727bccfeaJean-Baptiste Queru } 21480bacfeb4bda06541e8695bd502229727bccfeaJean-Baptiste Queru 21580bacfeb4bda06541e8695bd502229727bccfeaJean-Baptiste Queru virtual SkISize onISize() { return make_isize(640, 400); } 21680bacfeb4bda06541e8695bd502229727bccfeaJean-Baptiste Queru 21780bacfeb4bda06541e8695bd502229727bccfeaJean-Baptiste Queru virtual void onDraw(SkCanvas* canvas) { 21880bacfeb4bda06541e8695bd502229727bccfeaJean-Baptiste Queru SkMatrix perspective; 21980bacfeb4bda06541e8695bd502229727bccfeaJean-Baptiste Queru perspective.setIdentity(); 22080bacfeb4bda06541e8695bd502229727bccfeaJean-Baptiste Queru perspective.setPerspY(SkScalarDiv(SK_Scalar1, SkIntToScalar(1000))); 22180bacfeb4bda06541e8695bd502229727bccfeaJean-Baptiste Queru perspective.setSkewX(SkScalarDiv(SkIntToScalar(8), SkIntToScalar(25))); 22280bacfeb4bda06541e8695bd502229727bccfeaJean-Baptiste Queru canvas->concat(perspective); 22380bacfeb4bda06541e8695bd502229727bccfeaJean-Baptiste Queru INHERITED::onDraw(canvas); 22480bacfeb4bda06541e8695bd502229727bccfeaJean-Baptiste Queru } 22580bacfeb4bda06541e8695bd502229727bccfeaJean-Baptiste Queru 22680bacfeb4bda06541e8695bd502229727bccfeaJean-Baptiste Queruprivate: 22780bacfeb4bda06541e8695bd502229727bccfeaJean-Baptiste Queru typedef GradientsGM INHERITED; 22880bacfeb4bda06541e8695bd502229727bccfeaJean-Baptiste Queru}; 22980bacfeb4bda06541e8695bd502229727bccfeaJean-Baptiste Queru 23080bacfeb4bda06541e8695bd502229727bccfeaJean-Baptiste Queru/* 23180bacfeb4bda06541e8695bd502229727bccfeaJean-Baptiste Queru Inspired by this <canvas> javascript, where we need to detect that we are not 23280bacfeb4bda06541e8695bd502229727bccfeaJean-Baptiste Queru solving a quadratic equation, but must instead solve a linear (since our X^2 23380bacfeb4bda06541e8695bd502229727bccfeaJean-Baptiste Queru coefficient is 0) 23480bacfeb4bda06541e8695bd502229727bccfeaJean-Baptiste Queru 23580bacfeb4bda06541e8695bd502229727bccfeaJean-Baptiste Queru ctx.fillStyle = '#f00'; 23680bacfeb4bda06541e8695bd502229727bccfeaJean-Baptiste Queru ctx.fillRect(0, 0, 100, 50); 23780bacfeb4bda06541e8695bd502229727bccfeaJean-Baptiste Queru 23880bacfeb4bda06541e8695bd502229727bccfeaJean-Baptiste Queru var g = ctx.createRadialGradient(-80, 25, 70, 0, 25, 150); 23980bacfeb4bda06541e8695bd502229727bccfeaJean-Baptiste Queru g.addColorStop(0, '#f00'); 24080bacfeb4bda06541e8695bd502229727bccfeaJean-Baptiste Queru g.addColorStop(0.01, '#0f0'); 24180bacfeb4bda06541e8695bd502229727bccfeaJean-Baptiste Queru g.addColorStop(0.99, '#0f0'); 24280bacfeb4bda06541e8695bd502229727bccfeaJean-Baptiste Queru g.addColorStop(1, '#f00'); 24380bacfeb4bda06541e8695bd502229727bccfeaJean-Baptiste Queru ctx.fillStyle = g; 24480bacfeb4bda06541e8695bd502229727bccfeaJean-Baptiste Queru ctx.fillRect(0, 0, 100, 50); 24580bacfeb4bda06541e8695bd502229727bccfeaJean-Baptiste Queru */ 24680bacfeb4bda06541e8695bd502229727bccfeaJean-Baptiste Queruclass GradientsDegenrate2PointGM : public GM { 24780bacfeb4bda06541e8695bd502229727bccfeaJean-Baptiste Querupublic: 24880bacfeb4bda06541e8695bd502229727bccfeaJean-Baptiste Queru GradientsDegenrate2PointGM() {} 24980bacfeb4bda06541e8695bd502229727bccfeaJean-Baptiste Queru 25080bacfeb4bda06541e8695bd502229727bccfeaJean-Baptiste Queruprotected: 25180bacfeb4bda06541e8695bd502229727bccfeaJean-Baptiste Queru SkString onShortName() { 25280bacfeb4bda06541e8695bd502229727bccfeaJean-Baptiste Queru return SkString("gradients_degenerate_2pt"); 25380bacfeb4bda06541e8695bd502229727bccfeaJean-Baptiste Queru } 25480bacfeb4bda06541e8695bd502229727bccfeaJean-Baptiste Queru 25580bacfeb4bda06541e8695bd502229727bccfeaJean-Baptiste Queru virtual SkISize onISize() { return make_isize(320, 320); } 25680bacfeb4bda06541e8695bd502229727bccfeaJean-Baptiste Queru 25780bacfeb4bda06541e8695bd502229727bccfeaJean-Baptiste Queru void drawBG(SkCanvas* canvas) { 25880bacfeb4bda06541e8695bd502229727bccfeaJean-Baptiste Queru canvas->drawColor(SK_ColorBLUE); 25980bacfeb4bda06541e8695bd502229727bccfeaJean-Baptiste Queru } 26080bacfeb4bda06541e8695bd502229727bccfeaJean-Baptiste Queru 26180bacfeb4bda06541e8695bd502229727bccfeaJean-Baptiste Queru virtual void onDraw(SkCanvas* canvas) { 26280bacfeb4bda06541e8695bd502229727bccfeaJean-Baptiste Queru this->drawBG(canvas); 26380bacfeb4bda06541e8695bd502229727bccfeaJean-Baptiste Queru 26480bacfeb4bda06541e8695bd502229727bccfeaJean-Baptiste Queru SkColor colors[] = { SK_ColorRED, SK_ColorGREEN, SK_ColorGREEN, SK_ColorRED }; 26580bacfeb4bda06541e8695bd502229727bccfeaJean-Baptiste Queru SkScalar pos[] = { 0, SkFloatToScalar(0.01f), SkFloatToScalar(0.99f), SK_Scalar1 }; 26680bacfeb4bda06541e8695bd502229727bccfeaJean-Baptiste Queru SkPoint c0; 26780bacfeb4bda06541e8695bd502229727bccfeaJean-Baptiste Queru c0.iset(-80, 25); 26880bacfeb4bda06541e8695bd502229727bccfeaJean-Baptiste Queru SkScalar r0 = SkIntToScalar(70); 26980bacfeb4bda06541e8695bd502229727bccfeaJean-Baptiste Queru SkPoint c1; 27080bacfeb4bda06541e8695bd502229727bccfeaJean-Baptiste Queru c1.iset(0, 25); 27180bacfeb4bda06541e8695bd502229727bccfeaJean-Baptiste Queru SkScalar r1 = SkIntToScalar(150); 27280bacfeb4bda06541e8695bd502229727bccfeaJean-Baptiste Queru SkShader* s = SkGradientShader::CreateTwoPointRadial(c0, r0, c1, r1, colors, 27380bacfeb4bda06541e8695bd502229727bccfeaJean-Baptiste Queru pos, SK_ARRAY_COUNT(pos), 27480bacfeb4bda06541e8695bd502229727bccfeaJean-Baptiste Queru SkShader::kClamp_TileMode); 27580bacfeb4bda06541e8695bd502229727bccfeaJean-Baptiste Queru SkPaint paint; 27680bacfeb4bda06541e8695bd502229727bccfeaJean-Baptiste Queru paint.setShader(s)->unref(); 27780bacfeb4bda06541e8695bd502229727bccfeaJean-Baptiste Queru canvas->drawPaint(paint); 27880bacfeb4bda06541e8695bd502229727bccfeaJean-Baptiste Queru } 27980bacfeb4bda06541e8695bd502229727bccfeaJean-Baptiste Queru 28080bacfeb4bda06541e8695bd502229727bccfeaJean-Baptiste Queruprivate: 28180bacfeb4bda06541e8695bd502229727bccfeaJean-Baptiste Queru typedef GM INHERITED; 28280bacfeb4bda06541e8695bd502229727bccfeaJean-Baptiste Queru}; 28380bacfeb4bda06541e8695bd502229727bccfeaJean-Baptiste Queru 28480bacfeb4bda06541e8695bd502229727bccfeaJean-Baptiste Queru/// Tests correctness of *optimized* codepaths in gradients. 28580bacfeb4bda06541e8695bd502229727bccfeaJean-Baptiste Queru 28680bacfeb4bda06541e8695bd502229727bccfeaJean-Baptiste Queruclass ClampedGradientsGM : public GM { 28780bacfeb4bda06541e8695bd502229727bccfeaJean-Baptiste Querupublic: 28880bacfeb4bda06541e8695bd502229727bccfeaJean-Baptiste Queru ClampedGradientsGM() {} 28980bacfeb4bda06541e8695bd502229727bccfeaJean-Baptiste Queru 29080bacfeb4bda06541e8695bd502229727bccfeaJean-Baptiste Queruprotected: 29180bacfeb4bda06541e8695bd502229727bccfeaJean-Baptiste Queru SkString onShortName() { return SkString("clamped_gradients"); } 29280bacfeb4bda06541e8695bd502229727bccfeaJean-Baptiste Queru 29380bacfeb4bda06541e8695bd502229727bccfeaJean-Baptiste Queru virtual SkISize onISize() { return make_isize(640, 510); } 29480bacfeb4bda06541e8695bd502229727bccfeaJean-Baptiste Queru 29580bacfeb4bda06541e8695bd502229727bccfeaJean-Baptiste Queru void drawBG(SkCanvas* canvas) { 29680bacfeb4bda06541e8695bd502229727bccfeaJean-Baptiste Queru canvas->drawColor(0xFFDDDDDD); 29780bacfeb4bda06541e8695bd502229727bccfeaJean-Baptiste Queru } 29880bacfeb4bda06541e8695bd502229727bccfeaJean-Baptiste Queru 29980bacfeb4bda06541e8695bd502229727bccfeaJean-Baptiste Queru virtual void onDraw(SkCanvas* canvas) { 30080bacfeb4bda06541e8695bd502229727bccfeaJean-Baptiste Queru this->drawBG(canvas); 30180bacfeb4bda06541e8695bd502229727bccfeaJean-Baptiste Queru 30280bacfeb4bda06541e8695bd502229727bccfeaJean-Baptiste Queru SkRect r = { 0, 0, SkIntToScalar(100), SkIntToScalar(300) }; 30380bacfeb4bda06541e8695bd502229727bccfeaJean-Baptiste Queru SkPaint paint; 30480bacfeb4bda06541e8695bd502229727bccfeaJean-Baptiste Queru paint.setAntiAlias(true); 30580bacfeb4bda06541e8695bd502229727bccfeaJean-Baptiste Queru 30680bacfeb4bda06541e8695bd502229727bccfeaJean-Baptiste Queru SkPoint center; 30780bacfeb4bda06541e8695bd502229727bccfeaJean-Baptiste Queru center.iset(0, 300); 30880bacfeb4bda06541e8695bd502229727bccfeaJean-Baptiste Queru canvas->translate(SkIntToScalar(20), SkIntToScalar(20)); 30980bacfeb4bda06541e8695bd502229727bccfeaJean-Baptiste Queru SkShader* shader = SkGradientShader::CreateRadial( 31080bacfeb4bda06541e8695bd502229727bccfeaJean-Baptiste Queru SkPoint(center), 31180bacfeb4bda06541e8695bd502229727bccfeaJean-Baptiste Queru SkIntToScalar(200), gColors, NULL, 5, 31280bacfeb4bda06541e8695bd502229727bccfeaJean-Baptiste Queru SkShader::kClamp_TileMode, NULL); 31380bacfeb4bda06541e8695bd502229727bccfeaJean-Baptiste Queru paint.setShader(shader); 31480bacfeb4bda06541e8695bd502229727bccfeaJean-Baptiste Queru canvas->drawRect(r, paint); 31580bacfeb4bda06541e8695bd502229727bccfeaJean-Baptiste Queru shader->unref(); 31680bacfeb4bda06541e8695bd502229727bccfeaJean-Baptiste Queru } 31780bacfeb4bda06541e8695bd502229727bccfeaJean-Baptiste Queru 31880bacfeb4bda06541e8695bd502229727bccfeaJean-Baptiste Queruprivate: 31980bacfeb4bda06541e8695bd502229727bccfeaJean-Baptiste Queru typedef GM INHERITED; 32080bacfeb4bda06541e8695bd502229727bccfeaJean-Baptiste Queru}; 32180bacfeb4bda06541e8695bd502229727bccfeaJean-Baptiste Queru 32280bacfeb4bda06541e8695bd502229727bccfeaJean-Baptiste Queru/// Checks quality of large radial gradients, which may display 32380bacfeb4bda06541e8695bd502229727bccfeaJean-Baptiste Queru/// some banding. 32480bacfeb4bda06541e8695bd502229727bccfeaJean-Baptiste Queru 32580bacfeb4bda06541e8695bd502229727bccfeaJean-Baptiste Queruclass RadialGradientGM : public GM { 32680bacfeb4bda06541e8695bd502229727bccfeaJean-Baptiste Querupublic: 32780bacfeb4bda06541e8695bd502229727bccfeaJean-Baptiste Queru RadialGradientGM() {} 32880bacfeb4bda06541e8695bd502229727bccfeaJean-Baptiste Queru 32980bacfeb4bda06541e8695bd502229727bccfeaJean-Baptiste Queruprotected: 33080bacfeb4bda06541e8695bd502229727bccfeaJean-Baptiste Queru SkString onShortName() { return SkString("radial_gradient"); } 33180bacfeb4bda06541e8695bd502229727bccfeaJean-Baptiste Queru virtual SkISize onISize() { return make_isize(1280, 1280); } 33280bacfeb4bda06541e8695bd502229727bccfeaJean-Baptiste Queru void drawBG(SkCanvas* canvas) { 33380bacfeb4bda06541e8695bd502229727bccfeaJean-Baptiste Queru canvas->drawColor(0xFF000000); 33480bacfeb4bda06541e8695bd502229727bccfeaJean-Baptiste Queru } 33580bacfeb4bda06541e8695bd502229727bccfeaJean-Baptiste Queru virtual void onDraw(SkCanvas* canvas) { 33680bacfeb4bda06541e8695bd502229727bccfeaJean-Baptiste Queru const SkISize dim = this->getISize(); 33780bacfeb4bda06541e8695bd502229727bccfeaJean-Baptiste Queru 33880bacfeb4bda06541e8695bd502229727bccfeaJean-Baptiste Queru this->drawBG(canvas); 33980bacfeb4bda06541e8695bd502229727bccfeaJean-Baptiste Queru 34080bacfeb4bda06541e8695bd502229727bccfeaJean-Baptiste Queru SkPaint paint; 34180bacfeb4bda06541e8695bd502229727bccfeaJean-Baptiste Queru paint.setDither(true); 34280bacfeb4bda06541e8695bd502229727bccfeaJean-Baptiste Queru SkPoint center; 34380bacfeb4bda06541e8695bd502229727bccfeaJean-Baptiste Queru center.set(SkIntToScalar(dim.width())/2, SkIntToScalar(dim.height())/2); 34480bacfeb4bda06541e8695bd502229727bccfeaJean-Baptiste Queru SkScalar radius = SkIntToScalar(dim.width())/2; 34580bacfeb4bda06541e8695bd502229727bccfeaJean-Baptiste Queru const SkColor colors[] = { 0x7f7f7f7f, 0x7f7f7f7f, 0xb2000000 }; 34680bacfeb4bda06541e8695bd502229727bccfeaJean-Baptiste Queru const SkScalar pos[] = { SkFloatToScalar(0.0f), 34780bacfeb4bda06541e8695bd502229727bccfeaJean-Baptiste Queru SkFloatToScalar(0.35f), 34880bacfeb4bda06541e8695bd502229727bccfeaJean-Baptiste Queru SkFloatToScalar(1.0f) }; 34980bacfeb4bda06541e8695bd502229727bccfeaJean-Baptiste Queru SkShader* shader = 35080bacfeb4bda06541e8695bd502229727bccfeaJean-Baptiste Queru SkGradientShader::CreateRadial(center, radius, colors, 35180bacfeb4bda06541e8695bd502229727bccfeaJean-Baptiste Queru pos, SK_ARRAY_COUNT(pos), 35280bacfeb4bda06541e8695bd502229727bccfeaJean-Baptiste Queru SkShader::kClamp_TileMode); 35380bacfeb4bda06541e8695bd502229727bccfeaJean-Baptiste Queru paint.setShader(shader)->unref(); 35480bacfeb4bda06541e8695bd502229727bccfeaJean-Baptiste Queru SkRect r = { 35580bacfeb4bda06541e8695bd502229727bccfeaJean-Baptiste Queru 0, 0, SkIntToScalar(dim.width()), SkIntToScalar(dim.height()) 35680bacfeb4bda06541e8695bd502229727bccfeaJean-Baptiste Queru }; 35780bacfeb4bda06541e8695bd502229727bccfeaJean-Baptiste Queru canvas->drawRect(r, paint); 35880bacfeb4bda06541e8695bd502229727bccfeaJean-Baptiste Queru } 35980bacfeb4bda06541e8695bd502229727bccfeaJean-Baptiste Queruprivate: 36080bacfeb4bda06541e8695bd502229727bccfeaJean-Baptiste Queru typedef GM INHERITED; 36180bacfeb4bda06541e8695bd502229727bccfeaJean-Baptiste Queru}; 36280bacfeb4bda06541e8695bd502229727bccfeaJean-Baptiste Queru 36380bacfeb4bda06541e8695bd502229727bccfeaJean-Baptiste Queru 36480bacfeb4bda06541e8695bd502229727bccfeaJean-Baptiste Queru 36580bacfeb4bda06541e8695bd502229727bccfeaJean-Baptiste Queru/////////////////////////////////////////////////////////////////////////////// 36680bacfeb4bda06541e8695bd502229727bccfeaJean-Baptiste Queru 36780bacfeb4bda06541e8695bd502229727bccfeaJean-Baptiste Querustatic GM* MyFactory(void*) { return new GradientsGM; } 36880bacfeb4bda06541e8695bd502229727bccfeaJean-Baptiste Querustatic GMRegistry reg(MyFactory); 36980bacfeb4bda06541e8695bd502229727bccfeaJean-Baptiste Queru 37080bacfeb4bda06541e8695bd502229727bccfeaJean-Baptiste Querustatic GM* MyFactory2(void*) { return new GradientsDegenrate2PointGM; } 37180bacfeb4bda06541e8695bd502229727bccfeaJean-Baptiste Querustatic GMRegistry reg2(MyFactory2); 37280bacfeb4bda06541e8695bd502229727bccfeaJean-Baptiste Queru 37380bacfeb4bda06541e8695bd502229727bccfeaJean-Baptiste Querustatic GM* MyFactory3(void*) { return new ClampedGradientsGM; } 37480bacfeb4bda06541e8695bd502229727bccfeaJean-Baptiste Querustatic GMRegistry reg3(MyFactory3); 37580bacfeb4bda06541e8695bd502229727bccfeaJean-Baptiste Queru 37680bacfeb4bda06541e8695bd502229727bccfeaJean-Baptiste Querustatic GM* MyFactory4(void*) { return new RadialGradientGM; } 37780bacfeb4bda06541e8695bd502229727bccfeaJean-Baptiste Querustatic GMRegistry reg4(MyFactory4); 37880bacfeb4bda06541e8695bd502229727bccfeaJean-Baptiste Queru 37980bacfeb4bda06541e8695bd502229727bccfeaJean-Baptiste Querustatic GM* MyFactory5(void*) { return new GradientsLocalPerspectiveGM; } 38080bacfeb4bda06541e8695bd502229727bccfeaJean-Baptiste Querustatic GMRegistry reg5(MyFactory5); 38180bacfeb4bda06541e8695bd502229727bccfeaJean-Baptiste Queru 38280bacfeb4bda06541e8695bd502229727bccfeaJean-Baptiste Querustatic GM* MyFactory6(void*) { return new GradientsViewPerspectiveGM; } 38380bacfeb4bda06541e8695bd502229727bccfeaJean-Baptiste Querustatic GMRegistry reg6(MyFactory6); 38480bacfeb4bda06541e8695bd502229727bccfeaJean-Baptiste Queru} 385