Home | History | Annotate | Download | only in core
      1 /* libs/graphics/sgl/SkPathEffect.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 "SkPathEffect.h"
     19 #include "SkPath.h"
     20 #include "SkBuffer.h"
     21 
     22 ///////////////////////////////////////////////////////////////////////////////
     23 
     24 SkPairPathEffect::SkPairPathEffect(SkPathEffect* pe0, SkPathEffect* pe1)
     25         : fPE0(pe0), fPE1(pe1) {
     26     SkASSERT(pe0);
     27     SkASSERT(pe1);
     28     fPE0->ref();
     29     fPE1->ref();
     30 }
     31 
     32 SkPairPathEffect::~SkPairPathEffect() {
     33     fPE0->unref();
     34     fPE1->unref();
     35 }
     36 
     37 /*
     38     Format: [oe0-factory][pe1-factory][pe0-size][pe0-data][pe1-data]
     39 */
     40 void SkPairPathEffect::flatten(SkFlattenableWriteBuffer& buffer) {
     41     buffer.writeFlattenable(fPE0);
     42     buffer.writeFlattenable(fPE1);
     43 }
     44 
     45 SkPairPathEffect::SkPairPathEffect(SkFlattenableReadBuffer& buffer) {
     46     fPE0 = (SkPathEffect*)buffer.readFlattenable();
     47     fPE1 = (SkPathEffect*)buffer.readFlattenable();
     48 }
     49 
     50 ///////////////////////////////////////////////////////////////////////////////
     51 
     52 bool SkComposePathEffect::filterPath(SkPath* dst, const SkPath& src,
     53                                      SkScalar* width) {
     54     SkPath          tmp;
     55     const SkPath*   ptr = &src;
     56 
     57     if (fPE1->filterPath(&tmp, src, width)) {
     58         ptr = &tmp;
     59     }
     60     return fPE0->filterPath(dst, *ptr, width);
     61 }
     62 
     63 ///////////////////////////////////////////////////////////////////////////////
     64 
     65 bool SkSumPathEffect::filterPath(SkPath* dst, const SkPath& src,
     66                                  SkScalar* width) {
     67     // use bit-or so that we always call both, even if the first one succeeds
     68     return  fPE0->filterPath(dst, src, width) | fPE1->filterPath(dst, src, width);
     69 }
     70 
     71 ///////////////////////////////////////////////////////////////////////////////
     72 
     73 #include "SkStroke.h"
     74 
     75 SkStrokePathEffect::SkStrokePathEffect(const SkPaint& paint)
     76     : fWidth(paint.getStrokeWidth()), fMiter(paint.getStrokeMiter()),
     77       fStyle(SkToU8(paint.getStyle())), fJoin(SkToU8(paint.getStrokeJoin())),
     78       fCap(SkToU8(paint.getStrokeCap())) {
     79 }
     80 
     81 SkStrokePathEffect::SkStrokePathEffect(SkScalar width, SkPaint::Style style,
     82                            SkPaint::Join join, SkPaint::Cap cap, SkScalar miter)
     83         : fWidth(width), fMiter(miter), fStyle(SkToU8(style)),
     84           fJoin(SkToU8(join)), fCap(SkToU8(cap)) {
     85     if (miter < 0) {  // signal they want the default
     86         fMiter = SK_DefaultMiterLimit;
     87     }
     88 }
     89 
     90 bool SkStrokePathEffect::filterPath(SkPath* dst, const SkPath& src,
     91                                     SkScalar* width) {
     92     if (fWidth < 0 || fStyle == SkPaint::kFill_Style) {
     93         return false;
     94     }
     95 
     96     if (fStyle == SkPaint::kStroke_Style && fWidth == 0) {  // hairline
     97         *width = 0;
     98         return true;
     99     }
    100 
    101     SkStroke    stroke;
    102 
    103     stroke.setWidth(fWidth);
    104     stroke.setMiterLimit(fMiter);
    105     stroke.setJoin((SkPaint::Join)fJoin);
    106     stroke.setCap((SkPaint::Cap)fCap);
    107     stroke.setDoFill(fStyle == SkPaint::kStrokeAndFill_Style);
    108 
    109     stroke.strokePath(src, dst);
    110     return true;
    111 }
    112 
    113 SkFlattenable::Factory SkStrokePathEffect::getFactory() {
    114     return CreateProc;
    115 }
    116 
    117 SkFlattenable* SkStrokePathEffect::CreateProc(SkFlattenableReadBuffer& buffer) {
    118     return SkNEW_ARGS(SkStrokePathEffect, (buffer));
    119 }
    120 
    121 void SkStrokePathEffect::flatten(SkFlattenableWriteBuffer& buffer) {
    122     buffer.writeScalar(fWidth);
    123     buffer.writeScalar(fMiter);
    124     buffer.write8(fStyle);
    125     buffer.write8(fJoin);
    126     buffer.write8(fCap);
    127 }
    128 
    129 SkStrokePathEffect::SkStrokePathEffect(SkFlattenableReadBuffer& buffer) {
    130     fWidth = buffer.readScalar();
    131     fMiter = buffer.readScalar();
    132     fStyle = buffer.readU8();
    133     fJoin = buffer.readU8();
    134     fCap = buffer.readU8();
    135 }
    136 
    137