1ec3ed6a5ebf6f2c406d7bcf94b6bc34fcaeb976eepoger@google.com/* 2ec3ed6a5ebf6f2c406d7bcf94b6bc34fcaeb976eepoger@google.com * Copyright 2006 The Android Open Source Project 3ec3ed6a5ebf6f2c406d7bcf94b6bc34fcaeb976eepoger@google.com * 4ec3ed6a5ebf6f2c406d7bcf94b6bc34fcaeb976eepoger@google.com * Use of this source code is governed by a BSD-style license that can be 5ec3ed6a5ebf6f2c406d7bcf94b6bc34fcaeb976eepoger@google.com * found in the LICENSE file. 6ec3ed6a5ebf6f2c406d7bcf94b6bc34fcaeb976eepoger@google.com */ 7ec3ed6a5ebf6f2c406d7bcf94b6bc34fcaeb976eepoger@google.com 88a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com#include "SkDashPathEffect.h" 9a22ea1882391cc5c84136060636d5c952c1f34b3egdaniel 10a22ea1882391cc5c84136060636d5c952c1f34b3egdaniel#include "SkDashPathPriv.h" 118b0e8ac5f582de80356019406e2975079bf0829dcommit-bot@chromium.org#include "SkReadBuffer.h" 128b0e8ac5f582de80356019406e2975079bf0829dcommit-bot@chromium.org#include "SkWriteBuffer.h" 138a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com 14aec143824c9be4e4af6e2cb7cce3d2d2268c0b15commit-bot@chromium.orgSkDashPathEffect::SkDashPathEffect(const SkScalar intervals[], int count, 15aec143824c9be4e4af6e2cb7cce3d2d2268c0b15commit-bot@chromium.org SkScalar phase) { 16aec143824c9be4e4af6e2cb7cce3d2d2268c0b15commit-bot@chromium.org SkASSERT(intervals); 17aec143824c9be4e4af6e2cb7cce3d2d2268c0b15commit-bot@chromium.org SkASSERT(count > 1 && SkAlign2(count) == count); 18aec143824c9be4e4af6e2cb7cce3d2d2268c0b15commit-bot@chromium.org 19aec143824c9be4e4af6e2cb7cce3d2d2268c0b15commit-bot@chromium.org fIntervals = (SkScalar*)sk_malloc_throw(sizeof(SkScalar) * count); 20aec143824c9be4e4af6e2cb7cce3d2d2268c0b15commit-bot@chromium.org fCount = count; 21aec143824c9be4e4af6e2cb7cce3d2d2268c0b15commit-bot@chromium.org for (int i = 0; i < count; i++) { 22aec143824c9be4e4af6e2cb7cce3d2d2268c0b15commit-bot@chromium.org SkASSERT(intervals[i] >= 0); 23aec143824c9be4e4af6e2cb7cce3d2d2268c0b15commit-bot@chromium.org fIntervals[i] = intervals[i]; 24aec143824c9be4e4af6e2cb7cce3d2d2268c0b15commit-bot@chromium.org } 25aec143824c9be4e4af6e2cb7cce3d2d2268c0b15commit-bot@chromium.org 26a22ea1882391cc5c84136060636d5c952c1f34b3egdaniel // set the internal data members 27a22ea1882391cc5c84136060636d5c952c1f34b3egdaniel SkDashPath::CalcDashParameters(phase, fIntervals, fCount, &fInitialDashLength, 28a22ea1882391cc5c84136060636d5c952c1f34b3egdaniel &fInitialDashIndex, &fIntervalLength, &fPhase); 29aec143824c9be4e4af6e2cb7cce3d2d2268c0b15commit-bot@chromium.org} 30aec143824c9be4e4af6e2cb7cce3d2d2268c0b15commit-bot@chromium.org 313334c3a1fa05b5ee0cab0f2f1ec7b19939737337mike@reedtribe.orgSkDashPathEffect::~SkDashPathEffect() { 328a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com sk_free(fIntervals); 338a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com} 348a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com 353334c3a1fa05b5ee0cab0f2f1ec7b19939737337mike@reedtribe.orgbool SkDashPathEffect::filterPath(SkPath* dst, const SkPath& src, 364bbdeac58cc928dc66296bde3bd06e78070d96b7reed@google.com SkStrokeRec* rec, const SkRect* cullRect) const { 37a22ea1882391cc5c84136060636d5c952c1f34b3egdaniel return SkDashPath::FilterDashPath(dst, src, rec, cullRect, fIntervals, fCount, 38a22ea1882391cc5c84136060636d5c952c1f34b3egdaniel fInitialDashLength, fInitialDashIndex, fIntervalLength); 39629ab540667422d3edcb97c51e9628b7051e1ba4robertphillips@google.com} 40629ab540667422d3edcb97c51e9628b7051e1ba4robertphillips@google.com 41629ab540667422d3edcb97c51e9628b7051e1ba4robertphillips@google.com// Currently asPoints is more restrictive then it needs to be. In the future 42629ab540667422d3edcb97c51e9628b7051e1ba4robertphillips@google.com// we need to: 43629ab540667422d3edcb97c51e9628b7051e1ba4robertphillips@google.com// allow kRound_Cap capping (could allow rotations in the matrix with this) 446d87557278052c131957e5d6e093d3a675162d22robertphillips@google.com// allow paths to be returned 45629ab540667422d3edcb97c51e9628b7051e1ba4robertphillips@google.combool SkDashPathEffect::asPoints(PointData* results, 46629ab540667422d3edcb97c51e9628b7051e1ba4robertphillips@google.com const SkPath& src, 47629ab540667422d3edcb97c51e9628b7051e1ba4robertphillips@google.com const SkStrokeRec& rec, 484bbdeac58cc928dc66296bde3bd06e78070d96b7reed@google.com const SkMatrix& matrix, 494bbdeac58cc928dc66296bde3bd06e78070d96b7reed@google.com const SkRect* cullRect) const { 506d87557278052c131957e5d6e093d3a675162d22robertphillips@google.com // width < 0 -> fill && width == 0 -> hairline so requiring width > 0 rules both out 516d87557278052c131957e5d6e093d3a675162d22robertphillips@google.com if (fInitialDashLength < 0 || 0 >= rec.getWidth()) { 52629ab540667422d3edcb97c51e9628b7051e1ba4robertphillips@google.com return false; 53629ab540667422d3edcb97c51e9628b7051e1ba4robertphillips@google.com } 54629ab540667422d3edcb97c51e9628b7051e1ba4robertphillips@google.com 556d87557278052c131957e5d6e093d3a675162d22robertphillips@google.com // TODO: this next test could be eased up. We could allow any number of 566d87557278052c131957e5d6e093d3a675162d22robertphillips@google.com // intervals as long as all the ons match and all the offs match. 576d87557278052c131957e5d6e093d3a675162d22robertphillips@google.com // Additionally, they do not necessarily need to be integers. 586d87557278052c131957e5d6e093d3a675162d22robertphillips@google.com // We cannot allow arbitrary intervals since we want the returned points 596d87557278052c131957e5d6e093d3a675162d22robertphillips@google.com // to be uniformly sized. 607a03d86a3d9adcb13432fbd82039725149487c97skia.committer@gmail.com if (fCount != 2 || 616d87557278052c131957e5d6e093d3a675162d22robertphillips@google.com !SkScalarNearlyEqual(fIntervals[0], fIntervals[1]) || 626d87557278052c131957e5d6e093d3a675162d22robertphillips@google.com !SkScalarIsInt(fIntervals[0]) || 636d87557278052c131957e5d6e093d3a675162d22robertphillips@google.com !SkScalarIsInt(fIntervals[1])) { 64629ab540667422d3edcb97c51e9628b7051e1ba4robertphillips@google.com return false; 65629ab540667422d3edcb97c51e9628b7051e1ba4robertphillips@google.com } 66629ab540667422d3edcb97c51e9628b7051e1ba4robertphillips@google.com 67629ab540667422d3edcb97c51e9628b7051e1ba4robertphillips@google.com SkPoint pts[2]; 68629ab540667422d3edcb97c51e9628b7051e1ba4robertphillips@google.com 696d87557278052c131957e5d6e093d3a675162d22robertphillips@google.com if (!src.isLine(pts)) { 70629ab540667422d3edcb97c51e9628b7051e1ba4robertphillips@google.com return false; 71629ab540667422d3edcb97c51e9628b7051e1ba4robertphillips@google.com } 72629ab540667422d3edcb97c51e9628b7051e1ba4robertphillips@google.com 736d87557278052c131957e5d6e093d3a675162d22robertphillips@google.com // TODO: this test could be eased up to allow circles 74629ab540667422d3edcb97c51e9628b7051e1ba4robertphillips@google.com if (SkPaint::kButt_Cap != rec.getCap()) { 75629ab540667422d3edcb97c51e9628b7051e1ba4robertphillips@google.com return false; 76629ab540667422d3edcb97c51e9628b7051e1ba4robertphillips@google.com } 77629ab540667422d3edcb97c51e9628b7051e1ba4robertphillips@google.com 786d87557278052c131957e5d6e093d3a675162d22robertphillips@google.com // TODO: this test could be eased up for circles. Rotations could be allowed. 79629ab540667422d3edcb97c51e9628b7051e1ba4robertphillips@google.com if (!matrix.rectStaysRect()) { 80629ab540667422d3edcb97c51e9628b7051e1ba4robertphillips@google.com return false; 81629ab540667422d3edcb97c51e9628b7051e1ba4robertphillips@google.com } 82629ab540667422d3edcb97c51e9628b7051e1ba4robertphillips@google.com 836d87557278052c131957e5d6e093d3a675162d22robertphillips@google.com SkScalar length = SkPoint::Distance(pts[1], pts[0]); 846d87557278052c131957e5d6e093d3a675162d22robertphillips@google.com 856d87557278052c131957e5d6e093d3a675162d22robertphillips@google.com SkVector tangent = pts[1] - pts[0]; 866d87557278052c131957e5d6e093d3a675162d22robertphillips@google.com if (tangent.isZero()) { 876d87557278052c131957e5d6e093d3a675162d22robertphillips@google.com return false; 886d87557278052c131957e5d6e093d3a675162d22robertphillips@google.com } 89629ab540667422d3edcb97c51e9628b7051e1ba4robertphillips@google.com 906d87557278052c131957e5d6e093d3a675162d22robertphillips@google.com tangent.scale(SkScalarInvert(length)); 916d87557278052c131957e5d6e093d3a675162d22robertphillips@google.com 926d87557278052c131957e5d6e093d3a675162d22robertphillips@google.com // TODO: make this test for horizontal & vertical lines more robust 936d87557278052c131957e5d6e093d3a675162d22robertphillips@google.com bool isXAxis = true; 946d87557278052c131957e5d6e093d3a675162d22robertphillips@google.com if (SK_Scalar1 == tangent.fX || -SK_Scalar1 == tangent.fX) { 956d87557278052c131957e5d6e093d3a675162d22robertphillips@google.com results->fSize.set(SkScalarHalf(fIntervals[0]), SkScalarHalf(rec.getWidth())); 966d87557278052c131957e5d6e093d3a675162d22robertphillips@google.com } else if (SK_Scalar1 == tangent.fY || -SK_Scalar1 == tangent.fY) { 976d87557278052c131957e5d6e093d3a675162d22robertphillips@google.com results->fSize.set(SkScalarHalf(rec.getWidth()), SkScalarHalf(fIntervals[0])); 986d87557278052c131957e5d6e093d3a675162d22robertphillips@google.com isXAxis = false; 996d87557278052c131957e5d6e093d3a675162d22robertphillips@google.com } else if (SkPaint::kRound_Cap != rec.getCap()) { 1006d87557278052c131957e5d6e093d3a675162d22robertphillips@google.com // Angled lines don't have axis-aligned boxes. 101629ab540667422d3edcb97c51e9628b7051e1ba4robertphillips@google.com return false; 102629ab540667422d3edcb97c51e9628b7051e1ba4robertphillips@google.com } 103629ab540667422d3edcb97c51e9628b7051e1ba4robertphillips@google.com 104629ab540667422d3edcb97c51e9628b7051e1ba4robertphillips@google.com if (NULL != results) { 1057a03d86a3d9adcb13432fbd82039725149487c97skia.committer@gmail.com results->fFlags = 0; 1065c4d5582c9d47ea47c7699fe69b9f95d0117dbd5robertphillips@google.com SkScalar clampedInitialDashLength = SkMinScalar(length, fInitialDashLength); 107629ab540667422d3edcb97c51e9628b7051e1ba4robertphillips@google.com 1086d87557278052c131957e5d6e093d3a675162d22robertphillips@google.com if (SkPaint::kRound_Cap == rec.getCap()) { 1096d87557278052c131957e5d6e093d3a675162d22robertphillips@google.com results->fFlags |= PointData::kCircles_PointFlag; 110629ab540667422d3edcb97c51e9628b7051e1ba4robertphillips@google.com } 111629ab540667422d3edcb97c51e9628b7051e1ba4robertphillips@google.com 1126d87557278052c131957e5d6e093d3a675162d22robertphillips@google.com results->fNumPoints = 0; 1136d87557278052c131957e5d6e093d3a675162d22robertphillips@google.com SkScalar len2 = length; 1145c4d5582c9d47ea47c7699fe69b9f95d0117dbd5robertphillips@google.com if (clampedInitialDashLength > 0 || 0 == fInitialDashIndex) { 1155c4d5582c9d47ea47c7699fe69b9f95d0117dbd5robertphillips@google.com SkASSERT(len2 >= clampedInitialDashLength); 1166d87557278052c131957e5d6e093d3a675162d22robertphillips@google.com if (0 == fInitialDashIndex) { 1175c4d5582c9d47ea47c7699fe69b9f95d0117dbd5robertphillips@google.com if (clampedInitialDashLength > 0) { 1185c4d5582c9d47ea47c7699fe69b9f95d0117dbd5robertphillips@google.com if (clampedInitialDashLength >= fIntervals[0]) { 1196d87557278052c131957e5d6e093d3a675162d22robertphillips@google.com ++results->fNumPoints; // partial first dash 1206d87557278052c131957e5d6e093d3a675162d22robertphillips@google.com } 1215c4d5582c9d47ea47c7699fe69b9f95d0117dbd5robertphillips@google.com len2 -= clampedInitialDashLength; 1226d87557278052c131957e5d6e093d3a675162d22robertphillips@google.com } 1236d87557278052c131957e5d6e093d3a675162d22robertphillips@google.com len2 -= fIntervals[1]; // also skip first space 1246d87557278052c131957e5d6e093d3a675162d22robertphillips@google.com if (len2 < 0) { 1256d87557278052c131957e5d6e093d3a675162d22robertphillips@google.com len2 = 0; 1266d87557278052c131957e5d6e093d3a675162d22robertphillips@google.com } 1276d87557278052c131957e5d6e093d3a675162d22robertphillips@google.com } else { 1285c4d5582c9d47ea47c7699fe69b9f95d0117dbd5robertphillips@google.com len2 -= clampedInitialDashLength; // skip initial partial empty 1296d87557278052c131957e5d6e093d3a675162d22robertphillips@google.com } 1306d87557278052c131957e5d6e093d3a675162d22robertphillips@google.com } 1316d87557278052c131957e5d6e093d3a675162d22robertphillips@google.com int numMidPoints = SkScalarFloorToInt(SkScalarDiv(len2, fIntervalLength)); 1326d87557278052c131957e5d6e093d3a675162d22robertphillips@google.com results->fNumPoints += numMidPoints; 1336d87557278052c131957e5d6e093d3a675162d22robertphillips@google.com len2 -= numMidPoints * fIntervalLength; 1346d87557278052c131957e5d6e093d3a675162d22robertphillips@google.com bool partialLast = false; 1356d87557278052c131957e5d6e093d3a675162d22robertphillips@google.com if (len2 > 0) { 1366d87557278052c131957e5d6e093d3a675162d22robertphillips@google.com if (len2 < fIntervals[0]) { 1377a03d86a3d9adcb13432fbd82039725149487c97skia.committer@gmail.com partialLast = true; 1386d87557278052c131957e5d6e093d3a675162d22robertphillips@google.com } else { 1396d87557278052c131957e5d6e093d3a675162d22robertphillips@google.com ++numMidPoints; 1406d87557278052c131957e5d6e093d3a675162d22robertphillips@google.com ++results->fNumPoints; 1416d87557278052c131957e5d6e093d3a675162d22robertphillips@google.com } 1426d87557278052c131957e5d6e093d3a675162d22robertphillips@google.com } 143629ab540667422d3edcb97c51e9628b7051e1ba4robertphillips@google.com 144935ad026826fb7d31d562ff7326b84ec3a827456robertphillips@google.com results->fPoints = new SkPoint[results->fNumPoints]; 145629ab540667422d3edcb97c51e9628b7051e1ba4robertphillips@google.com 1466d87557278052c131957e5d6e093d3a675162d22robertphillips@google.com SkScalar distance = 0; 1476d87557278052c131957e5d6e093d3a675162d22robertphillips@google.com int curPt = 0; 1486d87557278052c131957e5d6e093d3a675162d22robertphillips@google.com 1495c4d5582c9d47ea47c7699fe69b9f95d0117dbd5robertphillips@google.com if (clampedInitialDashLength > 0 || 0 == fInitialDashIndex) { 1505c4d5582c9d47ea47c7699fe69b9f95d0117dbd5robertphillips@google.com SkASSERT(clampedInitialDashLength <= length); 1516d87557278052c131957e5d6e093d3a675162d22robertphillips@google.com 1526d87557278052c131957e5d6e093d3a675162d22robertphillips@google.com if (0 == fInitialDashIndex) { 1535c4d5582c9d47ea47c7699fe69b9f95d0117dbd5robertphillips@google.com if (clampedInitialDashLength > 0) { 1546d87557278052c131957e5d6e093d3a675162d22robertphillips@google.com // partial first block 1556d87557278052c131957e5d6e093d3a675162d22robertphillips@google.com SkASSERT(SkPaint::kRound_Cap != rec.getCap()); // can't handle partial circles 1565c4d5582c9d47ea47c7699fe69b9f95d0117dbd5robertphillips@google.com SkScalar x = pts[0].fX + SkScalarMul(tangent.fX, SkScalarHalf(clampedInitialDashLength)); 1575c4d5582c9d47ea47c7699fe69b9f95d0117dbd5robertphillips@google.com SkScalar y = pts[0].fY + SkScalarMul(tangent.fY, SkScalarHalf(clampedInitialDashLength)); 1586d87557278052c131957e5d6e093d3a675162d22robertphillips@google.com SkScalar halfWidth, halfHeight; 1596d87557278052c131957e5d6e093d3a675162d22robertphillips@google.com if (isXAxis) { 1605c4d5582c9d47ea47c7699fe69b9f95d0117dbd5robertphillips@google.com halfWidth = SkScalarHalf(clampedInitialDashLength); 1616d87557278052c131957e5d6e093d3a675162d22robertphillips@google.com halfHeight = SkScalarHalf(rec.getWidth()); 1626d87557278052c131957e5d6e093d3a675162d22robertphillips@google.com } else { 1636d87557278052c131957e5d6e093d3a675162d22robertphillips@google.com halfWidth = SkScalarHalf(rec.getWidth()); 1645c4d5582c9d47ea47c7699fe69b9f95d0117dbd5robertphillips@google.com halfHeight = SkScalarHalf(clampedInitialDashLength); 1656d87557278052c131957e5d6e093d3a675162d22robertphillips@google.com } 1665c4d5582c9d47ea47c7699fe69b9f95d0117dbd5robertphillips@google.com if (clampedInitialDashLength < fIntervals[0]) { 1676d87557278052c131957e5d6e093d3a675162d22robertphillips@google.com // This one will not be like the others 1686d87557278052c131957e5d6e093d3a675162d22robertphillips@google.com results->fFirst.addRect(x - halfWidth, y - halfHeight, 1696d87557278052c131957e5d6e093d3a675162d22robertphillips@google.com x + halfWidth, y + halfHeight); 1706d87557278052c131957e5d6e093d3a675162d22robertphillips@google.com } else { 1716d87557278052c131957e5d6e093d3a675162d22robertphillips@google.com SkASSERT(curPt < results->fNumPoints); 1726d87557278052c131957e5d6e093d3a675162d22robertphillips@google.com results->fPoints[curPt].set(x, y); 1736d87557278052c131957e5d6e093d3a675162d22robertphillips@google.com ++curPt; 1746d87557278052c131957e5d6e093d3a675162d22robertphillips@google.com } 1756d87557278052c131957e5d6e093d3a675162d22robertphillips@google.com 1765c4d5582c9d47ea47c7699fe69b9f95d0117dbd5robertphillips@google.com distance += clampedInitialDashLength; 1776d87557278052c131957e5d6e093d3a675162d22robertphillips@google.com } 178629ab540667422d3edcb97c51e9628b7051e1ba4robertphillips@google.com 1796d87557278052c131957e5d6e093d3a675162d22robertphillips@google.com distance += fIntervals[1]; // skip over the next blank block too 1806d87557278052c131957e5d6e093d3a675162d22robertphillips@google.com } else { 1815c4d5582c9d47ea47c7699fe69b9f95d0117dbd5robertphillips@google.com distance += clampedInitialDashLength; 1826d87557278052c131957e5d6e093d3a675162d22robertphillips@google.com } 1836d87557278052c131957e5d6e093d3a675162d22robertphillips@google.com } 1846d87557278052c131957e5d6e093d3a675162d22robertphillips@google.com 1856d87557278052c131957e5d6e093d3a675162d22robertphillips@google.com if (0 != numMidPoints) { 1866d87557278052c131957e5d6e093d3a675162d22robertphillips@google.com distance += SkScalarHalf(fIntervals[0]); 187629ab540667422d3edcb97c51e9628b7051e1ba4robertphillips@google.com 1886d87557278052c131957e5d6e093d3a675162d22robertphillips@google.com for (int i = 0; i < numMidPoints; ++i) { 1896d87557278052c131957e5d6e093d3a675162d22robertphillips@google.com SkScalar x = pts[0].fX + SkScalarMul(tangent.fX, distance); 1906d87557278052c131957e5d6e093d3a675162d22robertphillips@google.com SkScalar y = pts[0].fY + SkScalarMul(tangent.fY, distance); 1916d87557278052c131957e5d6e093d3a675162d22robertphillips@google.com 1926d87557278052c131957e5d6e093d3a675162d22robertphillips@google.com SkASSERT(curPt < results->fNumPoints); 1936d87557278052c131957e5d6e093d3a675162d22robertphillips@google.com results->fPoints[curPt].set(x, y); 1946d87557278052c131957e5d6e093d3a675162d22robertphillips@google.com ++curPt; 1956d87557278052c131957e5d6e093d3a675162d22robertphillips@google.com 1966d87557278052c131957e5d6e093d3a675162d22robertphillips@google.com distance += fIntervalLength; 197629ab540667422d3edcb97c51e9628b7051e1ba4robertphillips@google.com } 198629ab540667422d3edcb97c51e9628b7051e1ba4robertphillips@google.com 1996d87557278052c131957e5d6e093d3a675162d22robertphillips@google.com distance -= SkScalarHalf(fIntervals[0]); 2006d87557278052c131957e5d6e093d3a675162d22robertphillips@google.com } 2016d87557278052c131957e5d6e093d3a675162d22robertphillips@google.com 2026d87557278052c131957e5d6e093d3a675162d22robertphillips@google.com if (partialLast) { 2036d87557278052c131957e5d6e093d3a675162d22robertphillips@google.com // partial final block 2046d87557278052c131957e5d6e093d3a675162d22robertphillips@google.com SkASSERT(SkPaint::kRound_Cap != rec.getCap()); // can't handle partial circles 2056d87557278052c131957e5d6e093d3a675162d22robertphillips@google.com SkScalar temp = length - distance; 2066d87557278052c131957e5d6e093d3a675162d22robertphillips@google.com SkASSERT(temp < fIntervals[0]); 2076d87557278052c131957e5d6e093d3a675162d22robertphillips@google.com SkScalar x = pts[0].fX + SkScalarMul(tangent.fX, distance + SkScalarHalf(temp)); 2086d87557278052c131957e5d6e093d3a675162d22robertphillips@google.com SkScalar y = pts[0].fY + SkScalarMul(tangent.fY, distance + SkScalarHalf(temp)); 2096d87557278052c131957e5d6e093d3a675162d22robertphillips@google.com SkScalar halfWidth, halfHeight; 2106d87557278052c131957e5d6e093d3a675162d22robertphillips@google.com if (isXAxis) { 2116d87557278052c131957e5d6e093d3a675162d22robertphillips@google.com halfWidth = SkScalarHalf(temp); 2126d87557278052c131957e5d6e093d3a675162d22robertphillips@google.com halfHeight = SkScalarHalf(rec.getWidth()); 2136d87557278052c131957e5d6e093d3a675162d22robertphillips@google.com } else { 2146d87557278052c131957e5d6e093d3a675162d22robertphillips@google.com halfWidth = SkScalarHalf(rec.getWidth()); 2156d87557278052c131957e5d6e093d3a675162d22robertphillips@google.com halfHeight = SkScalarHalf(temp); 2166d87557278052c131957e5d6e093d3a675162d22robertphillips@google.com } 2176d87557278052c131957e5d6e093d3a675162d22robertphillips@google.com results->fLast.addRect(x - halfWidth, y - halfHeight, 2186d87557278052c131957e5d6e093d3a675162d22robertphillips@google.com x + halfWidth, y + halfHeight); 219629ab540667422d3edcb97c51e9628b7051e1ba4robertphillips@google.com } 220935ad026826fb7d31d562ff7326b84ec3a827456robertphillips@google.com 2216d87557278052c131957e5d6e093d3a675162d22robertphillips@google.com SkASSERT(curPt == results->fNumPoints); 222629ab540667422d3edcb97c51e9628b7051e1ba4robertphillips@google.com } 223629ab540667422d3edcb97c51e9628b7051e1ba4robertphillips@google.com 224629ab540667422d3edcb97c51e9628b7051e1ba4robertphillips@google.com return true; 2258a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com} 2268a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com 227aec143824c9be4e4af6e2cb7cce3d2d2268c0b15commit-bot@chromium.orgSkPathEffect::DashType SkDashPathEffect::asADash(DashInfo* info) const { 228aec143824c9be4e4af6e2cb7cce3d2d2268c0b15commit-bot@chromium.org if (info) { 229aec143824c9be4e4af6e2cb7cce3d2d2268c0b15commit-bot@chromium.org if (info->fCount >= fCount && NULL != info->fIntervals) { 230aec143824c9be4e4af6e2cb7cce3d2d2268c0b15commit-bot@chromium.org memcpy(info->fIntervals, fIntervals, fCount * sizeof(SkScalar)); 231aec143824c9be4e4af6e2cb7cce3d2d2268c0b15commit-bot@chromium.org } 232aec143824c9be4e4af6e2cb7cce3d2d2268c0b15commit-bot@chromium.org info->fCount = fCount; 233aec143824c9be4e4af6e2cb7cce3d2d2268c0b15commit-bot@chromium.org info->fPhase = fPhase; 234aec143824c9be4e4af6e2cb7cce3d2d2268c0b15commit-bot@chromium.org } 235aec143824c9be4e4af6e2cb7cce3d2d2268c0b15commit-bot@chromium.org return kDash_DashType; 236aec143824c9be4e4af6e2cb7cce3d2d2268c0b15commit-bot@chromium.org} 237aec143824c9be4e4af6e2cb7cce3d2d2268c0b15commit-bot@chromium.org 238c2eae4795478ab134a2315b1a9ff2c5de1d049e4robertphillips@google.comSkFlattenable::Factory SkDashPathEffect::getFactory() const { 2397fc2228795537a6202a4c25e63eada30dbcaf698commit-bot@chromium.org return CreateProc; 2408a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com} 2418a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com 2428b0e8ac5f582de80356019406e2975079bf0829dcommit-bot@chromium.orgvoid SkDashPathEffect::flatten(SkWriteBuffer& buffer) const { 24354924243c1b65b3ee6d8fa064b50a9b1bb2a19a5djsollen@google.com this->INHERITED::flatten(buffer); 244aec143824c9be4e4af6e2cb7cce3d2d2268c0b15commit-bot@chromium.org buffer.writeScalar(fPhase); 245c73dd5c6880739f26216f198c757028fd28df1a4djsollen@google.com buffer.writeScalarArray(fIntervals, fCount); 2468a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com} 2478a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com 2488b0e8ac5f582de80356019406e2975079bf0829dcommit-bot@chromium.orgSkFlattenable* SkDashPathEffect::CreateProc(SkReadBuffer& buffer) { 2498a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com return SkNEW_ARGS(SkDashPathEffect, (buffer)); 2508a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com} 2518a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com 2528b0e8ac5f582de80356019406e2975079bf0829dcommit-bot@chromium.orgSkDashPathEffect::SkDashPathEffect(SkReadBuffer& buffer) : INHERITED(buffer) { 2537ed173b1ebac84671fb0dc1b9bd323a5e6e63771commit-bot@chromium.org bool useOldPic = buffer.isVersionLT(SkReadBuffer::kDashWritesPhaseIntervals_Version); 254aec143824c9be4e4af6e2cb7cce3d2d2268c0b15commit-bot@chromium.org if (useOldPic) { 255aec143824c9be4e4af6e2cb7cce3d2d2268c0b15commit-bot@chromium.org fInitialDashIndex = buffer.readInt(); 256aec143824c9be4e4af6e2cb7cce3d2d2268c0b15commit-bot@chromium.org fInitialDashLength = buffer.readScalar(); 257aec143824c9be4e4af6e2cb7cce3d2d2268c0b15commit-bot@chromium.org fIntervalLength = buffer.readScalar(); 258aec143824c9be4e4af6e2cb7cce3d2d2268c0b15commit-bot@chromium.org buffer.readBool(); // Dummy for old ScalarToFit field 259aec143824c9be4e4af6e2cb7cce3d2d2268c0b15commit-bot@chromium.org } else { 260aec143824c9be4e4af6e2cb7cce3d2d2268c0b15commit-bot@chromium.org fPhase = buffer.readScalar(); 261aec143824c9be4e4af6e2cb7cce3d2d2268c0b15commit-bot@chromium.org } 262fbfcd5602128ec010c82cb733c9cdc0a3254f9f3rmistry@google.com 263c73dd5c6880739f26216f198c757028fd28df1a4djsollen@google.com fCount = buffer.getArrayCount(); 264ef74fa189b738e13295d6a96f86a6e10223505a8commit-bot@chromium.org size_t allocSize = sizeof(SkScalar) * fCount; 265ef74fa189b738e13295d6a96f86a6e10223505a8commit-bot@chromium.org if (buffer.validateAvailable(allocSize)) { 266ef74fa189b738e13295d6a96f86a6e10223505a8commit-bot@chromium.org fIntervals = (SkScalar*)sk_malloc_throw(allocSize); 267ef74fa189b738e13295d6a96f86a6e10223505a8commit-bot@chromium.org buffer.readScalarArray(fIntervals, fCount); 268ef74fa189b738e13295d6a96f86a6e10223505a8commit-bot@chromium.org } else { 269ef74fa189b738e13295d6a96f86a6e10223505a8commit-bot@chromium.org fIntervals = NULL; 270ef74fa189b738e13295d6a96f86a6e10223505a8commit-bot@chromium.org } 271aec143824c9be4e4af6e2cb7cce3d2d2268c0b15commit-bot@chromium.org 272aec143824c9be4e4af6e2cb7cce3d2d2268c0b15commit-bot@chromium.org if (useOldPic) { 273aec143824c9be4e4af6e2cb7cce3d2d2268c0b15commit-bot@chromium.org fPhase = 0; 2746b3eebce43dcd0e409ce953d2a2ea93df2b97733commit-bot@chromium.org if (fInitialDashLength != -1) { // Signal for bad dash interval 2756b3eebce43dcd0e409ce953d2a2ea93df2b97733commit-bot@chromium.org for (int i = 0; i < fInitialDashIndex; ++i) { 2766b3eebce43dcd0e409ce953d2a2ea93df2b97733commit-bot@chromium.org fPhase += fIntervals[i]; 2776b3eebce43dcd0e409ce953d2a2ea93df2b97733commit-bot@chromium.org } 2786b3eebce43dcd0e409ce953d2a2ea93df2b97733commit-bot@chromium.org fPhase += fIntervals[fInitialDashIndex] - fInitialDashLength; 279aec143824c9be4e4af6e2cb7cce3d2d2268c0b15commit-bot@chromium.org } 280aec143824c9be4e4af6e2cb7cce3d2d2268c0b15commit-bot@chromium.org } else { 281a22ea1882391cc5c84136060636d5c952c1f34b3egdaniel // set the internal data members, fPhase should have been between 0 and intervalLength 282a22ea1882391cc5c84136060636d5c952c1f34b3egdaniel // when written to buffer so no need to adjust it 283a22ea1882391cc5c84136060636d5c952c1f34b3egdaniel SkDashPath::CalcDashParameters(fPhase, fIntervals, fCount, &fInitialDashLength, 284a22ea1882391cc5c84136060636d5c952c1f34b3egdaniel &fInitialDashIndex, &fIntervalLength); 285aec143824c9be4e4af6e2cb7cce3d2d2268c0b15commit-bot@chromium.org } 2868a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com} 287