Home | History | Annotate | Download | only in samplecode
      1 #include "SampleCode.h"
      2 #include "SkCanvas.h"
      3 #include "SkParsePath.h"
      4 #include "SkPath.h"
      5 #include "SkRandom.h"
      6 #include "SkView.h"
      7 
      8 #include "SkBlurMaskFilter.h"
      9 
     10 static void test_huge_stroke(SkCanvas* canvas) {
     11     SkRect srcR = { 0, 0, 72000, 54000 };
     12     SkRect dstR = { 0, 0, 640, 480 };
     13 
     14     SkPath path;
     15     path.moveTo(17600, 8000);
     16     path.lineTo(52800, 8000);
     17     path.lineTo(52800, 41600);
     18     path.lineTo(17600, 41600);
     19     path.close();
     20 
     21     SkPaint paint;
     22     paint.setAntiAlias(true);
     23     paint.setStrokeWidth(8000);
     24     paint.setStrokeMiter(10);
     25     paint.setStrokeCap(SkPaint::kButt_Cap);
     26     paint.setStrokeJoin(SkPaint::kRound_Join);
     27     paint.setStyle(SkPaint::kStroke_Style);
     28 
     29     SkMatrix matrix;
     30     matrix.setRectToRect(srcR, dstR, SkMatrix::kCenter_ScaleToFit);
     31     canvas->concat(matrix);
     32 
     33     canvas->drawPath(path, paint);
     34 }
     35 
     36 #if 0
     37 #include "SkBlurMask.h"
     38 static void test_blur() {
     39     uint8_t cell[9];
     40     memset(cell, 0xFF, sizeof(cell));
     41     SkMask src;
     42     src.fImage = cell;
     43     src.fFormat = SkMask::kA8_Format;
     44     SkMask dst;
     45 
     46     for (int y = 1; y <= 3; y++) {
     47         for (int x = 1; x <= 3; x++) {
     48             src.fBounds.set(0, 0, x, y);
     49             src.fRowBytes = src.fBounds.width();
     50 
     51             SkScalar radius = 1.f;
     52 
     53             printf("src [%d %d %d %d] radius %g\n", src.fBounds.fLeft, src.fBounds.fTop,
     54                    src.fBounds.fRight, src.fBounds.fBottom, radius);
     55 
     56             SkBlurMask::Blur(&dst, src, radius, SkBlurMask::kNormal_Style);
     57             uint8_t* dstPtr = dst.fImage;
     58 
     59             for (int y = 0; y < dst.fBounds.height(); y++) {
     60                 for (int x = 0; x < dst.fBounds.width(); x++) {
     61                     printf(" %02X", dstPtr[x]);
     62                 }
     63                 printf("\n");
     64                 dstPtr += dst.fRowBytes;
     65             }
     66         }
     67     }
     68 }
     69 #endif
     70 
     71 static void scale_to_width(SkPath* path, SkScalar dstWidth) {
     72     const SkRect& bounds = path->getBounds();
     73     SkScalar scale = dstWidth / bounds.width();
     74     SkMatrix matrix;
     75 
     76     matrix.setScale(scale, scale);
     77     path->transform(matrix);
     78 }
     79 
     80 static const struct {
     81     SkPaint::Style  fStyle;
     82     SkPaint::Join   fJoin;
     83     int             fStrokeWidth;
     84 } gRec[] = {
     85     { SkPaint::kFill_Style,             SkPaint::kMiter_Join,   0 },
     86     { SkPaint::kStroke_Style,           SkPaint::kMiter_Join,   0 },
     87     { SkPaint::kStroke_Style,           SkPaint::kMiter_Join,   10 },
     88     { SkPaint::kStrokeAndFill_Style,    SkPaint::kMiter_Join,   10 },
     89 };
     90 
     91 class StrokePathView : public SampleView {
     92     SkScalar    fWidth;
     93     SkPath      fPath;
     94 public:
     95 	StrokePathView() {
     96 //        test_blur();
     97         fWidth = SkIntToScalar(120);
     98 
     99 #if 0
    100         const char str[] =
    101             "M 0, 3"
    102             "C 10, -10, 30, -10, 0, 28"
    103             "C -30, -10, -10, -10, 0, 3"
    104             "Z";
    105         SkParsePath::FromSVGString(str, &fPath);
    106 #else
    107         fPath.addCircle(0, 0, SkIntToScalar(50), SkPath::kCW_Direction);
    108         fPath.addCircle(0, SkIntToScalar(-50), SkIntToScalar(30), SkPath::kCW_Direction);
    109 #endif
    110 
    111         scale_to_width(&fPath, fWidth);
    112         const SkRect& bounds = fPath.getBounds();
    113         fPath.offset(-bounds.fLeft, -bounds.fTop);
    114 
    115         this->setBGColor(0xFFDDDDDD);
    116     }
    117 
    118 protected:
    119     // overrides from SkEventSink
    120     virtual bool onQuery(SkEvent* evt) {
    121         if (SampleCode::TitleQ(*evt)) {
    122             SampleCode::TitleR(evt, "StrokePath");
    123             return true;
    124         }
    125         return this->INHERITED::onQuery(evt);
    126     }
    127 
    128     SkRandom rand;
    129 
    130     void drawSet(SkCanvas* canvas, SkPaint* paint) {
    131         SkAutoCanvasRestore acr(canvas, true);
    132 
    133         for (size_t i = 0; i < SK_ARRAY_COUNT(gRec); i++) {
    134             paint->setStyle(gRec[i].fStyle);
    135             paint->setStrokeJoin(gRec[i].fJoin);
    136             paint->setStrokeWidth(SkIntToScalar(gRec[i].fStrokeWidth));
    137             canvas->drawPath(fPath, *paint);
    138             canvas->translate(fWidth * 5 / 4, 0);
    139         }
    140     }
    141 
    142     virtual void onDrawContent(SkCanvas* canvas) {
    143         test_huge_stroke(canvas); return;
    144         canvas->translate(SkIntToScalar(10), SkIntToScalar(10));
    145 
    146         SkPaint paint;
    147         paint.setAntiAlias(true);
    148 
    149         if (true) {
    150             canvas->drawColor(SK_ColorBLACK);
    151 
    152             paint.setTextSize(24);
    153             paint.setColor(SK_ColorWHITE);
    154             canvas->translate(10, 30);
    155 
    156             static const SkBlurMaskFilter::BlurStyle gStyle[] = {
    157                 SkBlurMaskFilter::kNormal_BlurStyle,
    158                 SkBlurMaskFilter::kInner_BlurStyle,
    159                 SkBlurMaskFilter::kOuter_BlurStyle,
    160                 SkBlurMaskFilter::kSolid_BlurStyle,
    161             };
    162             for (int x = 0; x < 5; x++) {
    163                 SkMaskFilter* mf;
    164                 SkScalar radius = 4;
    165                 for (int y = 0; y < 10; y++) {
    166                     if (x) {
    167                         mf = SkBlurMaskFilter::Create(radius, gStyle[x - 1]);
    168                         paint.setMaskFilter(mf)->unref();
    169                     }
    170                     canvas->drawText("Title Bar", 9, x*SkIntToScalar(100), y*SkIntToScalar(30), paint);
    171                     radius *= 0.75f;
    172                 }
    173 
    174             }
    175             return;
    176         }
    177 
    178         paint.setColor(SK_ColorBLUE);
    179 
    180 #if 1
    181         SkPath p;
    182         float r = rand.nextUScalar1() + 0.5f;
    183         SkScalar x = 0, y = 0;
    184         p.moveTo(x, y);
    185 #if 0
    186         p.cubicTo(x-75*r, y+75*r, x-40*r, y+125*r, x, y+85*r);
    187         p.cubicTo(x+40*r, y+125*r, x+75*r, y+75*r, x, y);
    188 #else
    189         p.cubicTo(x+75*r, y+75*r, x+40*r, y+125*r, x, y+85*r);
    190         p.cubicTo(x-40*r, y+125*r, x-75*r, y+75*r, x, y);
    191 #endif
    192         p.close();
    193         fPath = p;
    194         fPath.offset(100, 0);
    195 #endif
    196 
    197         fPath.setFillType(SkPath::kWinding_FillType);
    198         drawSet(canvas, &paint);
    199 
    200         canvas->translate(0, fPath.getBounds().height() * 5 / 4);
    201         fPath.setFillType(SkPath::kEvenOdd_FillType);
    202         drawSet(canvas, &paint);
    203     }
    204 
    205     virtual SkView::Click* onFindClickHandler(SkScalar x, SkScalar y) {
    206         this->inval(NULL);
    207         return this->INHERITED::onFindClickHandler(x, y);
    208     }
    209 private:
    210     typedef SampleView INHERITED;
    211 };
    212 
    213 //////////////////////////////////////////////////////////////////////////////
    214 
    215 static SkView* MyFactory() { return new StrokePathView; }
    216 static SkViewRegister reg(MyFactory);
    217 
    218