11cab2921ab279367f8206cdadc9259d12e603548Derek Sollenberger 21cab2921ab279367f8206cdadc9259d12e603548Derek Sollenberger/* 31cab2921ab279367f8206cdadc9259d12e603548Derek Sollenberger * Copyright 2006 The Android Open Source Project 41cab2921ab279367f8206cdadc9259d12e603548Derek Sollenberger * 51cab2921ab279367f8206cdadc9259d12e603548Derek Sollenberger * Use of this source code is governed by a BSD-style license that can be 61cab2921ab279367f8206cdadc9259d12e603548Derek Sollenberger * found in the LICENSE file. 71cab2921ab279367f8206cdadc9259d12e603548Derek Sollenberger */ 81cab2921ab279367f8206cdadc9259d12e603548Derek Sollenberger 90910916c0f7b951ee55c4b7c6358295b9bca0565The Android Open Source Project 100910916c0f7b951ee55c4b7c6358295b9bca0565The Android Open Source Project#include "SkDiscretePathEffect.h" 110910916c0f7b951ee55c4b7c6358295b9bca0565The Android Open Source Project#include "SkBuffer.h" 120910916c0f7b951ee55c4b7c6358295b9bca0565The Android Open Source Project#include "SkPathMeasure.h" 130910916c0f7b951ee55c4b7c6358295b9bca0565The Android Open Source Project#include "SkRandom.h" 140910916c0f7b951ee55c4b7c6358295b9bca0565The Android Open Source Project 1535e2e62b55598210f6999fc2ea26ff8f41446ffeDerek Sollenbergerstatic void Perterb(SkPoint* p, const SkVector& tangent, SkScalar scale) { 160910916c0f7b951ee55c4b7c6358295b9bca0565The Android Open Source Project SkVector normal = tangent; 170910916c0f7b951ee55c4b7c6358295b9bca0565The Android Open Source Project normal.rotateCCW(); 180910916c0f7b951ee55c4b7c6358295b9bca0565The Android Open Source Project normal.setLength(scale); 190910916c0f7b951ee55c4b7c6358295b9bca0565The Android Open Source Project *p += normal; 200910916c0f7b951ee55c4b7c6358295b9bca0565The Android Open Source Project} 210910916c0f7b951ee55c4b7c6358295b9bca0565The Android Open Source Project 220910916c0f7b951ee55c4b7c6358295b9bca0565The Android Open Source Project 230910916c0f7b951ee55c4b7c6358295b9bca0565The Android Open Source ProjectSkDiscretePathEffect::SkDiscretePathEffect(SkScalar segLength, SkScalar deviation) 240910916c0f7b951ee55c4b7c6358295b9bca0565The Android Open Source Project : fSegLength(segLength), fPerterb(deviation) 250910916c0f7b951ee55c4b7c6358295b9bca0565The Android Open Source Project{ 260910916c0f7b951ee55c4b7c6358295b9bca0565The Android Open Source Project} 270910916c0f7b951ee55c4b7c6358295b9bca0565The Android Open Source Project 2835e2e62b55598210f6999fc2ea26ff8f41446ffeDerek Sollenbergerbool SkDiscretePathEffect::filterPath(SkPath* dst, const SkPath& src, 2935e2e62b55598210f6999fc2ea26ff8f41446ffeDerek Sollenberger SkScalar* width) { 300910916c0f7b951ee55c4b7c6358295b9bca0565The Android Open Source Project bool doFill = *width < 0; 310910916c0f7b951ee55c4b7c6358295b9bca0565The Android Open Source Project 320910916c0f7b951ee55c4b7c6358295b9bca0565The Android Open Source Project SkPathMeasure meas(src, doFill); 330910916c0f7b951ee55c4b7c6358295b9bca0565The Android Open Source Project uint32_t seed = SkScalarRound(meas.getLength()); 340910916c0f7b951ee55c4b7c6358295b9bca0565The Android Open Source Project SkRandom rand(seed ^ ((seed << 16) | (seed >> 16))); 350910916c0f7b951ee55c4b7c6358295b9bca0565The Android Open Source Project SkScalar scale = fPerterb; 360910916c0f7b951ee55c4b7c6358295b9bca0565The Android Open Source Project SkPoint p; 370910916c0f7b951ee55c4b7c6358295b9bca0565The Android Open Source Project SkVector v; 380910916c0f7b951ee55c4b7c6358295b9bca0565The Android Open Source Project 390910916c0f7b951ee55c4b7c6358295b9bca0565The Android Open Source Project do { 400910916c0f7b951ee55c4b7c6358295b9bca0565The Android Open Source Project SkScalar length = meas.getLength(); 410910916c0f7b951ee55c4b7c6358295b9bca0565The Android Open Source Project 4235e2e62b55598210f6999fc2ea26ff8f41446ffeDerek Sollenberger if (fSegLength * (2 + doFill) > length) { 430910916c0f7b951ee55c4b7c6358295b9bca0565The Android Open Source Project meas.getSegment(0, length, dst, true); // to short for us to mangle 4435e2e62b55598210f6999fc2ea26ff8f41446ffeDerek Sollenberger } else { 450910916c0f7b951ee55c4b7c6358295b9bca0565The Android Open Source Project int n = SkScalarRound(SkScalarDiv(length, fSegLength)); 460910916c0f7b951ee55c4b7c6358295b9bca0565The Android Open Source Project SkScalar delta = length / n; 470910916c0f7b951ee55c4b7c6358295b9bca0565The Android Open Source Project SkScalar distance = 0; 480910916c0f7b951ee55c4b7c6358295b9bca0565The Android Open Source Project 4935e2e62b55598210f6999fc2ea26ff8f41446ffeDerek Sollenberger if (meas.isClosed()) { 500910916c0f7b951ee55c4b7c6358295b9bca0565The Android Open Source Project n -= 1; 510910916c0f7b951ee55c4b7c6358295b9bca0565The Android Open Source Project distance += delta/2; 520910916c0f7b951ee55c4b7c6358295b9bca0565The Android Open Source Project } 530910916c0f7b951ee55c4b7c6358295b9bca0565The Android Open Source Project meas.getPosTan(distance, &p, &v); 540910916c0f7b951ee55c4b7c6358295b9bca0565The Android Open Source Project Perterb(&p, v, SkScalarMul(rand.nextSScalar1(), scale)); 550910916c0f7b951ee55c4b7c6358295b9bca0565The Android Open Source Project dst->moveTo(p); 5635e2e62b55598210f6999fc2ea26ff8f41446ffeDerek Sollenberger while (--n >= 0) { 570910916c0f7b951ee55c4b7c6358295b9bca0565The Android Open Source Project distance += delta; 580910916c0f7b951ee55c4b7c6358295b9bca0565The Android Open Source Project meas.getPosTan(distance, &p, &v); 590910916c0f7b951ee55c4b7c6358295b9bca0565The Android Open Source Project Perterb(&p, v, SkScalarMul(rand.nextSScalar1(), scale)); 600910916c0f7b951ee55c4b7c6358295b9bca0565The Android Open Source Project dst->lineTo(p); 610910916c0f7b951ee55c4b7c6358295b9bca0565The Android Open Source Project } 6235e2e62b55598210f6999fc2ea26ff8f41446ffeDerek Sollenberger if (meas.isClosed()) { 630910916c0f7b951ee55c4b7c6358295b9bca0565The Android Open Source Project dst->close(); 6435e2e62b55598210f6999fc2ea26ff8f41446ffeDerek Sollenberger } 650910916c0f7b951ee55c4b7c6358295b9bca0565The Android Open Source Project } 660910916c0f7b951ee55c4b7c6358295b9bca0565The Android Open Source Project } while (meas.nextContour()); 670910916c0f7b951ee55c4b7c6358295b9bca0565The Android Open Source Project return true; 680910916c0f7b951ee55c4b7c6358295b9bca0565The Android Open Source Project} 690910916c0f7b951ee55c4b7c6358295b9bca0565The Android Open Source Project 7035e2e62b55598210f6999fc2ea26ff8f41446ffeDerek SollenbergerSkFlattenable::Factory SkDiscretePathEffect::getFactory() { 710910916c0f7b951ee55c4b7c6358295b9bca0565The Android Open Source Project return CreateProc; 720910916c0f7b951ee55c4b7c6358295b9bca0565The Android Open Source Project} 730910916c0f7b951ee55c4b7c6358295b9bca0565The Android Open Source Project 7435e2e62b55598210f6999fc2ea26ff8f41446ffeDerek SollenbergerSkFlattenable* SkDiscretePathEffect::CreateProc(SkFlattenableReadBuffer& buffer) { 750910916c0f7b951ee55c4b7c6358295b9bca0565The Android Open Source Project return SkNEW_ARGS(SkDiscretePathEffect, (buffer)); 760910916c0f7b951ee55c4b7c6358295b9bca0565The Android Open Source Project} 770910916c0f7b951ee55c4b7c6358295b9bca0565The Android Open Source Project 7835e2e62b55598210f6999fc2ea26ff8f41446ffeDerek Sollenbergervoid SkDiscretePathEffect::flatten(SkFlattenableWriteBuffer& buffer) { 790910916c0f7b951ee55c4b7c6358295b9bca0565The Android Open Source Project buffer.writeScalar(fSegLength); 800910916c0f7b951ee55c4b7c6358295b9bca0565The Android Open Source Project buffer.writeScalar(fPerterb); 810910916c0f7b951ee55c4b7c6358295b9bca0565The Android Open Source Project} 820910916c0f7b951ee55c4b7c6358295b9bca0565The Android Open Source Project 8335e2e62b55598210f6999fc2ea26ff8f41446ffeDerek SollenbergerSkDiscretePathEffect::SkDiscretePathEffect(SkFlattenableReadBuffer& buffer) { 840910916c0f7b951ee55c4b7c6358295b9bca0565The Android Open Source Project fSegLength = buffer.readScalar(); 850910916c0f7b951ee55c4b7c6358295b9bca0565The Android Open Source Project fPerterb = buffer.readScalar(); 860910916c0f7b951ee55c4b7c6358295b9bca0565The Android Open Source Project} 870910916c0f7b951ee55c4b7c6358295b9bca0565The Android Open Source Project 881cab2921ab279367f8206cdadc9259d12e603548Derek Sollenberger/////////////////////////////////////////////////////////////////////////////// 891cab2921ab279367f8206cdadc9259d12e603548Derek Sollenberger 901cab2921ab279367f8206cdadc9259d12e603548Derek SollenbergerSK_DEFINE_FLATTENABLE_REGISTRAR(SkDiscretePathEffect) 911cab2921ab279367f8206cdadc9259d12e603548Derek Sollenberger 92