1
2/*
3 * Copyright 2011 Google Inc.
4 *
5 * Use of this source code is governed by a BSD-style license that can be
6 * found in the LICENSE file.
7 */
8#include "SampleCode.h"
9#include "SkColorPriv.h"
10#include "SkGradientShader.h"
11#include "SkView.h"
12#include "SkCanvas.h"
13#include "SkUtils.h"
14
15static void draw_rect(SkCanvas* canvas, const SkRect& r, const SkPaint& p) {
16    canvas->drawRect(r, p);
17
18    SkPaint frame(p);
19    frame.setShader(NULL);
20    frame.setStyle(SkPaint::kStroke_Style);
21    canvas->drawRect(r, frame);
22}
23
24static void draw_gradient(SkCanvas* canvas) {
25    SkRect r = { 0, 0, SkIntToScalar(256), SkIntToScalar(32) };
26    SkPoint pts[] = { { r.fLeft, r.fTop }, { r.fRight, r.fTop } };
27    SkColor colors[] = { 0xFF000000, 0xFFFF0000 };
28    SkShader* s = SkGradientShader::CreateLinear(pts, colors, NULL, 2,
29                                                 SkShader::kClamp_TileMode);
30
31    SkPaint p;
32    p.setShader(s)->unref();
33    draw_rect(canvas, r, p);
34
35    canvas->translate(0, SkIntToScalar(40));
36    p.setDither(true);
37    draw_rect(canvas, r, p);
38}
39
40static bool test_pathregion() {
41    SkPath path;
42    SkRegion region;
43    path.moveTo(25071800.f, -141823808.f);
44    path.lineTo(25075500.f, -141824000.f);
45    path.lineTo(25075400.f, -141827712.f);
46    path.lineTo(25071810.f, -141827600.f);
47    path.close();
48
49    SkIRect bounds;
50    path.getBounds().round(&bounds);
51    SkRegion clip(bounds);
52    return region.setPath(path, clip); // <-- !! DOWN !!
53}
54
55static SkBitmap make_bitmap() {
56    SkPMColor c[256];
57    for (int i = 0; i < 256; i++) {
58        c[i] = SkPackARGB32(0xFF, i, 0, 0);
59    }
60    SkColorTable* ctable = new SkColorTable(c, 256);
61
62    SkBitmap bm;
63    bm.allocPixels(SkImageInfo::Make(256, 32, kIndex_8_SkColorType, kPremul_SkAlphaType),
64                   NULL, ctable);
65    ctable->unref();
66
67    bm.lockPixels();
68    for (int y = 0; y < bm.height(); y++) {
69        uint8_t* p = bm.getAddr8(0, y);
70        for (int x = 0; x < 256; x++) {
71            p[x] = x;
72        }
73    }
74    bm.unlockPixels();
75    return bm;
76}
77
78class DitherBitmapView : public SampleView {
79    SkBitmap    fBM8;
80    SkBitmap    fBM32;
81    bool        fResult;
82public:
83    DitherBitmapView() {
84        fResult = test_pathregion();
85        fBM8 = make_bitmap();
86        fBM8.copyTo(&fBM32, kN32_SkColorType);
87
88        this->setBGColor(0xFFDDDDDD);
89    }
90
91protected:
92    // overrides from SkEventSink
93    virtual bool onQuery(SkEvent* evt) {
94        if (SampleCode::TitleQ(*evt)) {
95            SampleCode::TitleR(evt, "DitherBitmap");
96            return true;
97        }
98        return this->INHERITED::onQuery(evt);
99    }
100
101    static void setBitmapOpaque(SkBitmap* bm, bool isOpaque) {
102        SkAutoLockPixels alp(*bm);  // needed for ctable
103        bm->setAlphaType(isOpaque ? kOpaque_SkAlphaType : kPremul_SkAlphaType);
104    }
105
106    static void draw2(SkCanvas* canvas, const SkBitmap& bm) {
107        SkPaint paint;
108        SkBitmap bitmap(bm);
109
110        setBitmapOpaque(&bitmap, false);
111        paint.setDither(false);
112        canvas->drawBitmap(bitmap, 0, 0, &paint);
113        paint.setDither(true);
114        canvas->drawBitmap(bitmap, 0, SkIntToScalar(bm.height() + 10), &paint);
115
116        setBitmapOpaque(&bitmap, true);
117        SkScalar x = SkIntToScalar(bm.width() + 10);
118        paint.setDither(false);
119        canvas->drawBitmap(bitmap, x, 0, &paint);
120        paint.setDither(true);
121        canvas->drawBitmap(bitmap, x, SkIntToScalar(bm.height() + 10), &paint);
122    }
123
124    virtual void onDrawContent(SkCanvas* canvas) {
125        canvas->translate(SkIntToScalar(20), SkIntToScalar(20));
126
127        draw2(canvas, fBM8);
128        canvas->translate(0, SkIntToScalar(fBM8.height() *3));
129        draw2(canvas, fBM32);
130
131        canvas->translate(0, SkIntToScalar(fBM8.height() *3));
132        draw_gradient(canvas);
133
134        char resultTrue[] = "SkRegion::setPath returned true";
135        char resultFalse[] = "SkRegion::setPath returned false";
136        SkPaint p;
137        if (fResult)
138            canvas->drawText(resultTrue, sizeof(resultTrue) - 1, 0, 50, p);
139        else
140            canvas->drawText(resultFalse, sizeof(resultFalse) - 1, 0, 50, p);
141    }
142
143private:
144    typedef SampleView INHERITED;
145};
146
147//////////////////////////////////////////////////////////////////////////////
148
149static SkView* MyFactory() { return new DitherBitmapView; }
150static SkViewRegister reg(MyFactory);
151