Home | History | Annotate | Download | only in gm
      1 /*
      2  * Copyright 2014 Google Inc.
      3  *
      4  * Use of this source code is governed by a BSD-style license that can be
      5  * found in the LICENSE file.
      6  */
      7 
      8 #include "gm.h"
      9 #include "SkGradientShader.h"
     10 #include "SkImage.h"
     11 #include "SkPatchUtils.h"
     12 #include "SkPath.h"
     13 
     14 static sk_sp<SkShader> make_shader() {
     15     const SkColor colors[] = {
     16         SK_ColorRED, SK_ColorCYAN, SK_ColorGREEN, SK_ColorWHITE, SK_ColorMAGENTA, SK_ColorBLUE,
     17         SK_ColorYELLOW,
     18     };
     19     const SkPoint pts[] = { { 100.f / 4.f, 0.f }, { 3.f * 100.f / 4.f, 100.f } };
     20 
     21     return SkGradientShader::MakeLinear(pts, colors, nullptr, SK_ARRAY_COUNT(colors),
     22                                         SkShader::kMirror_TileMode);
     23 }
     24 
     25 static void draw_control_points(SkCanvas* canvas, const SkPoint cubics[12]) {
     26     //draw control points
     27     SkPaint paint;
     28     SkPoint bottom[SkPatchUtils::kNumPtsCubic];
     29     SkPatchUtils::GetBottomCubic(cubics, bottom);
     30     SkPoint top[SkPatchUtils::kNumPtsCubic];
     31     SkPatchUtils::GetTopCubic(cubics, top);
     32     SkPoint left[SkPatchUtils::kNumPtsCubic];
     33     SkPatchUtils::GetLeftCubic(cubics, left);
     34     SkPoint right[SkPatchUtils::kNumPtsCubic];
     35     SkPatchUtils::GetRightCubic(cubics, right);
     36 
     37     paint.setColor(SK_ColorBLACK);
     38     paint.setStrokeWidth(0.5f);
     39     SkPoint corners[4] = { bottom[0], bottom[3], top[0], top[3] };
     40     canvas->drawPoints(SkCanvas::kLines_PointMode, 4, bottom, paint);
     41     canvas->drawPoints(SkCanvas::kLines_PointMode, 2, bottom + 1, paint);
     42     canvas->drawPoints(SkCanvas::kLines_PointMode, 4, top, paint);
     43     canvas->drawPoints(SkCanvas::kLines_PointMode, 4, left, paint);
     44     canvas->drawPoints(SkCanvas::kLines_PointMode, 4, right, paint);
     45 
     46     canvas->drawPoints(SkCanvas::kLines_PointMode, 2, top + 1, paint);
     47     canvas->drawPoints(SkCanvas::kLines_PointMode, 2, left + 1, paint);
     48     canvas->drawPoints(SkCanvas::kLines_PointMode, 2, right + 1, paint);
     49 
     50     paint.setStrokeWidth(2);
     51 
     52     paint.setColor(SK_ColorRED);
     53     canvas->drawPoints(SkCanvas::kPoints_PointMode, 4, corners, paint);
     54 
     55     paint.setColor(SK_ColorBLUE);
     56     canvas->drawPoints(SkCanvas::kPoints_PointMode, 2, bottom + 1, paint);
     57 
     58     paint.setColor(SK_ColorCYAN);
     59     canvas->drawPoints(SkCanvas::kPoints_PointMode, 2, top + 1, paint);
     60 
     61     paint.setColor(SK_ColorYELLOW);
     62     canvas->drawPoints(SkCanvas::kPoints_PointMode, 2, left + 1, paint);
     63 
     64     paint.setColor(SK_ColorGREEN);
     65     canvas->drawPoints(SkCanvas::kPoints_PointMode, 2, right + 1, paint);
     66 }
     67 
     68 // The order of the colors and points is clockwise starting at upper-left corner.
     69 const SkPoint gCubics[SkPatchUtils::kNumCtrlPts] = {
     70     //top points
     71     {100,100},{150,50},{250,150}, {300,100},
     72     //right points
     73     {250, 150},{350,250},
     74     //bottom points
     75     {300,300},{250,250},{150,350},{100,300},
     76     //left points
     77     {50,250},{150,150}
     78 };
     79 
     80 const SkPoint gTexCoords[SkPatchUtils::kNumCorners] = {
     81     {0.0f, 0.0f}, {100.0f, 0.0f}, {100.0f,100.0f}, {0.0f, 100.0f}
     82 };
     83 
     84 
     85 static void dopatch(SkCanvas* canvas, const SkColor colors[], sk_sp<SkImage> img = nullptr) {
     86     SkPaint paint;
     87 
     88     const SkBlendMode modes[] = {
     89         SkBlendMode::kSrc,
     90         SkBlendMode::kDst,
     91         SkBlendMode::kModulate,
     92     };
     93 
     94     SkPoint texStorage[4];
     95     const SkPoint* tex = gTexCoords;
     96 
     97     sk_sp<SkShader> shader;
     98     if (img) {
     99         SkScalar w = img->width();
    100         SkScalar h = img->height();
    101         shader = img->makeShader(SkShader::kClamp_TileMode, SkShader::kClamp_TileMode);
    102         texStorage[0].set(0, 0);
    103         texStorage[1].set(w, 0);
    104         texStorage[2].set(w, h);
    105         texStorage[3].set(0, h);
    106         tex = texStorage;
    107     } else {
    108         shader = make_shader();
    109     }
    110 
    111     canvas->save();
    112     for (int y = 0; y < 3; y++) {
    113         for (int x = 0; x < 4; x++) {
    114             canvas->save();
    115             canvas->translate(x * 350.0f, y * 350.0f);
    116             switch (x) {
    117                 case 0:
    118                     canvas->drawPatch(gCubics, nullptr, nullptr, modes[y], paint);
    119                     break;
    120                 case 1:
    121                     canvas->drawPatch(gCubics, colors, nullptr, modes[y], paint);
    122                     break;
    123                 case 2:
    124                     paint.setShader(shader);
    125                     canvas->drawPatch(gCubics, nullptr, tex, modes[y], paint);
    126                     paint.setShader(nullptr);
    127                     break;
    128                 case 3:
    129                     paint.setShader(shader);
    130                     canvas->drawPatch(gCubics, colors, tex, modes[y], paint);
    131                     paint.setShader(nullptr);
    132                     break;
    133                 default:
    134                     break;
    135             }
    136 
    137             draw_control_points(canvas, gCubics);
    138             canvas->restore();
    139         }
    140     }
    141     canvas->restore();
    142 }
    143 
    144 DEF_SIMPLE_GM(patch_primitive, canvas, 1500, 1100) {
    145     const SkColor colors[SkPatchUtils::kNumCorners] = {
    146         SK_ColorRED, SK_ColorGREEN, SK_ColorBLUE, SK_ColorCYAN
    147     };
    148     dopatch(canvas, colors);
    149 }
    150 #include "Resources.h"
    151 DEF_SIMPLE_GM(patch_image, canvas, 1500, 1100) {
    152     const SkColor colors[SkPatchUtils::kNumCorners] = {
    153         SK_ColorRED, SK_ColorGREEN, SK_ColorBLUE, SK_ColorCYAN
    154     };
    155     dopatch(canvas, colors, GetResourceAsImage("images/mandrill_128.png"));
    156 }
    157 DEF_SIMPLE_GM(patch_alpha, canvas, 1500, 1100) {
    158     const SkColor colors[SkPatchUtils::kNumCorners] = {
    159         SK_ColorRED, 0x0000FF00, SK_ColorBLUE, 0x00FF00FF,
    160     };
    161     dopatch(canvas, colors);
    162 }
    163 
    164 // These two should look the same (one patch, one simple path)
    165 DEF_SIMPLE_GM(patch_alpha_test, canvas, 550, 250) {
    166     canvas->translate(-75, -75);
    167 
    168     const SkColor colors[SkPatchUtils::kNumCorners] = {
    169         0x80FF0000, 0x80FF0000, 0x80FF0000, 0x80FF0000,
    170     };
    171     SkPaint paint;
    172     canvas->drawPatch(gCubics, colors, nullptr, SkBlendMode::kModulate, paint);
    173 
    174     canvas->translate(300, 0);
    175 
    176     SkPath path;
    177     path.moveTo(gCubics[0]);
    178     path.cubicTo(gCubics[ 1], gCubics[ 2], gCubics[ 3]);
    179     path.cubicTo(gCubics[ 4], gCubics[ 5], gCubics[ 6]);
    180     path.cubicTo(gCubics[ 7], gCubics[ 8], gCubics[ 9]);
    181     path.cubicTo(gCubics[10], gCubics[11], gCubics[ 0]);
    182     paint.setColor(colors[0]);
    183     canvas->drawPath(path, paint);
    184 }
    185 
    186