207 lines
		
	
	
		
			6.9 KiB
		
	
	
	
		
			C++
		
	
	
	
			
		
		
	
	
			207 lines
		
	
	
		
			6.9 KiB
		
	
	
	
		
			C++
		
	
	
	
| /*
 | |
|  * Copyright 2014 Google Inc.
 | |
|  *
 | |
|  * Use of this source code is governed by a BSD-style license that can be
 | |
|  * found in the LICENSE file.
 | |
|  */
 | |
| 
 | |
| #include "gm/gm.h"
 | |
| #include "include/core/SkBlendMode.h"
 | |
| #include "include/core/SkCanvas.h"
 | |
| #include "include/core/SkColor.h"
 | |
| #include "include/core/SkImage.h"
 | |
| #include "include/core/SkPaint.h"
 | |
| #include "include/core/SkPath.h"
 | |
| #include "include/core/SkPoint.h"
 | |
| #include "include/core/SkRefCnt.h"
 | |
| #include "include/core/SkScalar.h"
 | |
| #include "include/core/SkShader.h"
 | |
| #include "include/core/SkTileMode.h"
 | |
| #include "include/core/SkTypes.h"
 | |
| #include "include/effects/SkGradientShader.h"
 | |
| #include "src/utils/SkPatchUtils.h"
 | |
| #include "tools/Resources.h"
 | |
| 
 | |
| static sk_sp<SkShader> make_shader() {
 | |
|     const SkColor colors[] = {
 | |
|         SK_ColorRED, SK_ColorCYAN, SK_ColorGREEN, SK_ColorWHITE, SK_ColorMAGENTA, SK_ColorBLUE,
 | |
|         SK_ColorYELLOW,
 | |
|     };
 | |
|     const SkPoint pts[] = { { 100.f / 4.f, 0.f }, { 3.f * 100.f / 4.f, 100.f } };
 | |
| 
 | |
|     return SkGradientShader::MakeLinear(pts, colors, nullptr, SK_ARRAY_COUNT(colors),
 | |
|                                         SkTileMode::kMirror);
 | |
| }
 | |
| 
 | |
| static void draw_control_points(SkCanvas* canvas, const SkPoint cubics[12]) {
 | |
|     //draw control points
 | |
|     SkPaint paint;
 | |
|     SkPoint bottom[SkPatchUtils::kNumPtsCubic];
 | |
|     SkPatchUtils::GetBottomCubic(cubics, bottom);
 | |
|     SkPoint top[SkPatchUtils::kNumPtsCubic];
 | |
|     SkPatchUtils::GetTopCubic(cubics, top);
 | |
|     SkPoint left[SkPatchUtils::kNumPtsCubic];
 | |
|     SkPatchUtils::GetLeftCubic(cubics, left);
 | |
|     SkPoint right[SkPatchUtils::kNumPtsCubic];
 | |
|     SkPatchUtils::GetRightCubic(cubics, right);
 | |
| 
 | |
|     paint.setColor(SK_ColorBLACK);
 | |
|     paint.setStrokeWidth(0.5f);
 | |
|     SkPoint corners[4] = { bottom[0], bottom[3], top[0], top[3] };
 | |
|     canvas->drawPoints(SkCanvas::kLines_PointMode, 4, bottom, paint);
 | |
|     canvas->drawPoints(SkCanvas::kLines_PointMode, 2, bottom + 1, paint);
 | |
|     canvas->drawPoints(SkCanvas::kLines_PointMode, 4, top, paint);
 | |
|     canvas->drawPoints(SkCanvas::kLines_PointMode, 4, left, paint);
 | |
|     canvas->drawPoints(SkCanvas::kLines_PointMode, 4, right, paint);
 | |
| 
 | |
|     canvas->drawPoints(SkCanvas::kLines_PointMode, 2, top + 1, paint);
 | |
|     canvas->drawPoints(SkCanvas::kLines_PointMode, 2, left + 1, paint);
 | |
|     canvas->drawPoints(SkCanvas::kLines_PointMode, 2, right + 1, paint);
 | |
| 
 | |
|     paint.setStrokeWidth(2);
 | |
| 
 | |
|     paint.setColor(SK_ColorRED);
 | |
|     canvas->drawPoints(SkCanvas::kPoints_PointMode, 4, corners, paint);
 | |
| 
 | |
|     paint.setColor(SK_ColorBLUE);
 | |
|     canvas->drawPoints(SkCanvas::kPoints_PointMode, 2, bottom + 1, paint);
 | |
| 
 | |
|     paint.setColor(SK_ColorCYAN);
 | |
|     canvas->drawPoints(SkCanvas::kPoints_PointMode, 2, top + 1, paint);
 | |
| 
 | |
|     paint.setColor(SK_ColorYELLOW);
 | |
|     canvas->drawPoints(SkCanvas::kPoints_PointMode, 2, left + 1, paint);
 | |
| 
 | |
|     paint.setColor(SK_ColorGREEN);
 | |
|     canvas->drawPoints(SkCanvas::kPoints_PointMode, 2, right + 1, paint);
 | |
| }
 | |
| 
 | |
| // The order of the colors and points is clockwise starting at upper-left corner.
 | |
| const SkPoint gCubics[SkPatchUtils::kNumCtrlPts] = {
 | |
|     //top points
 | |
|     {100,100},{150,50},{250,150}, {300,100},
 | |
|     //right points
 | |
|     {250, 150},{350,250},
 | |
|     //bottom points
 | |
|     {300,300},{250,250},{150,350},{100,300},
 | |
|     //left points
 | |
|     {50,250},{150,150}
 | |
| };
 | |
| 
 | |
| const SkPoint gTexCoords[SkPatchUtils::kNumCorners] = {
 | |
|     {0.0f, 0.0f}, {100.0f, 0.0f}, {100.0f,100.0f}, {0.0f, 100.0f}
 | |
| };
 | |
| 
 | |
| 
 | |
| static void dopatch(SkCanvas* canvas, const SkColor colors[], sk_sp<SkImage> img,
 | |
|                     const SkMatrix* localMatrix) {
 | |
|     SkPaint paint;
 | |
|     paint.setColor(SK_ColorGREEN);
 | |
| 
 | |
|     const SkBlendMode modes[] = {
 | |
|         SkBlendMode::kSrc,
 | |
|         SkBlendMode::kDst,
 | |
|         SkBlendMode::kColorDodge,
 | |
|     };
 | |
| 
 | |
|     SkPoint texStorage[4];
 | |
|     const SkPoint* tex = gTexCoords;
 | |
| 
 | |
|     sk_sp<SkShader> shader;
 | |
|     if (img) {
 | |
|         SkScalar w = img->width();
 | |
|         SkScalar h = img->height();
 | |
|         shader = img->makeShader(SkSamplingOptions(), localMatrix);
 | |
|         texStorage[0].set(0, 0);
 | |
|         texStorage[1].set(w, 0);
 | |
|         texStorage[2].set(w, h);
 | |
|         texStorage[3].set(0, h);
 | |
|         tex = texStorage;
 | |
|     } else {
 | |
|         shader = make_shader();
 | |
|     }
 | |
| 
 | |
|     canvas->save();
 | |
|     for (int y = 0; y < 3; y++) {
 | |
|         for (int x = 0; x < 4; x++) {
 | |
|             canvas->save();
 | |
|             canvas->translate(x * 350.0f, y * 350.0f);
 | |
|             switch (x) {
 | |
|                 case 0:
 | |
|                     canvas->drawPatch(gCubics, nullptr, nullptr, modes[y], paint);
 | |
|                     break;
 | |
|                 case 1:
 | |
|                     canvas->drawPatch(gCubics, colors, nullptr, modes[y], paint);
 | |
|                     break;
 | |
|                 case 2:
 | |
|                     paint.setShader(shader);
 | |
|                     canvas->drawPatch(gCubics, nullptr, tex, modes[y], paint);
 | |
|                     paint.setShader(nullptr);
 | |
|                     break;
 | |
|                 case 3:
 | |
|                     paint.setShader(shader);
 | |
|                     canvas->drawPatch(gCubics, colors, tex, modes[y], paint);
 | |
|                     paint.setShader(nullptr);
 | |
|                     break;
 | |
|                 default:
 | |
|                     break;
 | |
|             }
 | |
| 
 | |
|             draw_control_points(canvas, gCubics);
 | |
|             canvas->restore();
 | |
|         }
 | |
|     }
 | |
|     canvas->restore();
 | |
| }
 | |
| 
 | |
| DEF_SIMPLE_GM(patch_primitive, canvas, 1500, 1100) {
 | |
|     const SkColor colors[SkPatchUtils::kNumCorners] = {
 | |
|         SK_ColorRED, SK_ColorGREEN, SK_ColorBLUE, SK_ColorCYAN
 | |
|     };
 | |
|     dopatch(canvas, colors, nullptr, nullptr);
 | |
| }
 | |
| DEF_SIMPLE_GM(patch_image, canvas, 1500, 1100) {
 | |
|     const SkColor colors[SkPatchUtils::kNumCorners] = {
 | |
|         SK_ColorRED, SK_ColorGREEN, SK_ColorBLUE, SK_ColorCYAN
 | |
|     };
 | |
|     dopatch(canvas, colors, GetResourceAsImage("images/mandrill_128.png"), nullptr);
 | |
| }
 | |
| DEF_SIMPLE_GM(patch_image_persp, canvas, 1500, 1100) {
 | |
|     const SkColor colors[SkPatchUtils::kNumCorners] = {
 | |
|         SK_ColorRED, SK_ColorGREEN, SK_ColorBLUE, SK_ColorCYAN
 | |
|     };
 | |
|     SkMatrix localM;
 | |
|     localM.reset();
 | |
|     localM[6] = 0.00001f;    // force perspective
 | |
|     dopatch(canvas, colors, GetResourceAsImage("images/mandrill_128.png"), &localM);
 | |
| }
 | |
| DEF_SIMPLE_GM(patch_alpha, canvas, 1500, 1100) {
 | |
|     const SkColor colors[SkPatchUtils::kNumCorners] = {
 | |
|         SK_ColorRED, 0x0000FF00, SK_ColorBLUE, 0x00FF00FF,
 | |
|     };
 | |
|     dopatch(canvas, colors, nullptr, nullptr);
 | |
| }
 | |
| 
 | |
| // These two should look the same (one patch, one simple path)
 | |
| DEF_SIMPLE_GM(patch_alpha_test, canvas, 550, 250) {
 | |
|     canvas->translate(-75, -75);
 | |
| 
 | |
|     const SkColor colors[SkPatchUtils::kNumCorners] = {
 | |
|         0x80FF0000, 0x80FF0000, 0x80FF0000, 0x80FF0000,
 | |
|     };
 | |
|     SkPaint paint;
 | |
|     canvas->drawPatch(gCubics, colors, nullptr, SkBlendMode::kDst, paint);
 | |
| 
 | |
|     canvas->translate(300, 0);
 | |
| 
 | |
|     SkPath path;
 | |
|     path.moveTo(gCubics[0]);
 | |
|     path.cubicTo(gCubics[ 1], gCubics[ 2], gCubics[ 3]);
 | |
|     path.cubicTo(gCubics[ 4], gCubics[ 5], gCubics[ 6]);
 | |
|     path.cubicTo(gCubics[ 7], gCubics[ 8], gCubics[ 9]);
 | |
|     path.cubicTo(gCubics[10], gCubics[11], gCubics[ 0]);
 | |
|     paint.setColor(colors[0]);
 | |
|     canvas->drawPath(path, paint);
 | |
| }
 | |
| 
 |