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