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 "SkReadBuffer.h"
     12 #include "SkWriteBuffer.h"
     13 #include "SkPath.h"
     14 #include "SkRegion.h"
     15 
     16 Sk2DPathEffect::Sk2DPathEffect(const SkMatrix& mat) : fMatrix(mat) {
     17     fMatrixIsInvertible = mat.invert(&fInverse);
     18 }
     19 
     20 bool Sk2DPathEffect::filterPath(SkPath* dst, const SkPath& src,
     21                                 SkStrokeRec*, const SkRect*) const {
     22     if (!fMatrixIsInvertible) {
     23         return false;
     24     }
     25 
     26     SkPath  tmp;
     27     SkIRect ir;
     28 
     29     src.transform(fInverse, &tmp);
     30     tmp.getBounds().round(&ir);
     31     if (!ir.isEmpty()) {
     32         this->begin(ir, dst);
     33 
     34         SkRegion rgn;
     35         rgn.setPath(tmp, SkRegion(ir));
     36         SkRegion::Iterator iter(rgn);
     37         for (; !iter.done(); iter.next()) {
     38             const SkIRect& rect = iter.rect();
     39             for (int y = rect.fTop; y < rect.fBottom; ++y) {
     40                 this->nextSpan(rect.fLeft, y, rect.width(), dst);
     41             }
     42         }
     43 
     44         this->end(dst);
     45     }
     46     return true;
     47 }
     48 
     49 void Sk2DPathEffect::nextSpan(int x, int y, int count, SkPath* path) const {
     50     if (!fMatrixIsInvertible) {
     51         return;
     52     }
     53 
     54     const SkMatrix& mat = this->getMatrix();
     55     SkPoint src, dst;
     56 
     57     src.set(SkIntToScalar(x) + SK_ScalarHalf, SkIntToScalar(y) + SK_ScalarHalf);
     58     do {
     59         mat.mapPoints(&dst, &src, 1);
     60         this->next(dst, x++, y, path);
     61         src.fX += SK_Scalar1;
     62     } while (--count > 0);
     63 }
     64 
     65 void Sk2DPathEffect::begin(const SkIRect& uvBounds, SkPath* dst) const {}
     66 void Sk2DPathEffect::next(const SkPoint& loc, int u, int v, SkPath* dst) const {}
     67 void Sk2DPathEffect::end(SkPath* dst) const {}
     68 
     69 ///////////////////////////////////////////////////////////////////////////////
     70 
     71 void Sk2DPathEffect::flatten(SkWriteBuffer& buffer) const {
     72     this->INHERITED::flatten(buffer);
     73     buffer.writeMatrix(fMatrix);
     74 }
     75 
     76 #ifdef SK_SUPPORT_LEGACY_DEEPFLATTENING
     77 Sk2DPathEffect::Sk2DPathEffect(SkReadBuffer& buffer) {
     78     buffer.readMatrix(&fMatrix);
     79     fMatrixIsInvertible = fMatrix.invert(&fInverse);
     80 }
     81 #endif
     82 
     83 ///////////////////////////////////////////////////////////////////////////////
     84 
     85 bool SkLine2DPathEffect::filterPath(SkPath* dst, const SkPath& src,
     86                             SkStrokeRec* rec, const SkRect* cullRect) const {
     87     if (this->INHERITED::filterPath(dst, src, rec, cullRect)) {
     88         rec->setStrokeStyle(fWidth);
     89         return true;
     90     }
     91     return false;
     92 }
     93 
     94 void SkLine2DPathEffect::nextSpan(int u, int v, int ucount, SkPath* dst) const {
     95     if (ucount > 1) {
     96         SkPoint    src[2], dstP[2];
     97 
     98         src[0].set(SkIntToScalar(u) + SK_ScalarHalf, SkIntToScalar(v) + SK_ScalarHalf);
     99         src[1].set(SkIntToScalar(u+ucount) + SK_ScalarHalf, SkIntToScalar(v) + SK_ScalarHalf);
    100         this->getMatrix().mapPoints(dstP, src, 2);
    101 
    102         dst->moveTo(dstP[0]);
    103         dst->lineTo(dstP[1]);
    104     }
    105 }
    106 
    107 #ifdef SK_SUPPORT_LEGACY_DEEPFLATTENING
    108 SkLine2DPathEffect::SkLine2DPathEffect(SkReadBuffer& buffer) : INHERITED(buffer) {
    109     fWidth = buffer.readScalar();
    110 }
    111 #endif
    112 
    113 SkFlattenable* SkLine2DPathEffect::CreateProc(SkReadBuffer& buffer) {
    114     SkMatrix matrix;
    115     buffer.readMatrix(&matrix);
    116     SkScalar width = buffer.readScalar();
    117     return SkLine2DPathEffect::Create(width, matrix);
    118 }
    119 
    120 void SkLine2DPathEffect::flatten(SkWriteBuffer &buffer) const {
    121     buffer.writeMatrix(this->getMatrix());
    122     buffer.writeScalar(fWidth);
    123 }
    124 
    125 ///////////////////////////////////////////////////////////////////////////////
    126 
    127 SkPath2DPathEffect::SkPath2DPathEffect(const SkMatrix& m, const SkPath& p)
    128     : INHERITED(m), fPath(p) {
    129 }
    130 
    131 #ifdef SK_SUPPORT_LEGACY_DEEPFLATTENING
    132 SkPath2DPathEffect::SkPath2DPathEffect(SkReadBuffer& buffer) : INHERITED(buffer) {
    133     buffer.readPath(&fPath);
    134 }
    135 #endif
    136 
    137 SkFlattenable* SkPath2DPathEffect::CreateProc(SkReadBuffer& buffer) {
    138     SkMatrix matrix;
    139     buffer.readMatrix(&matrix);
    140     SkPath path;
    141     buffer.readPath(&path);
    142     return SkPath2DPathEffect::Create(matrix, path);
    143 }
    144 
    145 void SkPath2DPathEffect::flatten(SkWriteBuffer& buffer) const {
    146     buffer.writeMatrix(this->getMatrix());
    147     buffer.writePath(fPath);
    148 }
    149 
    150 void SkPath2DPathEffect::next(const SkPoint& loc, int u, int v,
    151                               SkPath* dst) const {
    152     dst->addPath(fPath, loc.fX, loc.fY);
    153 }
    154