Home | History | Annotate | Download | only in effects
      1 
      2 /*
      3  * Copyright 2006 The Android Open Source Project
      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 
      9 
     10 #include "Sk2DPathEffect.h"
     11 #include "SkBlitter.h"
     12 #include "SkPath.h"
     13 #include "SkScan.h"
     14 
     15 class Sk2DPathEffectBlitter : public SkBlitter {
     16 public:
     17     Sk2DPathEffectBlitter(Sk2DPathEffect* pe, SkPath* dst)
     18         : fPE(pe), fDst(dst) {}
     19 
     20     virtual void blitH(int x, int y, int count) {
     21         fPE->nextSpan(x, y, count, fDst);
     22     }
     23 private:
     24     Sk2DPathEffect* fPE;
     25     SkPath*         fDst;
     26 };
     27 
     28 ///////////////////////////////////////////////////////////////////////////////
     29 
     30 Sk2DPathEffect::Sk2DPathEffect(const SkMatrix& mat) : fMatrix(mat) {
     31     mat.invert(&fInverse);
     32 }
     33 
     34 bool Sk2DPathEffect::filterPath(SkPath* dst, const SkPath& src, SkScalar* width) {
     35     Sk2DPathEffectBlitter   blitter(this, dst);
     36     SkPath                  tmp;
     37     SkIRect                 ir;
     38 
     39     src.transform(fInverse, &tmp);
     40     tmp.getBounds().round(&ir);
     41     if (!ir.isEmpty()) {
     42         this->begin(ir, dst);
     43         SkScan::FillPath(tmp, ir, &blitter);
     44         this->end(dst);
     45     }
     46     return true;
     47 }
     48 
     49 void Sk2DPathEffect::nextSpan(int x, int y, int count, SkPath* path) {
     50     const SkMatrix& mat = this->getMatrix();
     51     SkPoint src, dst;
     52 
     53     src.set(SkIntToScalar(x) + SK_ScalarHalf, SkIntToScalar(y) + SK_ScalarHalf);
     54     do {
     55         mat.mapPoints(&dst, &src, 1);
     56         this->next(dst, x++, y, path);
     57         src.fX += SK_Scalar1;
     58     } while (--count > 0);
     59 }
     60 
     61 void Sk2DPathEffect::begin(const SkIRect& uvBounds, SkPath* dst) {}
     62 void Sk2DPathEffect::next(const SkPoint& loc, int u, int v, SkPath* dst) {}
     63 void Sk2DPathEffect::end(SkPath* dst) {}
     64 
     65 ///////////////////////////////////////////////////////////////////////////////
     66 
     67 void Sk2DPathEffect::flatten(SkFlattenableWriteBuffer& buffer) {
     68     char storage[SkMatrix::kMaxFlattenSize];
     69     uint32_t size = fMatrix.flatten(storage);
     70     buffer.write32(size);
     71     buffer.write(storage, size);
     72 }
     73 
     74 Sk2DPathEffect::Sk2DPathEffect(SkFlattenableReadBuffer& buffer) {
     75     char storage[SkMatrix::kMaxFlattenSize];
     76     uint32_t size = buffer.readS32();
     77     SkASSERT(size <= sizeof(storage));
     78     buffer.read(storage, size);
     79     fMatrix.unflatten(storage);
     80     fMatrix.invert(&fInverse);
     81 }
     82 
     83 SkFlattenable::Factory Sk2DPathEffect::getFactory() {
     84     return CreateProc;
     85 }
     86 
     87 SkFlattenable* Sk2DPathEffect::CreateProc(SkFlattenableReadBuffer& buffer) {
     88     return SkNEW_ARGS(Sk2DPathEffect, (buffer));
     89 }
     90 
     91 ///////////////////////////////////////////////////////////////////////////////
     92 ///////////////////////////////////////////////////////////////////////////////
     93 
     94 SkPath2DPathEffect::SkPath2DPathEffect(const SkMatrix& m, const SkPath& p)
     95     : INHERITED(m), fPath(p) {
     96 }
     97 
     98 SkPath2DPathEffect::SkPath2DPathEffect(SkFlattenableReadBuffer& buffer)
     99         : INHERITED(buffer) {
    100     fPath.unflatten(buffer);
    101 }
    102 
    103 SkFlattenable* SkPath2DPathEffect::CreateProc(SkFlattenableReadBuffer& buffer) {
    104     return SkNEW_ARGS(SkPath2DPathEffect, (buffer));
    105 }
    106 
    107 void SkPath2DPathEffect::flatten(SkFlattenableWriteBuffer& buffer) {
    108     this->INHERITED::flatten(buffer);
    109     fPath.flatten(buffer);
    110 }
    111 
    112 SkFlattenable::Factory SkPath2DPathEffect::getFactory() {
    113     return CreateProc;
    114 }
    115 
    116 void SkPath2DPathEffect::next(const SkPoint& loc, int u, int v, SkPath* dst) {
    117     dst->addPath(fPath, loc.fX, loc.fY);
    118 }
    119 
    120 SK_DEFINE_FLATTENABLE_REGISTRAR(SkPath2DPathEffect)
    121 
    122