SkDiscretePathEffect.cpp revision 0910916c0f7b951ee55c4b7c6358295b9bca0565
10910916c0f7b951ee55c4b7c6358295b9bca0565The Android Open Source Project/* libs/graphics/effects/SkDiscretePathEffect.cpp
20910916c0f7b951ee55c4b7c6358295b9bca0565The Android Open Source Project**
30910916c0f7b951ee55c4b7c6358295b9bca0565The Android Open Source Project** Copyright 2006, The Android Open Source Project
40910916c0f7b951ee55c4b7c6358295b9bca0565The Android Open Source Project**
50910916c0f7b951ee55c4b7c6358295b9bca0565The Android Open Source Project** Licensed under the Apache License, Version 2.0 (the "License");
60910916c0f7b951ee55c4b7c6358295b9bca0565The Android Open Source Project** you may not use this file except in compliance with the License.
70910916c0f7b951ee55c4b7c6358295b9bca0565The Android Open Source Project** You may obtain a copy of the License at
80910916c0f7b951ee55c4b7c6358295b9bca0565The Android Open Source Project**
90910916c0f7b951ee55c4b7c6358295b9bca0565The Android Open Source Project**     http://www.apache.org/licenses/LICENSE-2.0
100910916c0f7b951ee55c4b7c6358295b9bca0565The Android Open Source Project**
110910916c0f7b951ee55c4b7c6358295b9bca0565The Android Open Source Project** Unless required by applicable law or agreed to in writing, software
120910916c0f7b951ee55c4b7c6358295b9bca0565The Android Open Source Project** distributed under the License is distributed on an "AS IS" BASIS,
130910916c0f7b951ee55c4b7c6358295b9bca0565The Android Open Source Project** WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
140910916c0f7b951ee55c4b7c6358295b9bca0565The Android Open Source Project** See the License for the specific language governing permissions and
150910916c0f7b951ee55c4b7c6358295b9bca0565The Android Open Source Project** limitations under the License.
160910916c0f7b951ee55c4b7c6358295b9bca0565The Android Open Source Project*/
170910916c0f7b951ee55c4b7c6358295b9bca0565The Android Open Source Project
180910916c0f7b951ee55c4b7c6358295b9bca0565The Android Open Source Project#include "SkDiscretePathEffect.h"
190910916c0f7b951ee55c4b7c6358295b9bca0565The Android Open Source Project#include "SkBuffer.h"
200910916c0f7b951ee55c4b7c6358295b9bca0565The Android Open Source Project#include "SkPathMeasure.h"
210910916c0f7b951ee55c4b7c6358295b9bca0565The Android Open Source Project#include "SkRandom.h"
220910916c0f7b951ee55c4b7c6358295b9bca0565The Android Open Source Project
230910916c0f7b951ee55c4b7c6358295b9bca0565The Android Open Source Projectstatic void Perterb(SkPoint* p, const SkVector& tangent, SkScalar scale)
240910916c0f7b951ee55c4b7c6358295b9bca0565The Android Open Source Project{
250910916c0f7b951ee55c4b7c6358295b9bca0565The Android Open Source Project    SkVector normal = tangent;
260910916c0f7b951ee55c4b7c6358295b9bca0565The Android Open Source Project    normal.rotateCCW();
270910916c0f7b951ee55c4b7c6358295b9bca0565The Android Open Source Project    normal.setLength(scale);
280910916c0f7b951ee55c4b7c6358295b9bca0565The Android Open Source Project    *p += normal;
290910916c0f7b951ee55c4b7c6358295b9bca0565The Android Open Source Project}
300910916c0f7b951ee55c4b7c6358295b9bca0565The Android Open Source Project
310910916c0f7b951ee55c4b7c6358295b9bca0565The Android Open Source Project
320910916c0f7b951ee55c4b7c6358295b9bca0565The Android Open Source ProjectSkDiscretePathEffect::SkDiscretePathEffect(SkScalar segLength, SkScalar deviation)
330910916c0f7b951ee55c4b7c6358295b9bca0565The Android Open Source Project    : fSegLength(segLength), fPerterb(deviation)
340910916c0f7b951ee55c4b7c6358295b9bca0565The Android Open Source Project{
350910916c0f7b951ee55c4b7c6358295b9bca0565The Android Open Source Project}
360910916c0f7b951ee55c4b7c6358295b9bca0565The Android Open Source Project
370910916c0f7b951ee55c4b7c6358295b9bca0565The Android Open Source Projectbool SkDiscretePathEffect::filterPath(SkPath* dst, const SkPath& src, SkScalar* width)
380910916c0f7b951ee55c4b7c6358295b9bca0565The Android Open Source Project{
390910916c0f7b951ee55c4b7c6358295b9bca0565The Android Open Source Project    bool doFill = *width < 0;
400910916c0f7b951ee55c4b7c6358295b9bca0565The Android Open Source Project
410910916c0f7b951ee55c4b7c6358295b9bca0565The Android Open Source Project    SkPathMeasure   meas(src, doFill);
420910916c0f7b951ee55c4b7c6358295b9bca0565The Android Open Source Project    uint32_t        seed = SkScalarRound(meas.getLength());
430910916c0f7b951ee55c4b7c6358295b9bca0565The Android Open Source Project    SkRandom        rand(seed ^ ((seed << 16) | (seed >> 16)));
440910916c0f7b951ee55c4b7c6358295b9bca0565The Android Open Source Project    SkScalar        scale = fPerterb;
450910916c0f7b951ee55c4b7c6358295b9bca0565The Android Open Source Project    SkPoint         p;
460910916c0f7b951ee55c4b7c6358295b9bca0565The Android Open Source Project    SkVector        v;
470910916c0f7b951ee55c4b7c6358295b9bca0565The Android Open Source Project
480910916c0f7b951ee55c4b7c6358295b9bca0565The Android Open Source Project    do {
490910916c0f7b951ee55c4b7c6358295b9bca0565The Android Open Source Project        SkScalar    length = meas.getLength();
500910916c0f7b951ee55c4b7c6358295b9bca0565The Android Open Source Project
510910916c0f7b951ee55c4b7c6358295b9bca0565The Android Open Source Project        if (fSegLength * (2 + doFill) > length)
520910916c0f7b951ee55c4b7c6358295b9bca0565The Android Open Source Project        {
530910916c0f7b951ee55c4b7c6358295b9bca0565The Android Open Source Project            meas.getSegment(0, length, dst, true);  // to short for us to mangle
540910916c0f7b951ee55c4b7c6358295b9bca0565The Android Open Source Project        }
550910916c0f7b951ee55c4b7c6358295b9bca0565The Android Open Source Project        else
560910916c0f7b951ee55c4b7c6358295b9bca0565The Android Open Source Project        {
570910916c0f7b951ee55c4b7c6358295b9bca0565The Android Open Source Project            int         n = SkScalarRound(SkScalarDiv(length, fSegLength));
580910916c0f7b951ee55c4b7c6358295b9bca0565The Android Open Source Project            SkScalar    delta = length / n;
590910916c0f7b951ee55c4b7c6358295b9bca0565The Android Open Source Project            SkScalar    distance = 0;
600910916c0f7b951ee55c4b7c6358295b9bca0565The Android Open Source Project
610910916c0f7b951ee55c4b7c6358295b9bca0565The Android Open Source Project            if (meas.isClosed())
620910916c0f7b951ee55c4b7c6358295b9bca0565The Android Open Source Project            {
630910916c0f7b951ee55c4b7c6358295b9bca0565The Android Open Source Project                n -= 1;
640910916c0f7b951ee55c4b7c6358295b9bca0565The Android Open Source Project                distance += delta/2;
650910916c0f7b951ee55c4b7c6358295b9bca0565The Android Open Source Project            }
660910916c0f7b951ee55c4b7c6358295b9bca0565The Android Open Source Project            meas.getPosTan(distance, &p, &v);
670910916c0f7b951ee55c4b7c6358295b9bca0565The Android Open Source Project            Perterb(&p, v, SkScalarMul(rand.nextSScalar1(), scale));
680910916c0f7b951ee55c4b7c6358295b9bca0565The Android Open Source Project            dst->moveTo(p);
690910916c0f7b951ee55c4b7c6358295b9bca0565The Android Open Source Project            while (--n >= 0)
700910916c0f7b951ee55c4b7c6358295b9bca0565The Android Open Source Project            {
710910916c0f7b951ee55c4b7c6358295b9bca0565The Android Open Source Project                distance += delta;
720910916c0f7b951ee55c4b7c6358295b9bca0565The Android Open Source Project                meas.getPosTan(distance, &p, &v);
730910916c0f7b951ee55c4b7c6358295b9bca0565The Android Open Source Project                Perterb(&p, v, SkScalarMul(rand.nextSScalar1(), scale));
740910916c0f7b951ee55c4b7c6358295b9bca0565The Android Open Source Project                dst->lineTo(p);
750910916c0f7b951ee55c4b7c6358295b9bca0565The Android Open Source Project            }
760910916c0f7b951ee55c4b7c6358295b9bca0565The Android Open Source Project            if (meas.isClosed())
770910916c0f7b951ee55c4b7c6358295b9bca0565The Android Open Source Project                dst->close();
780910916c0f7b951ee55c4b7c6358295b9bca0565The Android Open Source Project        }
790910916c0f7b951ee55c4b7c6358295b9bca0565The Android Open Source Project    } while (meas.nextContour());
800910916c0f7b951ee55c4b7c6358295b9bca0565The Android Open Source Project    return true;
810910916c0f7b951ee55c4b7c6358295b9bca0565The Android Open Source Project}
820910916c0f7b951ee55c4b7c6358295b9bca0565The Android Open Source Project
830910916c0f7b951ee55c4b7c6358295b9bca0565The Android Open Source ProjectSkFlattenable::Factory SkDiscretePathEffect::getFactory()
840910916c0f7b951ee55c4b7c6358295b9bca0565The Android Open Source Project{
850910916c0f7b951ee55c4b7c6358295b9bca0565The Android Open Source Project    return CreateProc;
860910916c0f7b951ee55c4b7c6358295b9bca0565The Android Open Source Project}
870910916c0f7b951ee55c4b7c6358295b9bca0565The Android Open Source Project
880910916c0f7b951ee55c4b7c6358295b9bca0565The Android Open Source ProjectSkFlattenable* SkDiscretePathEffect::CreateProc(SkFlattenableReadBuffer& buffer)
890910916c0f7b951ee55c4b7c6358295b9bca0565The Android Open Source Project{
900910916c0f7b951ee55c4b7c6358295b9bca0565The Android Open Source Project    return SkNEW_ARGS(SkDiscretePathEffect, (buffer));
910910916c0f7b951ee55c4b7c6358295b9bca0565The Android Open Source Project}
920910916c0f7b951ee55c4b7c6358295b9bca0565The Android Open Source Project
930910916c0f7b951ee55c4b7c6358295b9bca0565The Android Open Source Projectvoid SkDiscretePathEffect::flatten(SkFlattenableWriteBuffer& buffer)
940910916c0f7b951ee55c4b7c6358295b9bca0565The Android Open Source Project{
950910916c0f7b951ee55c4b7c6358295b9bca0565The Android Open Source Project    buffer.writeScalar(fSegLength);
960910916c0f7b951ee55c4b7c6358295b9bca0565The Android Open Source Project    buffer.writeScalar(fPerterb);
970910916c0f7b951ee55c4b7c6358295b9bca0565The Android Open Source Project}
980910916c0f7b951ee55c4b7c6358295b9bca0565The Android Open Source Project
990910916c0f7b951ee55c4b7c6358295b9bca0565The Android Open Source ProjectSkDiscretePathEffect::SkDiscretePathEffect(SkFlattenableReadBuffer& buffer)
1000910916c0f7b951ee55c4b7c6358295b9bca0565The Android Open Source Project{
1010910916c0f7b951ee55c4b7c6358295b9bca0565The Android Open Source Project    fSegLength = buffer.readScalar();
1020910916c0f7b951ee55c4b7c6358295b9bca0565The Android Open Source Project    fPerterb = buffer.readScalar();
1030910916c0f7b951ee55c4b7c6358295b9bca0565The Android Open Source Project}
1040910916c0f7b951ee55c4b7c6358295b9bca0565The Android Open Source Project
1050910916c0f7b951ee55c4b7c6358295b9bca0565The Android Open Source Project
106