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 "Sk64.h"
     12 #include "SkCornerPathEffect.h"
     13 #include "SkGradientShader.h"
     14 #include "SkGraphics.h"
     15 #include "SkImageDecoder.h"
     16 #include "SkKernel33MaskFilter.h"
     17 #include "SkPath.h"
     18 #include "SkRandom.h"
     19 #include "SkRegion.h"
     20 #include "SkShader.h"
     21 #include "SkUtils.h"
     22 #include "SkColorPriv.h"
     23 #include "SkColorFilter.h"
     24 #include "SkTime.h"
     25 #include "SkTypeface.h"
     26 #include "SkXfermode.h"
     27 
     28 #include "SkStream.h"
     29 #include "SkXMLParser.h"
     30 #include "SkColorPriv.h"
     31 #include "SkImageDecoder.h"
     32 
     33 static void setNamedTypeface(SkPaint* paint, const char name[]) {
     34     SkTypeface* face = SkTypeface::CreateFromName(name, SkTypeface::kNormal);
     35     paint->setTypeface(face);
     36     SkSafeUnref(face);
     37 }
     38 
     39 #if 0
     40 static int newscale(U8CPU a, U8CPU b, int shift) {
     41     unsigned prod = a * b + (1 << (shift - 1));
     42     return (prod + (prod >> shift)) >> shift;
     43 }
     44 
     45 static void test_srcover565(SkCanvas* canvas) {
     46     const int width = 32;
     47     SkBitmap bm1, bm2, bm3;
     48     bm1.setConfig(SkBitmap::kRGB_565_Config, width, 256); bm1.allocPixels(NULL);
     49     bm2.setConfig(SkBitmap::kRGB_565_Config, width, 256); bm2.allocPixels(NULL);
     50     bm3.setConfig(SkBitmap::kRGB_565_Config, width, 256); bm3.allocPixels(NULL);
     51 
     52     int rgb = 0x18;
     53     int r = rgb >> 3;
     54     int g = rgb >> 2;
     55     uint16_t dst = SkPackRGB16(r, g, r);
     56     for (int alpha = 0; alpha <= 255; alpha++) {
     57         SkPMColor pm = SkPreMultiplyARGB(alpha, rgb, rgb, rgb);
     58         uint16_t newdst = SkSrcOver32To16(pm, dst);
     59         sk_memset16(bm1.getAddr16(0, alpha), newdst, bm1.width());
     60 
     61         int ia = 255 - alpha;
     62         int iscale = SkAlpha255To256(ia);
     63         int dr = (SkGetPackedR32(pm) + (r * iscale >> 5)) >> 3;
     64         int dg = (SkGetPackedG32(pm) + (g * iscale >> 6)) >> 2;
     65 
     66         sk_memset16(bm2.getAddr16(0, alpha), SkPackRGB16(dr, dg, dr), bm2.width());
     67 
     68         int dr2 = (SkMulDiv255Round(alpha, rgb) + newscale(r, ia, 5)) >> 3;
     69         int dg2 = (SkMulDiv255Round(alpha, rgb) + newscale(g, ia, 6)) >> 2;
     70 
     71         sk_memset16(bm3.getAddr16(0, alpha), SkPackRGB16(dr2, dg2, dr2), bm3.width());
     72 
     73 //        if (mr != dr || mg != dg)
     74         {
     75 //            SkDebugf("[%d] macro [%d %d] inline [%d %d] new [%d %d]\n", alpha, mr, mg, dr, dg, dr2, dg2);
     76         }
     77     }
     78 
     79     SkScalar dx = SkIntToScalar(width+4);
     80 
     81     canvas->drawBitmap(bm1, 0, 0, NULL); canvas->translate(dx, 0);
     82     canvas->drawBitmap(bm2, 0, 0, NULL); canvas->translate(dx, 0);
     83     canvas->drawBitmap(bm3, 0, 0, NULL); canvas->translate(dx, 0);
     84 
     85     SkRect rect = { 0, 0, SkIntToScalar(bm1.width()), SkIntToScalar(bm1.height()) };
     86     SkPaint p;
     87     p.setARGB(0xFF, rgb, rgb, rgb);
     88     canvas->drawRect(rect, p);
     89 }
     90 #endif
     91 
     92 static void make_bitmaps(int w, int h, SkBitmap* src, SkBitmap* dst) {
     93     src->setConfig(SkBitmap::kARGB_8888_Config, w, h);
     94     src->allocPixels();
     95     src->eraseColor(0);
     96 
     97     SkCanvas c(*src);
     98     SkPaint p;
     99     SkRect r;
    100     SkScalar ww = SkIntToScalar(w);
    101     SkScalar hh = SkIntToScalar(h);
    102 
    103     p.setAntiAlias(true);
    104     p.setColor(0xFFFFCC44);
    105     r.set(0, 0, ww*3/4, hh*3/4);
    106     c.drawOval(r, p);
    107 
    108     dst->setConfig(SkBitmap::kARGB_8888_Config, w, h);
    109     dst->allocPixels();
    110     dst->eraseColor(0);
    111     c.setBitmapDevice(*dst);
    112 
    113     p.setColor(0xFF66AAFF);
    114     r.set(ww/3, hh/3, ww*19/20, hh*19/20);
    115     c.drawRect(r, p);
    116 }
    117 
    118 static uint16_t gBG[] = { 0xFFFF, 0xCCCF, 0xCCCF, 0xFFFF };
    119 
    120 class XfermodesView : public SampleView {
    121     SkBitmap    fBG;
    122     SkBitmap    fSrcB, fDstB;
    123 
    124     void draw_mode(SkCanvas* canvas, SkXfermode* mode, int alpha,
    125                    SkScalar x, SkScalar y) {
    126         SkPaint p;
    127 
    128         canvas->drawBitmap(fSrcB, x, y, &p);
    129         p.setAlpha(alpha);
    130         p.setXfermode(mode);
    131         canvas->drawBitmap(fDstB, x, y, &p);
    132     }
    133 
    134 public:
    135     const static int W = 64;
    136     const static int H = 64;
    137 	XfermodesView() {
    138         const int W = 64;
    139         const int H = 64;
    140 
    141         fBG.setConfig(SkBitmap::kARGB_4444_Config, 2, 2, 4);
    142         fBG.setPixels(gBG);
    143         fBG.setIsOpaque(true);
    144 
    145         make_bitmaps(W, H, &fSrcB, &fDstB);
    146     }
    147 
    148 protected:
    149     // overrides from SkEventSink
    150     virtual bool onQuery(SkEvent* evt) {
    151         if (SampleCode::TitleQ(*evt)) {
    152             SampleCode::TitleR(evt, "Xfermodes");
    153             return true;
    154         }
    155         return this->INHERITED::onQuery(evt);
    156     }
    157 
    158     virtual void onDrawContent(SkCanvas* canvas) {
    159         canvas->translate(SkIntToScalar(10), SkIntToScalar(20));
    160 
    161         const struct {
    162             SkXfermode::Mode  fMode;
    163             const char*         fLabel;
    164         } gModes[] = {
    165             { SkXfermode::kClear_Mode,    "Clear"     },
    166             { SkXfermode::kSrc_Mode,      "Src"       },
    167             { SkXfermode::kDst_Mode,      "Dst"       },
    168             { SkXfermode::kSrcOver_Mode,  "SrcOver"   },
    169             { SkXfermode::kDstOver_Mode,  "DstOver"   },
    170             { SkXfermode::kSrcIn_Mode,    "SrcIn"     },
    171             { SkXfermode::kDstIn_Mode,    "DstIn"     },
    172             { SkXfermode::kSrcOut_Mode,   "SrcOut"    },
    173             { SkXfermode::kDstOut_Mode,   "DstOut"    },
    174             { SkXfermode::kSrcATop_Mode,  "SrcATop"   },
    175             { SkXfermode::kDstATop_Mode,  "DstATop"   },
    176             { SkXfermode::kXor_Mode,      "Xor"       },
    177 
    178             { SkXfermode::kPlus_Mode,         "Plus"          },
    179             { SkXfermode::kMultiply_Mode,     "Multiply"      },
    180             { SkXfermode::kScreen_Mode,       "Screen"        },
    181             { SkXfermode::kOverlay_Mode,      "Overlay"       },
    182             { SkXfermode::kDarken_Mode,       "Darken"        },
    183             { SkXfermode::kLighten_Mode,      "Lighten"       },
    184             { SkXfermode::kColorDodge_Mode,   "ColorDodge"    },
    185             { SkXfermode::kColorBurn_Mode,    "ColorBurn"     },
    186             { SkXfermode::kHardLight_Mode,    "HardLight"     },
    187             { SkXfermode::kSoftLight_Mode,    "SoftLight"     },
    188             { SkXfermode::kDifference_Mode,   "Difference"    },
    189             { SkXfermode::kExclusion_Mode,    "Exclusion"     },
    190         };
    191 
    192         const SkScalar w = SkIntToScalar(W);
    193         const SkScalar h = SkIntToScalar(H);
    194         SkShader* s = SkShader::CreateBitmapShader(fBG,
    195                                                    SkShader::kRepeat_TileMode,
    196                                                    SkShader::kRepeat_TileMode);
    197         SkMatrix m;
    198         m.setScale(SkIntToScalar(6), SkIntToScalar(6));
    199         s->setLocalMatrix(m);
    200 
    201         SkPaint labelP;
    202         labelP.setAntiAlias(true);
    203         labelP.setLCDRenderText(true);
    204         labelP.setTextAlign(SkPaint::kCenter_Align);
    205         setNamedTypeface(&labelP, "Menlo Regular");
    206 //        labelP.setTextSize(SkIntToScalar(11));
    207 
    208         const int W = 5;
    209 
    210         SkScalar x0 = 0;
    211         for (int twice = 0; twice < 2; twice++) {
    212             SkScalar x = x0, y = 0;
    213             for (size_t i = 0; i < SK_ARRAY_COUNT(gModes); i++) {
    214                 SkXfermode* mode = SkXfermode::Create(gModes[i].fMode);
    215                 SkAutoUnref aur(mode);
    216                 SkRect r;
    217                 r.set(x, y, x+w, y+h);
    218 
    219                 SkPaint p;
    220                 p.setStyle(SkPaint::kFill_Style);
    221                 p.setShader(s);
    222                 canvas->drawRect(r, p);
    223 
    224                 canvas->saveLayer(&r, NULL, SkCanvas::kARGB_ClipLayer_SaveFlag);
    225          //       canvas->save();
    226                 draw_mode(canvas, mode, twice ? 0x88 : 0xFF, r.fLeft, r.fTop);
    227                 canvas->restore();
    228 
    229                 r.inset(-SK_ScalarHalf, -SK_ScalarHalf);
    230                 p.setStyle(SkPaint::kStroke_Style);
    231                 p.setShader(NULL);
    232                 canvas->drawRect(r, p);
    233 
    234 #if 1
    235                 canvas->drawText(gModes[i].fLabel, strlen(gModes[i].fLabel),
    236                                  x + w/2, y - labelP.getTextSize()/2, labelP);
    237 #endif
    238                 x += w + SkIntToScalar(10);
    239                 if ((i % W) == W - 1) {
    240                     x = x0;
    241                     y += h + SkIntToScalar(30);
    242                 }
    243             }
    244             x0 += SkIntToScalar(400);
    245         }
    246         s->unref();
    247     }
    248 
    249 private:
    250     typedef SampleView INHERITED;
    251 };
    252 
    253 //////////////////////////////////////////////////////////////////////////////
    254 
    255 static SkView* MyFactory() { return new XfermodesView; }
    256 static SkViewRegister reg(MyFactory);
    257 
    258