Home | History | Annotate | Download | only in effects
      1 /* libs/graphics/effects/Sk2DPathEffect.cpp
      2 **
      3 ** Copyright 2006, The Android Open Source Project
      4 **
      5 ** Licensed under the Apache License, Version 2.0 (the "License");
      6 ** you may not use this file except in compliance with the License.
      7 ** You may obtain a copy of the License at
      8 **
      9 **     http://www.apache.org/licenses/LICENSE-2.0
     10 **
     11 ** Unless required by applicable law or agreed to in writing, software
     12 ** distributed under the License is distributed on an "AS IS" BASIS,
     13 ** WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
     14 ** See the License for the specific language governing permissions and
     15 ** limitations under the License.
     16 */
     17 
     18 #include "Sk2DPathEffect.h"
     19 #include "SkBlitter.h"
     20 #include "SkPath.h"
     21 #include "SkScan.h"
     22 
     23 class Sk2DPathEffectBlitter : public SkBlitter {
     24 public:
     25     Sk2DPathEffectBlitter(Sk2DPathEffect* pe, SkPath* dst)
     26         : fPE(pe), fDst(dst)
     27     {}
     28     virtual void blitH(int x, int y, int count)
     29     {
     30         fPE->nextSpan(x, y, count, fDst);
     31     }
     32 private:
     33     Sk2DPathEffect* fPE;
     34     SkPath*         fDst;
     35 };
     36 
     37 ////////////////////////////////////////////////////////////////////////////////////
     38 
     39 Sk2DPathEffect::Sk2DPathEffect(const SkMatrix& mat) : fMatrix(mat)
     40 {
     41     mat.invert(&fInverse);
     42 }
     43 
     44 bool Sk2DPathEffect::filterPath(SkPath* dst, const SkPath& src, SkScalar* width)
     45 {
     46     Sk2DPathEffectBlitter   blitter(this, dst);
     47     SkPath                  tmp;
     48     SkIRect                 ir;
     49 
     50     src.transform(fInverse, &tmp);
     51     tmp.getBounds().round(&ir);
     52     if (!ir.isEmpty()) {
     53         // need to pass a clip to fillpath, required for inverse filltypes,
     54         // even though those do not make sense for this patheffect
     55         SkRegion clip(ir);
     56 
     57         this->begin(ir, dst);
     58         SkScan::FillPath(tmp, clip, &blitter);
     59         this->end(dst);
     60     }
     61     return true;
     62 }
     63 
     64 void Sk2DPathEffect::nextSpan(int x, int y, int count, SkPath* path)
     65 {
     66     const SkMatrix& mat = this->getMatrix();
     67     SkPoint src, dst;
     68 
     69     src.set(SkIntToScalar(x) + SK_ScalarHalf, SkIntToScalar(y) + SK_ScalarHalf);
     70     do {
     71         mat.mapPoints(&dst, &src, 1);
     72         this->next(dst, x++, y, path);
     73         src.fX += SK_Scalar1;
     74     } while (--count > 0);
     75 }
     76 
     77 void Sk2DPathEffect::begin(const SkIRect& uvBounds, SkPath* dst) {}
     78 void Sk2DPathEffect::next(const SkPoint& loc, int u, int v, SkPath* dst) {}
     79 void Sk2DPathEffect::end(SkPath* dst) {}
     80 
     81 ////////////////////////////////////////////////////////////////////////////////
     82 
     83 void Sk2DPathEffect::flatten(SkFlattenableWriteBuffer& buffer)
     84 {
     85     char storage[SkMatrix::kMaxFlattenSize];
     86     uint32_t size = fMatrix.flatten(storage);
     87     buffer.write32(size);
     88     buffer.write(storage, size);
     89 }
     90 
     91 Sk2DPathEffect::Sk2DPathEffect(SkFlattenableReadBuffer& buffer)
     92 {
     93     char storage[SkMatrix::kMaxFlattenSize];
     94     uint32_t size = buffer.readS32();
     95     SkASSERT(size <= sizeof(storage));
     96     buffer.read(storage, size);
     97     fMatrix.unflatten(storage);
     98     fMatrix.invert(&fInverse);
     99 }
    100 
    101 SkFlattenable::Factory Sk2DPathEffect::getFactory()
    102 {
    103     return CreateProc;
    104 }
    105 
    106 SkFlattenable* Sk2DPathEffect::CreateProc(SkFlattenableReadBuffer& buffer)
    107 {
    108     return SkNEW_ARGS(Sk2DPathEffect, (buffer));
    109 }
    110 
    111 
    112 
    113