1685cfc0ee13d7c355ae2f4f3d225ad45e945763fepoger@google.com 2685cfc0ee13d7c355ae2f4f3d225ad45e945763fepoger@google.com/* 3685cfc0ee13d7c355ae2f4f3d225ad45e945763fepoger@google.com * Copyright 2006 The Android Open Source Project 4685cfc0ee13d7c355ae2f4f3d225ad45e945763fepoger@google.com * 5685cfc0ee13d7c355ae2f4f3d225ad45e945763fepoger@google.com * Use of this source code is governed by a BSD-style license that can be 6685cfc0ee13d7c355ae2f4f3d225ad45e945763fepoger@google.com * found in the LICENSE file. 7685cfc0ee13d7c355ae2f4f3d225ad45e945763fepoger@google.com */ 8685cfc0ee13d7c355ae2f4f3d225ad45e945763fepoger@google.com 9bcd4d5ab12df062500a4df90ec90d0f2d764931reed@android.com 10bcd4d5ab12df062500a4df90ec90d0f2d764931reed@android.com#include "SkDiscretePathEffect.h" 119ce78f26f529fd3e10a3eb4f044bc3f0037ead56djsollen@google.com#include "SkFlattenableBuffers.h" 12bcd4d5ab12df062500a4df90ec90d0f2d764931reed@android.com#include "SkPathMeasure.h" 13bcd4d5ab12df062500a4df90ec90d0f2d764931reed@android.com#include "SkRandom.h" 14bcd4d5ab12df062500a4df90ec90d0f2d764931reed@android.com 156c8459aa6c4bbc6e0638edab09f035924f31eda3mike@reedtribe.orgstatic void Perterb(SkPoint* p, const SkVector& tangent, SkScalar scale) { 16bcd4d5ab12df062500a4df90ec90d0f2d764931reed@android.com SkVector normal = tangent; 17bcd4d5ab12df062500a4df90ec90d0f2d764931reed@android.com normal.rotateCCW(); 18bcd4d5ab12df062500a4df90ec90d0f2d764931reed@android.com normal.setLength(scale); 19bcd4d5ab12df062500a4df90ec90d0f2d764931reed@android.com *p += normal; 20bcd4d5ab12df062500a4df90ec90d0f2d764931reed@android.com} 21bcd4d5ab12df062500a4df90ec90d0f2d764931reed@android.com 22bcd4d5ab12df062500a4df90ec90d0f2d764931reed@android.com 23bcd4d5ab12df062500a4df90ec90d0f2d764931reed@android.comSkDiscretePathEffect::SkDiscretePathEffect(SkScalar segLength, SkScalar deviation) 24bcd4d5ab12df062500a4df90ec90d0f2d764931reed@android.com : fSegLength(segLength), fPerterb(deviation) 25bcd4d5ab12df062500a4df90ec90d0f2d764931reed@android.com{ 26bcd4d5ab12df062500a4df90ec90d0f2d764931reed@android.com} 27bcd4d5ab12df062500a4df90ec90d0f2d764931reed@android.com 286c8459aa6c4bbc6e0638edab09f035924f31eda3mike@reedtribe.orgbool SkDiscretePathEffect::filterPath(SkPath* dst, const SkPath& src, 29bb77acf17c4eb4f58b6bfbe48d750d018485ecf2reed@google.com SkStrokeRec* rec, const SkRect*) const { 30d49b87f7307690e47c5cb093ff9d7cce4f009e87reed@google.com bool doFill = rec->isFillStyle(); 31bcd4d5ab12df062500a4df90ec90d0f2d764931reed@android.com 32bcd4d5ab12df062500a4df90ec90d0f2d764931reed@android.com SkPathMeasure meas(src, doFill); 33bcd4d5ab12df062500a4df90ec90d0f2d764931reed@android.com uint32_t seed = SkScalarRound(meas.getLength()); 34680372190ee596c7485dcf2974c824fcf6a355dccommit-bot@chromium.org SkLCGRandom rand(seed ^ ((seed << 16) | (seed >> 16))); 35bcd4d5ab12df062500a4df90ec90d0f2d764931reed@android.com SkScalar scale = fPerterb; 36bcd4d5ab12df062500a4df90ec90d0f2d764931reed@android.com SkPoint p; 37bcd4d5ab12df062500a4df90ec90d0f2d764931reed@android.com SkVector v; 38bcd4d5ab12df062500a4df90ec90d0f2d764931reed@android.com 39bcd4d5ab12df062500a4df90ec90d0f2d764931reed@android.com do { 40bcd4d5ab12df062500a4df90ec90d0f2d764931reed@android.com SkScalar length = meas.getLength(); 41bcd4d5ab12df062500a4df90ec90d0f2d764931reed@android.com 426c8459aa6c4bbc6e0638edab09f035924f31eda3mike@reedtribe.org if (fSegLength * (2 + doFill) > length) { 43bcd4d5ab12df062500a4df90ec90d0f2d764931reed@android.com meas.getSegment(0, length, dst, true); // to short for us to mangle 446c8459aa6c4bbc6e0638edab09f035924f31eda3mike@reedtribe.org } else { 45bcd4d5ab12df062500a4df90ec90d0f2d764931reed@android.com int n = SkScalarRound(SkScalarDiv(length, fSegLength)); 46bcd4d5ab12df062500a4df90ec90d0f2d764931reed@android.com SkScalar delta = length / n; 47bcd4d5ab12df062500a4df90ec90d0f2d764931reed@android.com SkScalar distance = 0; 48bcd4d5ab12df062500a4df90ec90d0f2d764931reed@android.com 496c8459aa6c4bbc6e0638edab09f035924f31eda3mike@reedtribe.org if (meas.isClosed()) { 50bcd4d5ab12df062500a4df90ec90d0f2d764931reed@android.com n -= 1; 51bcd4d5ab12df062500a4df90ec90d0f2d764931reed@android.com distance += delta/2; 52bcd4d5ab12df062500a4df90ec90d0f2d764931reed@android.com } 53935e9f4fafdfc64130e6be9ea2bb30e3bafd852armistry@google.com 54cdf1e2c68ac50376dd9ae6f335632d005182b4f7reed@google.com if (meas.getPosTan(distance, &p, &v)) { 55cdf1e2c68ac50376dd9ae6f335632d005182b4f7reed@google.com Perterb(&p, v, SkScalarMul(rand.nextSScalar1(), scale)); 56cdf1e2c68ac50376dd9ae6f335632d005182b4f7reed@google.com dst->moveTo(p); 57cdf1e2c68ac50376dd9ae6f335632d005182b4f7reed@google.com } 586c8459aa6c4bbc6e0638edab09f035924f31eda3mike@reedtribe.org while (--n >= 0) { 59bcd4d5ab12df062500a4df90ec90d0f2d764931reed@android.com distance += delta; 60cdf1e2c68ac50376dd9ae6f335632d005182b4f7reed@google.com if (meas.getPosTan(distance, &p, &v)) { 61cdf1e2c68ac50376dd9ae6f335632d005182b4f7reed@google.com Perterb(&p, v, SkScalarMul(rand.nextSScalar1(), scale)); 62cdf1e2c68ac50376dd9ae6f335632d005182b4f7reed@google.com dst->lineTo(p); 63cdf1e2c68ac50376dd9ae6f335632d005182b4f7reed@google.com } 64bcd4d5ab12df062500a4df90ec90d0f2d764931reed@android.com } 656c8459aa6c4bbc6e0638edab09f035924f31eda3mike@reedtribe.org if (meas.isClosed()) { 66bcd4d5ab12df062500a4df90ec90d0f2d764931reed@android.com dst->close(); 676c8459aa6c4bbc6e0638edab09f035924f31eda3mike@reedtribe.org } 68bcd4d5ab12df062500a4df90ec90d0f2d764931reed@android.com } 69bcd4d5ab12df062500a4df90ec90d0f2d764931reed@android.com } while (meas.nextContour()); 70bcd4d5ab12df062500a4df90ec90d0f2d764931reed@android.com return true; 71bcd4d5ab12df062500a4df90ec90d0f2d764931reed@android.com} 72bcd4d5ab12df062500a4df90ec90d0f2d764931reed@android.com 73cd2e444e946f5cfec4723f5bc46e9487d82e8e54djsollen@google.comvoid SkDiscretePathEffect::flatten(SkFlattenableWriteBuffer& buffer) const { 74cd2e444e946f5cfec4723f5bc46e9487d82e8e54djsollen@google.com this->INHERITED::flatten(buffer); 75bcd4d5ab12df062500a4df90ec90d0f2d764931reed@android.com buffer.writeScalar(fSegLength); 76bcd4d5ab12df062500a4df90ec90d0f2d764931reed@android.com buffer.writeScalar(fPerterb); 77bcd4d5ab12df062500a4df90ec90d0f2d764931reed@android.com} 78bcd4d5ab12df062500a4df90ec90d0f2d764931reed@android.com 796c8459aa6c4bbc6e0638edab09f035924f31eda3mike@reedtribe.orgSkDiscretePathEffect::SkDiscretePathEffect(SkFlattenableReadBuffer& buffer) { 80bcd4d5ab12df062500a4df90ec90d0f2d764931reed@android.com fSegLength = buffer.readScalar(); 81bcd4d5ab12df062500a4df90ec90d0f2d764931reed@android.com fPerterb = buffer.readScalar(); 82bcd4d5ab12df062500a4df90ec90d0f2d764931reed@android.com} 83