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 "SkCanvas.h"
10 #include "SkGradientShader.h"
11 #include "SkPath.h"
12 #include "SkRandom.h"
13 
make_bm(SkBitmap * bm,int height)14 int make_bm(SkBitmap* bm, int height) {
15     static const int kRadius = 22;
16     static const int kMargin = 8;
17     static const SkScalar kStartAngle = 0;
18     static const SkScalar kDAngle = 25;
19     static const SkScalar kSweep = 320;
20     static const SkScalar kThickness = 8;
21 
22     int count = (height / (2 * kRadius + kMargin));
23     height = count * (2 * kRadius + kMargin);
24 
25     bm->allocN32Pixels(2 * (kRadius + kMargin), height);
26     SkRandom random;
27 
28     SkCanvas wholeCanvas(*bm);
29     wholeCanvas.clear(0x00000000);
30 
31     SkScalar angle = kStartAngle;
32     for (int i = 0; i < count; ++i) {
33         SkPaint paint;
34         // The sw rasterizer disables AA for large canvii. So we make a small canvas for each draw.
35         SkBitmap smallBM;
36         SkIRect subRect = SkIRect::MakeXYWH(0, i * (kMargin + 2 * kRadius),
37                                             2 * kRadius + kMargin, 2 * kRadius + kMargin);
38         bm->extractSubset(&smallBM, subRect);
39         SkCanvas canvas(smallBM);
40         canvas.translate(kMargin + kRadius, kMargin + kRadius);
41 
42         paint.setAntiAlias(true);
43         paint.setColor(random.nextU() | 0xFF000000);
44         paint.setStyle(SkPaint::kStroke_Style);
45         paint.setStrokeWidth(kThickness);
46         paint.setStrokeCap(SkPaint::kRound_Cap);
47         SkScalar radius = kRadius - kThickness / 2;
48         SkRect bounds = SkRect::MakeLTRB(-radius, -radius, radius, radius);
49 
50         canvas.drawArc(bounds, angle, kSweep, false, paint);
51         angle += kDAngle;
52     }
53     bm->setImmutable();
54     return count;
55 }
56 
57 class TallStretchedBitmapsGM : public skiagm::GM {
58 public:
TallStretchedBitmapsGM()59     TallStretchedBitmapsGM() {}
60 
61 protected:
onShortName()62     SkString onShortName() override {
63         return SkString("tall_stretched_bitmaps");
64     }
65 
onISize()66     SkISize onISize() override {
67         return SkISize::Make(750, 750);
68     }
69 
onOnceBeforeDraw()70     void onOnceBeforeDraw() override {
71         for (size_t i = 0; i < SK_ARRAY_COUNT(fTallBmps); ++i) {
72             int h = SkToInt((4 + i) * 1024);
73 
74             fTallBmps[i].fItemCnt = make_bm(&fTallBmps[i].fBmp, h);
75         }
76     }
77 
onDraw(SkCanvas * canvas)78     void onDraw(SkCanvas* canvas) override {
79         canvas->scale(1.3f, 1.3f);
80         for (size_t i = 0; i < SK_ARRAY_COUNT(fTallBmps); ++i) {
81             SkASSERT(fTallBmps[i].fItemCnt > 10);
82             SkBitmap bmp = fTallBmps[i].fBmp;
83             // Draw the last 10 elements of the bitmap.
84             int startItem = fTallBmps[i].fItemCnt - 10;
85             int itemHeight = bmp.height() / fTallBmps[i].fItemCnt;
86             SkIRect subRect = SkIRect::MakeLTRB(0, startItem * itemHeight,
87                                                bmp.width(), bmp.height());
88             SkRect dstRect = SkRect::MakeWH(SkIntToScalar(bmp.width()), 10.f * itemHeight);
89             SkPaint paint;
90             paint.setFilterQuality(kLow_SkFilterQuality);
91             canvas->drawBitmapRect(bmp, &subRect, dstRect, &paint);
92             canvas->translate(SkIntToScalar(bmp.width() + 10), 0);
93         }
94     }
95 
96 private:
97     struct {
98         SkBitmap fBmp;
99         int      fItemCnt;
100     } fTallBmps[8];
101     typedef skiagm::GM INHERITED;
102 };
103 
104 //////////////////////////////////////////////////////////////////////////////
105 
106 DEF_GM(return SkNEW(TallStretchedBitmapsGM);)
107 
108