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, kOpaque_SkAlphaType);
61
62    SkBitmap bm;
63    bm.allocPixels(SkImageInfo::Make(256, 32, kIndex_8_SkColorType,
64                                     kPremul_SkAlphaType),
65                   NULL, ctable);
66    ctable->unref();
67
68    bm.lockPixels();
69    for (int y = 0; y < bm.height(); y++) {
70        uint8_t* p = bm.getAddr8(0, y);
71        for (int x = 0; x < 256; x++) {
72            p[x] = x;
73        }
74    }
75    bm.unlockPixels();
76    return bm;
77}
78
79class DitherBitmapView : public SampleView {
80    SkBitmap    fBM8;
81    SkBitmap    fBM32;
82    bool        fResult;
83public:
84    DitherBitmapView() {
85        fResult = test_pathregion();
86        fBM8 = make_bitmap();
87        fBM8.copyTo(&fBM32, kN32_SkColorType);
88
89        this->setBGColor(0xFFDDDDDD);
90    }
91
92protected:
93    // overrides from SkEventSink
94    virtual bool onQuery(SkEvent* evt) {
95        if (SampleCode::TitleQ(*evt)) {
96            SampleCode::TitleR(evt, "DitherBitmap");
97            return true;
98        }
99        return this->INHERITED::onQuery(evt);
100    }
101
102    static void setBitmapOpaque(SkBitmap* bm, bool isOpaque) {
103        SkAutoLockPixels alp(*bm);  // needed for ctable
104        bm->setAlphaType(isOpaque ? kOpaque_SkAlphaType : kPremul_SkAlphaType);
105    }
106
107    static void draw2(SkCanvas* canvas, const SkBitmap& bm) {
108        SkPaint paint;
109        SkBitmap bitmap(bm);
110
111        setBitmapOpaque(&bitmap, false);
112        paint.setDither(false);
113        canvas->drawBitmap(bitmap, 0, 0, &paint);
114        paint.setDither(true);
115        canvas->drawBitmap(bitmap, 0, SkIntToScalar(bm.height() + 10), &paint);
116
117        setBitmapOpaque(&bitmap, true);
118        SkScalar x = SkIntToScalar(bm.width() + 10);
119        paint.setDither(false);
120        canvas->drawBitmap(bitmap, x, 0, &paint);
121        paint.setDither(true);
122        canvas->drawBitmap(bitmap, x, SkIntToScalar(bm.height() + 10), &paint);
123    }
124
125    virtual void onDrawContent(SkCanvas* canvas) {
126        canvas->translate(SkIntToScalar(20), SkIntToScalar(20));
127
128        draw2(canvas, fBM8);
129        canvas->translate(0, SkIntToScalar(fBM8.height() *3));
130        draw2(canvas, fBM32);
131
132        canvas->translate(0, SkIntToScalar(fBM8.height() *3));
133        draw_gradient(canvas);
134
135        char resultTrue[] = "SkRegion::setPath returned true";
136        char resultFalse[] = "SkRegion::setPath returned false";
137        SkPaint p;
138        if (fResult)
139            canvas->drawText(resultTrue, sizeof(resultTrue) - 1, 0, 50, p);
140        else
141            canvas->drawText(resultFalse, sizeof(resultFalse) - 1, 0, 50, p);
142    }
143
144private:
145    typedef SampleView INHERITED;
146};
147
148//////////////////////////////////////////////////////////////////////////////
149
150static SkView* MyFactory() { return new DitherBitmapView; }
151static SkViewRegister reg(MyFactory);
152