Home | History | Annotate | Download | only in samplecode
      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 "SkView.h"
     10 #include "SkCanvas.h"
     11 #include "SkReadBuffer.h"
     12 #include "SkWriteBuffer.h"
     13 #include "SkGradientShader.h"
     14 #include "SkPath.h"
     15 #include "SkRegion.h"
     16 #include "SkShader.h"
     17 #include "SkUtils.h"
     18 #include "SkColorPriv.h"
     19 #include "SkColorFilter.h"
     20 #include "SkTypeface.h"
     21 #include "SkAvoidXfermode.h"
     22 
     23 static inline SkPMColor rgb2gray(SkPMColor c) {
     24     unsigned r = SkGetPackedR32(c);
     25     unsigned g = SkGetPackedG32(c);
     26     unsigned b = SkGetPackedB32(c);
     27 
     28     unsigned x = (r * 5 + g * 7 + b * 4) >> 4;
     29 
     30     return SkPackARGB32(0, x, x, x) | (c & (SK_A32_MASK << SK_A32_SHIFT));
     31 }
     32 
     33 class SkGrayScaleColorFilter : public SkColorFilter {
     34 public:
     35     virtual void filterSpan(const SkPMColor src[], int count,
     36                             SkPMColor result[]) const SK_OVERRIDE {
     37         for (int i = 0; i < count; i++) {
     38             result[i] = rgb2gray(src[i]);
     39         }
     40     }
     41 };
     42 
     43 class SkChannelMaskColorFilter : public SkColorFilter {
     44 public:
     45     SkChannelMaskColorFilter(U8CPU redMask, U8CPU greenMask, U8CPU blueMask) {
     46         fMask = SkPackARGB32(0xFF, redMask, greenMask, blueMask);
     47     }
     48 
     49     virtual void filterSpan(const SkPMColor src[], int count,
     50                             SkPMColor result[]) const SK_OVERRIDE {
     51         SkPMColor mask = fMask;
     52         for (int i = 0; i < count; i++) {
     53             result[i] = src[i] & mask;
     54         }
     55     }
     56 
     57 private:
     58     SkPMColor   fMask;
     59 };
     60 
     61 ///////////////////////////////////////////////////////////////////////////////
     62 
     63 #include "SkGradientShader.h"
     64 #include "SkLayerRasterizer.h"
     65 #include "SkBlurMaskFilter.h"
     66 
     67 #include "Sk2DPathEffect.h"
     68 
     69 class Dot2DPathEffect : public Sk2DPathEffect {
     70 public:
     71     Dot2DPathEffect(SkScalar radius, const SkMatrix& matrix,
     72                     SkTDArray<SkPoint>* pts)
     73     : Sk2DPathEffect(matrix), fRadius(radius), fPts(pts) {}
     74 
     75     SK_DECLARE_PUBLIC_FLATTENABLE_DESERIALIZATION_PROCS(Dot2DPathEffect)
     76 
     77 protected:
     78     virtual void begin(const SkIRect& uvBounds, SkPath* dst) const SK_OVERRIDE {
     79         if (fPts) {
     80             fPts->reset();
     81         }
     82         this->INHERITED::begin(uvBounds, dst);
     83     }
     84 
     85     virtual void next(const SkPoint& loc, int u, int v,
     86                       SkPath* dst) const SK_OVERRIDE {
     87         if (fPts) {
     88             *fPts->append() = loc;
     89         }
     90         dst->addCircle(loc.fX, loc.fY, fRadius);
     91     }
     92 
     93     Dot2DPathEffect(SkReadBuffer& buffer) : INHERITED(buffer) {
     94         fRadius = buffer.readScalar();
     95         fPts = NULL;
     96     }
     97 
     98     virtual void flatten(SkWriteBuffer& buffer) const SK_OVERRIDE {
     99         this->INHERITED::flatten(buffer);
    100         buffer.writeScalar(fRadius);
    101     }
    102 
    103 private:
    104     SkScalar fRadius;
    105     SkTDArray<SkPoint>* fPts;
    106 
    107     typedef Sk2DPathEffect INHERITED;
    108 };
    109 
    110 class InverseFillPE : public SkPathEffect {
    111 public:
    112     InverseFillPE() {}
    113     virtual bool filterPath(SkPath* dst, const SkPath& src,
    114                             SkStrokeRec*, const SkRect*) const SK_OVERRIDE {
    115         *dst = src;
    116         dst->setFillType(SkPath::kInverseWinding_FillType);
    117         return true;
    118     }
    119     SK_DECLARE_PUBLIC_FLATTENABLE_DESERIALIZATION_PROCS(InverseFillPE)
    120 
    121 protected:
    122     InverseFillPE(SkReadBuffer& buffer) : INHERITED(buffer) {}
    123 private:
    124 
    125     typedef SkPathEffect INHERITED;
    126 };
    127 
    128 static SkPathEffect* makepe(float interp, SkTDArray<SkPoint>* pts) {
    129     SkMatrix    lattice;
    130     SkScalar    rad = 3 + SkIntToScalar(4) * (1 - interp);
    131     lattice.setScale(rad*2, rad*2, 0, 0);
    132     lattice.postSkew(SK_Scalar1/3, 0, 0, 0);
    133     return new Dot2DPathEffect(rad, lattice, pts);
    134 }
    135 
    136 static void r7(SkLayerRasterizer::Builder* rastBuilder, SkPaint& p, SkScalar interp) {
    137     p.setPathEffect(makepe(SkScalarToFloat(interp), NULL))->unref();
    138     rastBuilder->addLayer(p);
    139 #if 0
    140     p.setPathEffect(new InverseFillPE())->unref();
    141     p.setXfermodeMode(SkXfermode::kSrcIn_Mode);
    142     p.setXfermodeMode(SkXfermode::kClear_Mode);
    143     p.setAlpha((1 - interp) * 255);
    144     rastBuilder->addLayer(p);
    145 #endif
    146 }
    147 
    148 typedef void (*raster_proc)(SkLayerRasterizer*, SkPaint&);
    149 
    150 #include "SkXfermode.h"
    151 
    152 static void apply_shader(SkPaint* paint, float scale)
    153 {
    154     SkPaint p;
    155     SkLayerRasterizer::Builder rastBuilder;
    156 
    157     p.setAntiAlias(true);
    158     r7(&rastBuilder, p, scale);
    159     paint->setRasterizer(rastBuilder.detachRasterizer())->unref();
    160 
    161     paint->setColor(SK_ColorBLUE);
    162 }
    163 
    164 class ClockFaceView : public SkView {
    165     SkTypeface* fFace;
    166     SkScalar fInterp;
    167     SkScalar fDx;
    168 
    169 public:
    170     ClockFaceView() {
    171         fFace = SkTypeface::CreateFromFile("/Users/reed/Downloads/p052024l.pfb");
    172         fInterp = 0;
    173         fDx = SK_Scalar1/64;
    174     }
    175 
    176     virtual ~ClockFaceView() {
    177         SkSafeUnref(fFace);
    178     }
    179 
    180 protected:
    181     // overrides from SkEventSink
    182     virtual bool onQuery(SkEvent* evt) {
    183         if (SampleCode::TitleQ(*evt)) {
    184             SampleCode::TitleR(evt, "Text Effects");
    185             return true;
    186         }
    187         return this->INHERITED::onQuery(evt);
    188     }
    189 
    190     void drawBG(SkCanvas* canvas) {
    191 //        canvas->drawColor(0xFFDDDDDD);
    192         canvas->drawColor(SK_ColorWHITE);
    193     }
    194 
    195     static void drawdots(SkCanvas* canvas, const SkPaint& orig) {
    196         SkTDArray<SkPoint> pts;
    197         SkPathEffect* pe = makepe(0, &pts);
    198 
    199         SkStrokeRec rec(SkStrokeRec::kFill_InitStyle);
    200         SkPath path, dstPath;
    201         orig.getTextPath("9", 1, 0, 0, &path);
    202         pe->filterPath(&dstPath, path, &rec, NULL);
    203 
    204         SkPaint p;
    205         p.setAntiAlias(true);
    206         p.setStrokeWidth(10);
    207         p.setColor(SK_ColorRED);
    208         canvas->drawPoints(SkCanvas::kPoints_PointMode, pts.count(), pts.begin(),
    209                            p);
    210     }
    211 
    212     virtual void onDraw(SkCanvas* canvas) {
    213         this->drawBG(canvas);
    214 
    215         SkScalar    x = SkIntToScalar(20);
    216         SkScalar    y = SkIntToScalar(300);
    217         SkPaint     paint;
    218 
    219         paint.setAntiAlias(true);
    220         paint.setTextSize(SkIntToScalar(240));
    221         paint.setTypeface(SkTypeface::CreateFromName("sans-serif",
    222                                                      SkTypeface::kBold));
    223 
    224         SkString str("9");
    225 
    226         paint.setTypeface(fFace);
    227 
    228         apply_shader(&paint, SkScalarToFloat(fInterp));
    229         canvas->drawText(str.c_str(), str.size(), x, y, paint);
    230 
    231     //    drawdots(canvas, paint);
    232 
    233         if (false) {
    234             fInterp += fDx;
    235             if (fInterp > 1) {
    236                 fInterp = 1;
    237                 fDx = -fDx;
    238             } else if (fInterp < 0) {
    239                 fInterp = 0;
    240                 fDx = -fDx;
    241             }
    242             this->inval(NULL);
    243         }
    244     }
    245 
    246 private:
    247     typedef SkView INHERITED;
    248 };
    249 
    250 //////////////////////////////////////////////////////////////////////////////
    251 
    252 static SkView* MyFactory() { return new ClockFaceView; }
    253 static SkViewRegister reg(MyFactory);
    254