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