• Home
  • Line#
  • Scopes#
  • Navigate#
  • Raw
  • Download
1 /*
2  * Copyright 2015 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 "include/core/SkCanvas.h"
9 #include "include/core/SkFont.h"
10 #include "include/core/SkRSXform.h"
11 #include "include/core/SkSurface.h"
12 #include "samplecode/Sample.h"
13 #include "src/core/SkPaintPriv.h"
14 #include "tools/Resources.h"
15 #include "tools/timer/Timer.h"
16 
17 #include <stdio.h>
18 
19 static const int kGrid = 100;
20 static const int kWidth = 960;
21 static const int kHeight = 640;
22 
23 typedef void (*DrawAtlasProc)(SkCanvas*, SkImage*, const SkRSXform[], const SkRect[],
24 const SkColor[], int, const SkRect*, const SkSamplingOptions&, const SkPaint*);
25 
draw_atlas(SkCanvas * canvas,SkImage * atlas,const SkRSXform xform[],const SkRect tex[],const SkColor colors[],int count,const SkRect * cull,const SkSamplingOptions & sampling,const SkPaint * paint)26 static void draw_atlas(SkCanvas* canvas, SkImage* atlas, const SkRSXform xform[],
27                        const SkRect tex[], const SkColor colors[], int count, const SkRect* cull,
28                        const SkSamplingOptions& sampling, const SkPaint* paint) {
29     canvas->drawAtlas(atlas, xform, tex, colors, count, SkBlendMode::kModulate, sampling,
30                       cull, paint);
31 }
32 
draw_atlas_sim(SkCanvas * canvas,SkImage * atlas,const SkRSXform xform[],const SkRect tex[],const SkColor colors[],int count,const SkRect * cull,const SkSamplingOptions & sampling,const SkPaint * paint)33 static void draw_atlas_sim(SkCanvas* canvas, SkImage* atlas, const SkRSXform xform[],
34                            const SkRect tex[], const SkColor colors[], int count, const SkRect* cull,
35                            const SkSamplingOptions& sampling, const SkPaint* paint) {
36     for (int i = 0; i < count; ++i) {
37         SkMatrix matrix;
38         matrix.setRSXform(xform[i]);
39 
40         canvas->save();
41         canvas->concat(matrix);
42         canvas->drawImageRect(atlas, tex[i], tex[i].makeOffset(-tex[i].x(), -tex[i].y()),
43                               sampling, paint, SkCanvas::kFast_SrcRectConstraint);
44         canvas->restore();
45     }
46 }
47 
48 
49 class DrawShipView : public Sample {
50 public:
DrawShipView(const char name[],DrawAtlasProc proc)51     DrawShipView(const char name[], DrawAtlasProc proc) : fName(name), fProc(proc) {
52         fAtlas = GetResourceAsImage("images/ship.png");
53         if (!fAtlas) {
54             SkDebugf("\nCould not decode file ship.png. Falling back to penguin mode.\n");
55             fAtlas = GetResourceAsImage("images/baby_tux.png");
56             if (!fAtlas) {
57                 SkDebugf("\nCould not decode file baby_tux.png. Did you forget"
58                          " to set the resourcePath?\n");
59                 return;
60             }
61         }
62 
63         SkScalar anchorX = fAtlas->width()*0.5f;
64         SkScalar anchorY = fAtlas->height()*0.5f;
65         int currIndex = 0;
66         for (int x = 0; x < kGrid; x++) {
67             for (int y = 0; y < kGrid; y++) {
68                 float xPos = (x / (kGrid - 1.0f)) * kWidth;
69                 float yPos = (y / (kGrid - 1.0f)) * kWidth;
70 
71                 fTex[currIndex] = SkRect::MakeLTRB(0.0f, 0.0f,
72                                                    SkIntToScalar(fAtlas->width()),
73                                                    SkIntToScalar(fAtlas->height()));
74                 fXform[currIndex] = SkRSXform::MakeFromRadians(0.1f, SK_ScalarPI*0.5f,
75                                                                xPos, yPos, anchorX, anchorY);
76                 currIndex++;
77             }
78         }
79         fTex[currIndex] = SkRect::MakeLTRB(0.0f, 0.0f,
80                                            SkIntToScalar(fAtlas->width()),
81                                            SkIntToScalar(fAtlas->height()));
82         fXform[currIndex] = SkRSXform::MakeFromRadians(0.5f, SK_ScalarPI*0.5f,
83                                                        kWidth*0.5f, kHeight*0.5f, anchorX, anchorY);
84 
85     }
86 
~DrawShipView()87     ~DrawShipView() override {}
88 
89 protected:
name()90     SkString name() override { return SkString(fName); }
91 
onDrawContent(SkCanvas * canvas)92     void onDrawContent(SkCanvas* canvas) override {
93         const float kCosDiff = 0.99984769515f;
94         const float kSinDiff = 0.01745240643f;
95 
96         if (!fAtlas) {
97             return;
98         }
99 
100         SkPaint paint;
101         paint.setColor(SK_ColorWHITE);
102 
103         SkScalar anchorX = fAtlas->width()*0.5f;
104         SkScalar anchorY = fAtlas->height()*0.5f;
105         for (int i = 0; i < kGrid*kGrid+1; ++i) {
106             SkScalar c = fXform[i].fSCos;
107             SkScalar s = fXform[i].fSSin;
108 
109             SkScalar dx = c*anchorX - s*anchorY;
110             SkScalar dy = s*anchorX + c*anchorY;
111 
112             fXform[i].fSCos = kCosDiff*c - kSinDiff*s;
113             fXform[i].fSSin = kSinDiff*c + kCosDiff*s;
114 
115             dx -= fXform[i].fSCos*anchorX - fXform[i].fSSin*anchorY;
116             dy -= fXform[i].fSSin*anchorX + fXform[i].fSCos*anchorY;
117             fXform[i].fTx += dx;
118             fXform[i].fTy += dy;
119         }
120 
121         fProc(canvas, fAtlas.get(), fXform, fTex, nullptr, kGrid*kGrid+1, nullptr,
122               SkSamplingOptions(SkFilterMode::kLinear), &paint);
123     }
124 
onAnimate(double nanos)125     bool onAnimate(double nanos) override {
126         //TODO: use nanos
127         //SkScalar angle = SkDoubleToScalar(fmod(1e-9 * nanos * 360 / 24, 360));
128         //fAnimatingDrawable->setSweep(angle);
129         return true;
130     }
131 
132 private:
133     const char*         fName;
134     DrawAtlasProc       fProc;
135 
136     sk_sp<SkImage> fAtlas;
137     SkRSXform   fXform[kGrid*kGrid+1];
138     SkRect      fTex[kGrid*kGrid+1];
139 
140     using INHERITED = Sample;
141 };
142 
143 //////////////////////////////////////////////////////////////////////////////
144 
145 DEF_SAMPLE( return new DrawShipView("DrawShip", draw_atlas); )
146 DEF_SAMPLE( return new DrawShipView("DrawShipSim", draw_atlas_sim); )
147