Home | History | Annotate | Download | only in gm
      1 /*
      2  * Copyright 2013 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 "sk_tool_utils.h"
     10 
     11 #include "SkPictureImageFilter.h"
     12 #include "SkPictureRecorder.h"
     13 
     14 #include "SkImage.h"
     15 #include "SkImageSource.h"
     16 
     17 // This GM exercises the SkPictureImageFilter ImageFilter class.
     18 
     19 static void fill_rect_filtered(SkCanvas* canvas,
     20                                const SkRect& clipRect,
     21                                sk_sp<SkImageFilter> filter) {
     22     SkPaint paint;
     23     paint.setImageFilter(filter);
     24     canvas->save();
     25     canvas->clipRect(clipRect);
     26     canvas->drawPaint(paint);
     27     canvas->restore();
     28 }
     29 
     30 static sk_sp<SkPicture> make_picture() {
     31     SkPictureRecorder recorder;
     32     SkCanvas* canvas = recorder.beginRecording(100, 100, nullptr, 0);
     33     SkPaint paint;
     34     paint.setAntiAlias(true);
     35     sk_tool_utils::set_portable_typeface(&paint);
     36     paint.setColor(0xFFFFFFFF);
     37     paint.setTextSize(SkIntToScalar(96));
     38     const char* str = "e";
     39     canvas->drawString(str, SkIntToScalar(20), SkIntToScalar(70), paint);
     40     return recorder.finishRecordingAsPicture();
     41 }
     42 
     43 // Create a picture that will draw LCD text
     44 static sk_sp<SkPicture> make_LCD_picture() {
     45     SkPictureRecorder recorder;
     46     SkCanvas* canvas = recorder.beginRecording(100, 100, nullptr, 0);
     47     canvas->clear(SK_ColorTRANSPARENT);
     48     SkPaint paint;
     49     paint.setLCDRenderText(true);   // want LCD
     50     paint.setAntiAlias(true);       // need AA for LCD
     51     sk_tool_utils::set_portable_typeface(&paint);
     52     paint.setColor(0xFFFFFFFF);
     53     // this has to be small enough that it doesn't become a path
     54     paint.setTextSize(SkIntToScalar(36));
     55     const char* str = "e";
     56     canvas->drawString(str, SkIntToScalar(20), SkIntToScalar(70), paint);
     57     return recorder.finishRecordingAsPicture();
     58 }
     59 
     60 class PictureImageFilterGM : public skiagm::GM {
     61 public:
     62     PictureImageFilterGM() { }
     63 
     64 protected:
     65     SkString onShortName() override {
     66         return SkString("pictureimagefilter");
     67     }
     68 
     69     SkISize onISize() override { return SkISize::Make(600, 300); }
     70 
     71     void onOnceBeforeDraw() override {
     72         fPicture = make_picture();
     73         fLCDPicture = make_LCD_picture();
     74     }
     75 
     76     sk_sp<SkImageFilter> make(sk_sp<SkPicture> pic, SkRect r, SkFilterQuality fq) {
     77         SkISize dim = { SkScalarRoundToInt(r.width()), SkScalarRoundToInt(r.height()) };
     78         auto img = SkImage::MakeFromPicture(pic, dim, nullptr, nullptr,
     79                                             SkImage::BitDepth::kU8, SkColorSpace::MakeSRGB());
     80         return SkImageSource::Make(img, r, r, fq);
     81     }
     82     sk_sp<SkImageFilter> make(SkFilterQuality fq) {
     83         return make(fPicture, fPicture->cullRect(), fq);
     84     }
     85 
     86     void onDraw(SkCanvas* canvas) override {
     87         canvas->clear(SK_ColorGRAY);
     88         {
     89             SkRect srcRect = SkRect::MakeXYWH(20, 20, 30, 30);
     90             SkRect emptyRect = SkRect::MakeXYWH(20, 20, 0, 0);
     91             SkRect bounds = SkRect::MakeXYWH(0, 0, 100, 100);
     92             sk_sp<SkImageFilter> pictureSource(SkPictureImageFilter::Make(fPicture));
     93             sk_sp<SkImageFilter> pictureSourceSrcRect(SkPictureImageFilter::Make(fPicture,
     94                                                                                  srcRect));
     95             sk_sp<SkImageFilter> pictureSourceEmptyRect(SkPictureImageFilter::Make(fPicture,
     96                                                                                    emptyRect));
     97             sk_sp<SkImageFilter> pictureSourceResampled = make(kLow_SkFilterQuality);
     98             sk_sp<SkImageFilter> pictureSourcePixelated = make(kNone_SkFilterQuality);
     99 
    100             canvas->save();
    101             // Draw the picture unscaled.
    102             fill_rect_filtered(canvas, bounds, pictureSource);
    103             canvas->translate(SkIntToScalar(100), 0);
    104 
    105             // Draw an unscaled subset of the source picture.
    106             fill_rect_filtered(canvas, bounds, pictureSourceSrcRect);
    107             canvas->translate(SkIntToScalar(100), 0);
    108 
    109             // Draw the picture to an empty rect (should draw nothing).
    110             fill_rect_filtered(canvas, bounds, pictureSourceEmptyRect);
    111             canvas->translate(SkIntToScalar(100), 0);
    112 
    113             // Draw the LCD picture to a layer
    114             {
    115                 SkPaint stroke;
    116                 stroke.setStyle(SkPaint::kStroke_Style);
    117 
    118                 canvas->drawRect(bounds, stroke);
    119 
    120                 SkPaint paint;
    121                 paint.setImageFilter(make(fLCDPicture, fPicture->cullRect(), kNone_SkFilterQuality));
    122 
    123                 canvas->scale(4, 4);
    124                 canvas->translate(-0.9f*srcRect.fLeft, -2.45f*srcRect.fTop);
    125 
    126                 canvas->saveLayerPreserveLCDTextRequests(&bounds, &paint);
    127                 canvas->restore();
    128             }
    129 
    130             canvas->restore();
    131 
    132             // Draw the picture scaled
    133             canvas->translate(0, SkIntToScalar(100));
    134             canvas->scale(200 / srcRect.width(), 200 / srcRect.height());
    135             canvas->translate(-srcRect.fLeft, -srcRect.fTop);
    136             fill_rect_filtered(canvas, srcRect, pictureSource);
    137 
    138             // Draw the picture scaled, but rasterized at original resolution
    139             canvas->translate(srcRect.width(), 0);
    140             fill_rect_filtered(canvas, srcRect, pictureSourceResampled);
    141 
    142             // Draw the picture scaled, pixelated
    143             canvas->translate(srcRect.width(), 0);
    144             fill_rect_filtered(canvas, srcRect, pictureSourcePixelated);
    145         }
    146     }
    147 
    148 private:
    149     sk_sp<SkPicture> fPicture;
    150     sk_sp<SkPicture> fLCDPicture;
    151 
    152     typedef GM INHERITED;
    153 };
    154 
    155 ///////////////////////////////////////////////////////////////////////////////
    156 
    157 DEF_GM( return new PictureImageFilterGM; )
    158