• Home
  • Line#
  • Scopes#
  • Navigate#
  • Raw
  • Download
1 /*
2  * Copyright 2015 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 "SkData.h"
11 #include "SkImage.h"
12 #include "SkPictureRecorder.h"
13 #include "SkSurface.h"
14 
draw_something(SkCanvas * canvas,const SkRect & bounds)15 static void draw_something(SkCanvas* canvas, const SkRect& bounds) {
16     SkPaint paint;
17     paint.setAntiAlias(true);
18     paint.setColor(SK_ColorRED);
19     paint.setStyle(SkPaint::kStroke_Style);
20     paint.setStrokeWidth(10);
21     canvas->drawRect(bounds, paint);
22     paint.setStyle(SkPaint::kFill_Style);
23     paint.setColor(SK_ColorBLUE);
24     canvas->drawOval(bounds, paint);
25 }
26 
27 typedef SkImage* (*ImageMakerProc)(GrContext*, const SkPicture*, const SkImageInfo&);
28 
make_raster(GrContext *,const SkPicture * pic,const SkImageInfo & info)29 static SkImage* make_raster(GrContext*, const SkPicture* pic, const SkImageInfo& info) {
30     SkAutoTUnref<SkSurface> surface(SkSurface::NewRaster(info));
31     surface->getCanvas()->clear(0);
32     surface->getCanvas()->drawPicture(pic);
33     return surface->newImageSnapshot();
34 }
35 
make_texture(GrContext * ctx,const SkPicture * pic,const SkImageInfo & info)36 static SkImage* make_texture(GrContext* ctx, const SkPicture* pic, const SkImageInfo& info) {
37     if (!ctx) {
38         return nullptr;
39     }
40     SkAutoTUnref<SkSurface> surface(SkSurface::NewRenderTarget(ctx, SkBudgeted::kNo,
41                                                                info, 0));
42     surface->getCanvas()->clear(0);
43     surface->getCanvas()->drawPicture(pic);
44     return surface->newImageSnapshot();
45 }
46 
make_pict_gen(GrContext *,const SkPicture * pic,const SkImageInfo & info)47 static SkImage* make_pict_gen(GrContext*, const SkPicture* pic, const SkImageInfo& info) {
48     return SkImage::NewFromPicture(pic, info.dimensions(), nullptr, nullptr);
49 }
50 
make_encode_gen(GrContext * ctx,const SkPicture * pic,const SkImageInfo & info)51 static SkImage* make_encode_gen(GrContext* ctx, const SkPicture* pic, const SkImageInfo& info) {
52     SkAutoTUnref<SkImage> src(make_raster(ctx, pic, info));
53     if (!src) {
54         return nullptr;
55     }
56     SkAutoTUnref<SkData> encoded(src->encode(SkImageEncoder::kPNG_Type, 100));
57     if (!encoded) {
58         return nullptr;
59     }
60     return SkImage::NewFromEncoded(encoded);
61 }
62 
63 const ImageMakerProc gProcs[] = {
64     make_raster,
65     make_texture,
66     make_pict_gen,
67     make_encode_gen,
68 };
69 
70 /*
71  *  Exercise drawing pictures inside an image, showing that the image version is pixelated
72  *  (correctly) when it is inside an image.
73  */
74 class ImageShaderGM : public skiagm::GM {
75     SkAutoTUnref<SkPicture> fPicture;
76 
77 public:
ImageShaderGM()78     ImageShaderGM() {}
79 
80 protected:
onShortName()81     SkString onShortName() override {
82         return SkString("image-shader");
83     }
84 
onISize()85     SkISize onISize() override {
86         return SkISize::Make(850, 450);
87     }
88 
onOnceBeforeDraw()89     void onOnceBeforeDraw() override {
90         const SkRect bounds = SkRect::MakeWH(100, 100);
91         SkPictureRecorder recorder;
92         draw_something(recorder.beginRecording(bounds), bounds);
93         fPicture.reset(recorder.endRecording());
94     }
95 
testImage(SkCanvas * canvas,SkImage * image)96     void testImage(SkCanvas* canvas, SkImage* image) {
97         SkAutoCanvasRestore acr(canvas, true);
98 
99         canvas->drawImage(image, 0, 0);
100         canvas->translate(0, 120);
101 
102         const SkShader::TileMode tile = SkShader::kRepeat_TileMode;
103         const SkMatrix localM = SkMatrix::MakeTrans(-50, -50);
104         SkAutoTUnref<SkShader> shader(image->newShader(tile, tile, &localM));
105         SkPaint paint;
106         paint.setAntiAlias(true);
107         paint.setShader(shader);
108         canvas->drawCircle(50, 50, 50, paint);
109     }
110 
onDraw(SkCanvas * canvas)111     void onDraw(SkCanvas* canvas) override {
112         canvas->translate(20, 20);
113 
114         const SkImageInfo info = SkImageInfo::MakeN32Premul(100, 100);
115 
116         for (size_t i = 0; i < SK_ARRAY_COUNT(gProcs); ++i) {
117             SkAutoTUnref<SkImage> image(gProcs[i](canvas->getGrContext(), fPicture, info));
118             if (image) {
119                 this->testImage(canvas, image);
120             }
121             canvas->translate(120, 0);
122         }
123     }
124 
125 private:
126     typedef skiagm::GM INHERITED;
127 };
128 DEF_GM( return new ImageShaderGM; )
129 
130