1 /* 2 * Copyright 2011 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 "SampleCode.h" 9 #include "SkAnimTimer.h" 10 #include "SkView.h" 11 #include "SkCanvas.h" 12 #include "SkGradientShader.h" 13 #include "SkGraphics.h" 14 #include "SkImageDecoder.h" 15 #include "SkPath.h" 16 #include "SkRegion.h" 17 #include "SkShader.h" 18 #include "SkUtils.h" 19 #include "SkXfermode.h" 20 #include "SkColorPriv.h" 21 #include "SkColorFilter.h" 22 #include "SkTime.h" 23 #include "SkTypeface.h" 24 25 #include "SkOSFile.h" 26 #include "SkStream.h" 27 28 #define INT_SIZE 64 29 #define SCALAR_SIZE SkIntToScalar(INT_SIZE) 30 31 static void make_bitmap(SkBitmap* bitmap) { 32 bitmap->allocN32Pixels(INT_SIZE, INT_SIZE); 33 SkCanvas canvas(*bitmap); 34 35 canvas.drawColor(SK_ColorRED); 36 SkPaint paint; 37 paint.setAntiAlias(true); 38 const SkPoint pts[] = { { 0, 0 }, { SCALAR_SIZE, SCALAR_SIZE } }; 39 const SkColor colors[] = { SK_ColorWHITE, SK_ColorBLUE }; 40 paint.setShader(SkGradientShader::CreateLinear(pts, colors, NULL, 2, 41 SkShader::kClamp_TileMode))->unref(); 42 canvas.drawCircle(SCALAR_SIZE/2, SCALAR_SIZE/2, SCALAR_SIZE/2, paint); 43 } 44 45 static SkPoint unit_vec(int degrees) { 46 SkScalar rad = SkDegreesToRadians(SkIntToScalar(degrees)); 47 SkScalar s, c; 48 s = SkScalarSinCos(rad, &c); 49 return SkPoint::Make(c, s); 50 } 51 52 static void bounce(SkScalar* value, SkScalar* delta, SkScalar min, SkScalar max) { 53 *value += *delta; 54 if (*value < min) { 55 *value = min; 56 *delta = - *delta; 57 } else if (*value > max) { 58 *value = max; 59 *delta = - *delta; 60 } 61 } 62 63 static void bounce_pt(SkPoint* pt, SkVector* vec, const SkRect& limit) { 64 bounce(&pt->fX, &vec->fX, limit.fLeft, limit.fRight); 65 bounce(&pt->fY, &vec->fY, limit.fTop, limit.fBottom); 66 } 67 68 class BitmapRectView : public SampleView { 69 SkPoint fSrcPts[2]; 70 SkPoint fSrcVec[2]; 71 SkRect fSrcLimit; 72 SkRect fDstR[2]; 73 74 void bounce() { 75 bounce_pt(&fSrcPts[0], &fSrcVec[0], fSrcLimit); 76 bounce_pt(&fSrcPts[1], &fSrcVec[1], fSrcLimit); 77 } 78 79 void resetBounce() { 80 fSrcPts[0].set(0, 0); 81 fSrcPts[1].set(SCALAR_SIZE, SCALAR_SIZE); 82 83 fSrcVec[0] = unit_vec(30); 84 fSrcVec[1] = unit_vec(107); 85 } 86 87 public: 88 BitmapRectView() { 89 this->setBGColor(SK_ColorGRAY); 90 91 this->resetBounce(); 92 93 fSrcLimit.set(-SCALAR_SIZE/4, -SCALAR_SIZE/4, 94 SCALAR_SIZE*5/4, SCALAR_SIZE*5/4); 95 96 fDstR[0] = SkRect::MakeXYWH(SkIntToScalar(10), SkIntToScalar(100), 97 SkIntToScalar(250), SkIntToScalar(300)); 98 fDstR[1] = fDstR[0]; 99 fDstR[1].offset(fDstR[0].width() * 5/4, 0); 100 101 fSrcPts[0].set(32, 32); 102 fSrcPts[1].set(90, 90); 103 } 104 105 protected: 106 bool onQuery(SkEvent* evt) override { 107 if (SampleCode::TitleQ(*evt)) { 108 SampleCode::TitleR(evt, "BitmapRect"); 109 return true; 110 } 111 return this->INHERITED::onQuery(evt); 112 } 113 114 void onDrawContent(SkCanvas* canvas) override { 115 SkRect srcR; 116 srcR.set(fSrcPts[0], fSrcPts[1]); 117 srcR = SkRect::MakeXYWH(fSrcPts[0].fX, fSrcPts[0].fY, 32, 32); 118 srcR.offset(-srcR.width()/2, -srcR.height()/2); 119 120 SkPaint paint; 121 paint.setStyle(SkPaint::kStroke_Style); 122 paint.setColor(SK_ColorYELLOW); 123 124 SkBitmap bitmap; 125 make_bitmap(&bitmap); 126 127 canvas->translate(20, 20); 128 129 canvas->drawBitmap(bitmap, 0, 0, &paint); 130 canvas->drawRect(srcR, paint); 131 132 for (int i = 0; i < 2; ++i) { 133 paint.setFilterQuality(1 == i ? kLow_SkFilterQuality : kNone_SkFilterQuality); 134 canvas->drawBitmapRectToRect(bitmap, &srcR, fDstR[i], &paint); 135 canvas->drawRect(fDstR[i], paint); 136 } 137 } 138 139 bool onAnimate(const SkAnimTimer& timer) override { 140 if (timer.isStopped()) { 141 this->resetBounce(); 142 } else if (timer.isRunning()) { 143 this->bounce(); 144 } 145 return true; 146 } 147 148 private: 149 typedef SampleView INHERITED; 150 }; 151 152 ////////////////////////////////////////////////////////////////////////////// 153 154 static void make_big_bitmap(SkBitmap* bm) { 155 static const char gText[] = 156 "We the people, in order to form a more perfect union, establish justice," 157 " ensure domestic tranquility, provide for the common defense, promote the" 158 " general welfare and ensure the blessings of liberty to ourselves and our" 159 " posterity, do ordain and establish this constitution for the United" 160 " States of America."; 161 162 const int BIG_H = 120; 163 164 SkPaint paint; 165 paint.setAntiAlias(true); 166 paint.setTextSize(SkIntToScalar(BIG_H)); 167 168 const int BIG_W = SkScalarRoundToInt(paint.measureText(gText, strlen(gText))); 169 170 bm->allocN32Pixels(BIG_W, BIG_H); 171 bm->eraseColor(SK_ColorWHITE); 172 173 SkCanvas canvas(*bm); 174 175 canvas.drawText(gText, strlen(gText), 0, paint.getTextSize()*4/5, paint); 176 } 177 178 class BitmapRectView2 : public SampleView { 179 SkBitmap fBitmap; 180 181 SkRect fSrcR; 182 SkRect fLimitR; 183 SkScalar fDX; 184 SkRect fDstR[2]; 185 186 void bounceMe() { 187 SkScalar width = fSrcR.width(); 188 bounce(&fSrcR.fLeft, &fDX, fLimitR.fLeft, fLimitR.fRight - width); 189 fSrcR.fRight = fSrcR.fLeft + width; 190 } 191 192 void resetBounce() { 193 fSrcR.iset(0, 0, fBitmap.height() * 3, fBitmap.height()); 194 fDX = SK_Scalar1; 195 } 196 197 public: 198 BitmapRectView2() { 199 make_big_bitmap(&fBitmap); 200 201 this->setBGColor(SK_ColorGRAY); 202 203 this->resetBounce(); 204 205 fLimitR.iset(0, 0, fBitmap.width(), fBitmap.height()); 206 207 fDstR[0] = SkRect::MakeXYWH(20, 20, 600, 200); 208 fDstR[1] = fDstR[0]; 209 fDstR[1].offset(0, fDstR[0].height() * 5/4); 210 } 211 212 protected: 213 bool onQuery(SkEvent* evt) override { 214 if (SampleCode::TitleQ(*evt)) { 215 SampleCode::TitleR(evt, "BigBitmapRect"); 216 return true; 217 } 218 return this->INHERITED::onQuery(evt); 219 } 220 221 void onDrawContent(SkCanvas* canvas) override { 222 SkPaint paint; 223 paint.setStyle(SkPaint::kStroke_Style); 224 paint.setColor(SK_ColorYELLOW); 225 226 for (int i = 0; i < 2; ++i) { 227 paint.setFilterQuality(1 == i ? kLow_SkFilterQuality : kNone_SkFilterQuality); 228 canvas->drawBitmapRectToRect(fBitmap, &fSrcR, fDstR[i], &paint); 229 canvas->drawRect(fDstR[i], paint); 230 } 231 } 232 233 bool onAnimate(const SkAnimTimer& timer) override { 234 if (timer.isStopped()) { 235 this->resetBounce(); 236 } else if (timer.isRunning()) { 237 this->bounceMe(); 238 } 239 return true; 240 } 241 242 private: 243 typedef SampleView INHERITED; 244 }; 245 246 ////////////////////////////////////////////////////////////////////////////// 247 248 static SkView* F0() { return new BitmapRectView; } 249 static SkView* F1() { return new BitmapRectView2; } 250 static SkViewRegister gR0(F0); 251 static SkViewRegister gR1(F1); 252