1ca0c8389e2fd1c7f528869beb77a6c8587d59f29robertphillips@google.com/* 2ca0c8389e2fd1c7f528869beb77a6c8587d59f29robertphillips@google.com * Copyright 2013 Google Inc. 3ca0c8389e2fd1c7f528869beb77a6c8587d59f29robertphillips@google.com * 4ca0c8389e2fd1c7f528869beb77a6c8587d59f29robertphillips@google.com * Use of this source code is governed by a BSD-style license that can be 5ca0c8389e2fd1c7f528869beb77a6c8587d59f29robertphillips@google.com * found in the LICENSE file. 6ca0c8389e2fd1c7f528869beb77a6c8587d59f29robertphillips@google.com */ 7ca0c8389e2fd1c7f528869beb77a6c8587d59f29robertphillips@google.com 8ca0c8389e2fd1c7f528869beb77a6c8587d59f29robertphillips@google.com#include "SkBuffer.h" 978358bf624c7e7c09ffccf638c50870808d884d6mtklein#include "SkLazyPtr.h" 10ca0c8389e2fd1c7f528869beb77a6c8587d59f29robertphillips@google.com#include "SkPath.h" 11ca0c8389e2fd1c7f528869beb77a6c8587d59f29robertphillips@google.com#include "SkPathRef.h" 12ca0c8389e2fd1c7f528869beb77a6c8587d59f29robertphillips@google.com 133e292aa398dc40f5188bc4f0b36c8916ac552308robertphillips@google.com////////////////////////////////////////////////////////////////////////////// 143e292aa398dc40f5188bc4f0b36c8916ac552308robertphillips@google.comSkPathRef::Editor::Editor(SkAutoTUnref<SkPathRef>* pathRef, 153e292aa398dc40f5188bc4f0b36c8916ac552308robertphillips@google.com int incReserveVerbs, 163e292aa398dc40f5188bc4f0b36c8916ac552308robertphillips@google.com int incReservePoints) 173e292aa398dc40f5188bc4f0b36c8916ac552308robertphillips@google.com{ 183e292aa398dc40f5188bc4f0b36c8916ac552308robertphillips@google.com if ((*pathRef)->unique()) { 193e292aa398dc40f5188bc4f0b36c8916ac552308robertphillips@google.com (*pathRef)->incReserve(incReserveVerbs, incReservePoints); 203e292aa398dc40f5188bc4f0b36c8916ac552308robertphillips@google.com } else { 213e292aa398dc40f5188bc4f0b36c8916ac552308robertphillips@google.com SkPathRef* copy = SkNEW(SkPathRef); 223e292aa398dc40f5188bc4f0b36c8916ac552308robertphillips@google.com copy->copy(**pathRef, incReserveVerbs, incReservePoints); 233e292aa398dc40f5188bc4f0b36c8916ac552308robertphillips@google.com pathRef->reset(copy); 243e292aa398dc40f5188bc4f0b36c8916ac552308robertphillips@google.com } 253e292aa398dc40f5188bc4f0b36c8916ac552308robertphillips@google.com fPathRef = *pathRef; 263e292aa398dc40f5188bc4f0b36c8916ac552308robertphillips@google.com fPathRef->fGenerationID = 0; 273e292aa398dc40f5188bc4f0b36c8916ac552308robertphillips@google.com SkDEBUGCODE(sk_atomic_inc(&fPathRef->fEditorsAttached);) 28ca0c8389e2fd1c7f528869beb77a6c8587d59f29robertphillips@google.com} 29ca0c8389e2fd1c7f528869beb77a6c8587d59f29robertphillips@google.com 303e292aa398dc40f5188bc4f0b36c8916ac552308robertphillips@google.com////////////////////////////////////////////////////////////////////////////// 31709ca75f032d7c60eb53c5840524a875a3a6cdb1commit-bot@chromium.org 3278358bf624c7e7c09ffccf638c50870808d884d6mtkleinSkPathRef* SkPathRef::CreateEmptyImpl() { 337a6a1ea54fa24dd4f6e9811e4f843f387fda3457Mike Klein SkPathRef* empty = SkNEW(SkPathRef); 347a6a1ea54fa24dd4f6e9811e4f843f387fda3457Mike Klein empty->computeBounds(); // Avoids races later to be the first to do this. 357a6a1ea54fa24dd4f6e9811e4f843f387fda3457Mike Klein return empty; 361f81fd6546c111e21bc665657e976b9d842192dfcommit-bot@chromium.org} 371f81fd6546c111e21bc665657e976b9d842192dfcommit-bot@chromium.org 381f81fd6546c111e21bc665657e976b9d842192dfcommit-bot@chromium.orgSkPathRef* SkPathRef::CreateEmpty() { 3978358bf624c7e7c09ffccf638c50870808d884d6mtklein SK_DECLARE_STATIC_LAZY_PTR(SkPathRef, empty, CreateEmptyImpl); 4078358bf624c7e7c09ffccf638c50870808d884d6mtklein return SkRef(empty.get()); 411f81fd6546c111e21bc665657e976b9d842192dfcommit-bot@chromium.org} 421f81fd6546c111e21bc665657e976b9d842192dfcommit-bot@chromium.org 433e292aa398dc40f5188bc4f0b36c8916ac552308robertphillips@google.comvoid SkPathRef::CreateTransformedCopy(SkAutoTUnref<SkPathRef>* dst, 443e292aa398dc40f5188bc4f0b36c8916ac552308robertphillips@google.com const SkPathRef& src, 453e292aa398dc40f5188bc4f0b36c8916ac552308robertphillips@google.com const SkMatrix& matrix) { 4603087072483378a43f7b3f7a47944614187275ebrobertphillips@google.com SkDEBUGCODE(src.validate();) 473e292aa398dc40f5188bc4f0b36c8916ac552308robertphillips@google.com if (matrix.isIdentity()) { 483e292aa398dc40f5188bc4f0b36c8916ac552308robertphillips@google.com if (*dst != &src) { 493e292aa398dc40f5188bc4f0b36c8916ac552308robertphillips@google.com src.ref(); 503e292aa398dc40f5188bc4f0b36c8916ac552308robertphillips@google.com dst->reset(const_cast<SkPathRef*>(&src)); 5103087072483378a43f7b3f7a47944614187275ebrobertphillips@google.com SkDEBUGCODE((*dst)->validate();) 523e292aa398dc40f5188bc4f0b36c8916ac552308robertphillips@google.com } 533e292aa398dc40f5188bc4f0b36c8916ac552308robertphillips@google.com return; 54ca0c8389e2fd1c7f528869beb77a6c8587d59f29robertphillips@google.com } 553e292aa398dc40f5188bc4f0b36c8916ac552308robertphillips@google.com 56b06e88dc6505412cc2b1a5f0bfb0f669465e1f8erobertphillips@google.com if (!(*dst)->unique()) { 573e292aa398dc40f5188bc4f0b36c8916ac552308robertphillips@google.com dst->reset(SkNEW(SkPathRef)); 58b06e88dc6505412cc2b1a5f0bfb0f669465e1f8erobertphillips@google.com } 59b06e88dc6505412cc2b1a5f0bfb0f669465e1f8erobertphillips@google.com 60b06e88dc6505412cc2b1a5f0bfb0f669465e1f8erobertphillips@google.com if (*dst != &src) { 613e292aa398dc40f5188bc4f0b36c8916ac552308robertphillips@google.com (*dst)->resetToSize(src.fVerbCnt, src.fPointCnt, src.fConicWeights.count()); 623e292aa398dc40f5188bc4f0b36c8916ac552308robertphillips@google.com memcpy((*dst)->verbsMemWritable(), src.verbsMemBegin(), src.fVerbCnt * sizeof(uint8_t)); 633e292aa398dc40f5188bc4f0b36c8916ac552308robertphillips@google.com (*dst)->fConicWeights = src.fConicWeights; 643e292aa398dc40f5188bc4f0b36c8916ac552308robertphillips@google.com } 653e292aa398dc40f5188bc4f0b36c8916ac552308robertphillips@google.com 66b06e88dc6505412cc2b1a5f0bfb0f669465e1f8erobertphillips@google.com SkASSERT((*dst)->countPoints() == src.countPoints()); 67b06e88dc6505412cc2b1a5f0bfb0f669465e1f8erobertphillips@google.com SkASSERT((*dst)->countVerbs() == src.countVerbs()); 68b06e88dc6505412cc2b1a5f0bfb0f669465e1f8erobertphillips@google.com SkASSERT((*dst)->fConicWeights.count() == src.fConicWeights.count()); 69b06e88dc6505412cc2b1a5f0bfb0f669465e1f8erobertphillips@google.com 703e292aa398dc40f5188bc4f0b36c8916ac552308robertphillips@google.com // Need to check this here in case (&src == dst) 713e292aa398dc40f5188bc4f0b36c8916ac552308robertphillips@google.com bool canXformBounds = !src.fBoundsIsDirty && matrix.rectStaysRect() && src.countPoints() > 1; 723e292aa398dc40f5188bc4f0b36c8916ac552308robertphillips@google.com 733e292aa398dc40f5188bc4f0b36c8916ac552308robertphillips@google.com matrix.mapPoints((*dst)->fPoints, src.points(), src.fPointCnt); 743e292aa398dc40f5188bc4f0b36c8916ac552308robertphillips@google.com 753e292aa398dc40f5188bc4f0b36c8916ac552308robertphillips@google.com /* 763e292aa398dc40f5188bc4f0b36c8916ac552308robertphillips@google.com * Here we optimize the bounds computation, by noting if the bounds are 773e292aa398dc40f5188bc4f0b36c8916ac552308robertphillips@google.com * already known, and if so, we just transform those as well and mark 783e292aa398dc40f5188bc4f0b36c8916ac552308robertphillips@google.com * them as "known", rather than force the transformed path to have to 793e292aa398dc40f5188bc4f0b36c8916ac552308robertphillips@google.com * recompute them. 803e292aa398dc40f5188bc4f0b36c8916ac552308robertphillips@google.com * 813e292aa398dc40f5188bc4f0b36c8916ac552308robertphillips@google.com * Special gotchas if the path is effectively empty (<= 1 point) or 823e292aa398dc40f5188bc4f0b36c8916ac552308robertphillips@google.com * if it is non-finite. In those cases bounds need to stay empty, 833e292aa398dc40f5188bc4f0b36c8916ac552308robertphillips@google.com * regardless of the matrix. 843e292aa398dc40f5188bc4f0b36c8916ac552308robertphillips@google.com */ 853e292aa398dc40f5188bc4f0b36c8916ac552308robertphillips@google.com if (canXformBounds) { 863e292aa398dc40f5188bc4f0b36c8916ac552308robertphillips@google.com (*dst)->fBoundsIsDirty = false; 873e292aa398dc40f5188bc4f0b36c8916ac552308robertphillips@google.com if (src.fIsFinite) { 880b544ae222aab1c5d9122a8dfe2800451b31d979mtklein matrix.mapRect((*dst)->fBounds.get(), src.fBounds); 890b544ae222aab1c5d9122a8dfe2800451b31d979mtklein if (!((*dst)->fIsFinite = (*dst)->fBounds->isFinite())) { 900b544ae222aab1c5d9122a8dfe2800451b31d979mtklein (*dst)->fBounds->setEmpty(); 913e292aa398dc40f5188bc4f0b36c8916ac552308robertphillips@google.com } 923e292aa398dc40f5188bc4f0b36c8916ac552308robertphillips@google.com } else { 933e292aa398dc40f5188bc4f0b36c8916ac552308robertphillips@google.com (*dst)->fIsFinite = false; 940b544ae222aab1c5d9122a8dfe2800451b31d979mtklein (*dst)->fBounds->setEmpty(); 953e292aa398dc40f5188bc4f0b36c8916ac552308robertphillips@google.com } 963e292aa398dc40f5188bc4f0b36c8916ac552308robertphillips@google.com } else { 973e292aa398dc40f5188bc4f0b36c8916ac552308robertphillips@google.com (*dst)->fBoundsIsDirty = true; 983e292aa398dc40f5188bc4f0b36c8916ac552308robertphillips@google.com } 993e292aa398dc40f5188bc4f0b36c8916ac552308robertphillips@google.com 1006b8dbb668f1f069270d35a47cfe98decd059c625robertphillips@google.com (*dst)->fSegmentMask = src.fSegmentMask; 1016b8dbb668f1f069270d35a47cfe98decd059c625robertphillips@google.com 102466310dbd3073add2ec934e336c30deaaf702eaerobertphillips@google.com // It's an oval only if it stays a rect. 103466310dbd3073add2ec934e336c30deaaf702eaerobertphillips@google.com (*dst)->fIsOval = src.fIsOval && matrix.rectStaysRect(); 104466310dbd3073add2ec934e336c30deaaf702eaerobertphillips@google.com 10503087072483378a43f7b3f7a47944614187275ebrobertphillips@google.com SkDEBUGCODE((*dst)->validate();) 106ca0c8389e2fd1c7f528869beb77a6c8587d59f29robertphillips@google.com} 107ca0c8389e2fd1c7f528869beb77a6c8587d59f29robertphillips@google.com 108fed2ab648341ec153ad2af746a31d368963171e4commit-bot@chromium.orgSkPathRef* SkPathRef::CreateFromBuffer(SkRBuffer* buffer) { 109ca0c8389e2fd1c7f528869beb77a6c8587d59f29robertphillips@google.com SkPathRef* ref = SkNEW(SkPathRef); 110466310dbd3073add2ec934e336c30deaaf702eaerobertphillips@google.com bool isOval; 1116b8dbb668f1f069270d35a47cfe98decd059c625robertphillips@google.com uint8_t segmentMask; 112466310dbd3073add2ec934e336c30deaaf702eaerobertphillips@google.com 113466310dbd3073add2ec934e336c30deaaf702eaerobertphillips@google.com int32_t packed; 114466310dbd3073add2ec934e336c30deaaf702eaerobertphillips@google.com if (!buffer->readS32(&packed)) { 115466310dbd3073add2ec934e336c30deaaf702eaerobertphillips@google.com SkDELETE(ref); 116466310dbd3073add2ec934e336c30deaaf702eaerobertphillips@google.com return NULL; 117466310dbd3073add2ec934e336c30deaaf702eaerobertphillips@google.com } 118466310dbd3073add2ec934e336c30deaaf702eaerobertphillips@google.com 119466310dbd3073add2ec934e336c30deaaf702eaerobertphillips@google.com ref->fIsFinite = (packed >> kIsFinite_SerializationShift) & 1; 120fed2ab648341ec153ad2af746a31d368963171e4commit-bot@chromium.org segmentMask = (packed >> kSegmentMask_SerializationShift) & 0xF; 121fed2ab648341ec153ad2af746a31d368963171e4commit-bot@chromium.org isOval = (packed >> kIsOval_SerializationShift) & 1; 122ca0c8389e2fd1c7f528869beb77a6c8587d59f29robertphillips@google.com 1238f457e3230f1a4ce737f512ffbb5c919b8d02407commit-bot@chromium.org int32_t verbCount, pointCount, conicCount; 1248f457e3230f1a4ce737f512ffbb5c919b8d02407commit-bot@chromium.org if (!buffer->readU32(&(ref->fGenerationID)) || 1258f457e3230f1a4ce737f512ffbb5c919b8d02407commit-bot@chromium.org !buffer->readS32(&verbCount) || 1268f457e3230f1a4ce737f512ffbb5c919b8d02407commit-bot@chromium.org !buffer->readS32(&pointCount) || 1278f457e3230f1a4ce737f512ffbb5c919b8d02407commit-bot@chromium.org !buffer->readS32(&conicCount)) { 1288f457e3230f1a4ce737f512ffbb5c919b8d02407commit-bot@chromium.org SkDELETE(ref); 1298f457e3230f1a4ce737f512ffbb5c919b8d02407commit-bot@chromium.org return NULL; 1308f457e3230f1a4ce737f512ffbb5c919b8d02407commit-bot@chromium.org } 131ca0c8389e2fd1c7f528869beb77a6c8587d59f29robertphillips@google.com 1328f457e3230f1a4ce737f512ffbb5c919b8d02407commit-bot@chromium.org ref->resetToSize(verbCount, pointCount, conicCount); 133ca0c8389e2fd1c7f528869beb77a6c8587d59f29robertphillips@google.com SkASSERT(verbCount == ref->countVerbs()); 134ca0c8389e2fd1c7f528869beb77a6c8587d59f29robertphillips@google.com SkASSERT(pointCount == ref->countPoints()); 135ca0c8389e2fd1c7f528869beb77a6c8587d59f29robertphillips@google.com SkASSERT(conicCount == ref->fConicWeights.count()); 1368f457e3230f1a4ce737f512ffbb5c919b8d02407commit-bot@chromium.org 1378f457e3230f1a4ce737f512ffbb5c919b8d02407commit-bot@chromium.org if (!buffer->read(ref->verbsMemWritable(), verbCount * sizeof(uint8_t)) || 1388f457e3230f1a4ce737f512ffbb5c919b8d02407commit-bot@chromium.org !buffer->read(ref->fPoints, pointCount * sizeof(SkPoint)) || 1398f457e3230f1a4ce737f512ffbb5c919b8d02407commit-bot@chromium.org !buffer->read(ref->fConicWeights.begin(), conicCount * sizeof(SkScalar)) || 1408f457e3230f1a4ce737f512ffbb5c919b8d02407commit-bot@chromium.org !buffer->read(&ref->fBounds, sizeof(SkRect))) { 1418f457e3230f1a4ce737f512ffbb5c919b8d02407commit-bot@chromium.org SkDELETE(ref); 1428f457e3230f1a4ce737f512ffbb5c919b8d02407commit-bot@chromium.org return NULL; 1438f457e3230f1a4ce737f512ffbb5c919b8d02407commit-bot@chromium.org } 144ca0c8389e2fd1c7f528869beb77a6c8587d59f29robertphillips@google.com ref->fBoundsIsDirty = false; 1456b8dbb668f1f069270d35a47cfe98decd059c625robertphillips@google.com 1466b8dbb668f1f069270d35a47cfe98decd059c625robertphillips@google.com // resetToSize clears fSegmentMask and fIsOval 1476b8dbb668f1f069270d35a47cfe98decd059c625robertphillips@google.com ref->fSegmentMask = segmentMask; 148466310dbd3073add2ec934e336c30deaaf702eaerobertphillips@google.com ref->fIsOval = isOval; 149ca0c8389e2fd1c7f528869beb77a6c8587d59f29robertphillips@google.com return ref; 150ca0c8389e2fd1c7f528869beb77a6c8587d59f29robertphillips@google.com} 151ca0c8389e2fd1c7f528869beb77a6c8587d59f29robertphillips@google.com 1523e292aa398dc40f5188bc4f0b36c8916ac552308robertphillips@google.comvoid SkPathRef::Rewind(SkAutoTUnref<SkPathRef>* pathRef) { 1533e292aa398dc40f5188bc4f0b36c8916ac552308robertphillips@google.com if ((*pathRef)->unique()) { 15403087072483378a43f7b3f7a47944614187275ebrobertphillips@google.com SkDEBUGCODE((*pathRef)->validate();) 1553e292aa398dc40f5188bc4f0b36c8916ac552308robertphillips@google.com (*pathRef)->fBoundsIsDirty = true; // this also invalidates fIsFinite 1563e292aa398dc40f5188bc4f0b36c8916ac552308robertphillips@google.com (*pathRef)->fVerbCnt = 0; 1573e292aa398dc40f5188bc4f0b36c8916ac552308robertphillips@google.com (*pathRef)->fPointCnt = 0; 1583e292aa398dc40f5188bc4f0b36c8916ac552308robertphillips@google.com (*pathRef)->fFreeSpace = (*pathRef)->currSize(); 1593e292aa398dc40f5188bc4f0b36c8916ac552308robertphillips@google.com (*pathRef)->fGenerationID = 0; 1603e292aa398dc40f5188bc4f0b36c8916ac552308robertphillips@google.com (*pathRef)->fConicWeights.rewind(); 1616b8dbb668f1f069270d35a47cfe98decd059c625robertphillips@google.com (*pathRef)->fSegmentMask = 0; 162466310dbd3073add2ec934e336c30deaaf702eaerobertphillips@google.com (*pathRef)->fIsOval = false; 16303087072483378a43f7b3f7a47944614187275ebrobertphillips@google.com SkDEBUGCODE((*pathRef)->validate();) 1643e292aa398dc40f5188bc4f0b36c8916ac552308robertphillips@google.com } else { 1653e292aa398dc40f5188bc4f0b36c8916ac552308robertphillips@google.com int oldVCnt = (*pathRef)->countVerbs(); 1663e292aa398dc40f5188bc4f0b36c8916ac552308robertphillips@google.com int oldPCnt = (*pathRef)->countPoints(); 1673e292aa398dc40f5188bc4f0b36c8916ac552308robertphillips@google.com pathRef->reset(SkNEW(SkPathRef)); 1683e292aa398dc40f5188bc4f0b36c8916ac552308robertphillips@google.com (*pathRef)->resetToSize(0, 0, 0, oldVCnt, oldPCnt); 1693e292aa398dc40f5188bc4f0b36c8916ac552308robertphillips@google.com } 1703e292aa398dc40f5188bc4f0b36c8916ac552308robertphillips@google.com} 1713e292aa398dc40f5188bc4f0b36c8916ac552308robertphillips@google.com 1723e292aa398dc40f5188bc4f0b36c8916ac552308robertphillips@google.combool SkPathRef::operator== (const SkPathRef& ref) const { 17303087072483378a43f7b3f7a47944614187275ebrobertphillips@google.com SkDEBUGCODE(this->validate();) 17403087072483378a43f7b3f7a47944614187275ebrobertphillips@google.com SkDEBUGCODE(ref.validate();) 1756b8dbb668f1f069270d35a47cfe98decd059c625robertphillips@google.com 1766b8dbb668f1f069270d35a47cfe98decd059c625robertphillips@google.com // We explicitly check fSegmentMask as a quick-reject. We could skip it, 1776b8dbb668f1f069270d35a47cfe98decd059c625robertphillips@google.com // since it is only a cache of info in the fVerbs, but its a fast way to 1786b8dbb668f1f069270d35a47cfe98decd059c625robertphillips@google.com // notice a difference 1796b8dbb668f1f069270d35a47cfe98decd059c625robertphillips@google.com if (fSegmentMask != ref.fSegmentMask) { 1806b8dbb668f1f069270d35a47cfe98decd059c625robertphillips@google.com return false; 1816b8dbb668f1f069270d35a47cfe98decd059c625robertphillips@google.com } 1826b8dbb668f1f069270d35a47cfe98decd059c625robertphillips@google.com 1833e292aa398dc40f5188bc4f0b36c8916ac552308robertphillips@google.com bool genIDMatch = fGenerationID && fGenerationID == ref.fGenerationID; 1843e292aa398dc40f5188bc4f0b36c8916ac552308robertphillips@google.com#ifdef SK_RELEASE 1853e292aa398dc40f5188bc4f0b36c8916ac552308robertphillips@google.com if (genIDMatch) { 1863e292aa398dc40f5188bc4f0b36c8916ac552308robertphillips@google.com return true; 1873e292aa398dc40f5188bc4f0b36c8916ac552308robertphillips@google.com } 1883e292aa398dc40f5188bc4f0b36c8916ac552308robertphillips@google.com#endif 1893e292aa398dc40f5188bc4f0b36c8916ac552308robertphillips@google.com if (fPointCnt != ref.fPointCnt || 1903e292aa398dc40f5188bc4f0b36c8916ac552308robertphillips@google.com fVerbCnt != ref.fVerbCnt) { 1913e292aa398dc40f5188bc4f0b36c8916ac552308robertphillips@google.com SkASSERT(!genIDMatch); 1923e292aa398dc40f5188bc4f0b36c8916ac552308robertphillips@google.com return false; 1933e292aa398dc40f5188bc4f0b36c8916ac552308robertphillips@google.com } 1943e292aa398dc40f5188bc4f0b36c8916ac552308robertphillips@google.com if (0 != memcmp(this->verbsMemBegin(), 1953e292aa398dc40f5188bc4f0b36c8916ac552308robertphillips@google.com ref.verbsMemBegin(), 1963e292aa398dc40f5188bc4f0b36c8916ac552308robertphillips@google.com ref.fVerbCnt * sizeof(uint8_t))) { 1973e292aa398dc40f5188bc4f0b36c8916ac552308robertphillips@google.com SkASSERT(!genIDMatch); 1983e292aa398dc40f5188bc4f0b36c8916ac552308robertphillips@google.com return false; 1993e292aa398dc40f5188bc4f0b36c8916ac552308robertphillips@google.com } 2003e292aa398dc40f5188bc4f0b36c8916ac552308robertphillips@google.com if (0 != memcmp(this->points(), 2013e292aa398dc40f5188bc4f0b36c8916ac552308robertphillips@google.com ref.points(), 2023e292aa398dc40f5188bc4f0b36c8916ac552308robertphillips@google.com ref.fPointCnt * sizeof(SkPoint))) { 2033e292aa398dc40f5188bc4f0b36c8916ac552308robertphillips@google.com SkASSERT(!genIDMatch); 2043e292aa398dc40f5188bc4f0b36c8916ac552308robertphillips@google.com return false; 2053e292aa398dc40f5188bc4f0b36c8916ac552308robertphillips@google.com } 2063e292aa398dc40f5188bc4f0b36c8916ac552308robertphillips@google.com if (fConicWeights != ref.fConicWeights) { 2073e292aa398dc40f5188bc4f0b36c8916ac552308robertphillips@google.com SkASSERT(!genIDMatch); 2083e292aa398dc40f5188bc4f0b36c8916ac552308robertphillips@google.com return false; 2093e292aa398dc40f5188bc4f0b36c8916ac552308robertphillips@google.com } 2103e292aa398dc40f5188bc4f0b36c8916ac552308robertphillips@google.com // We've done the work to determine that these are equal. If either has a zero genID, copy 2113e292aa398dc40f5188bc4f0b36c8916ac552308robertphillips@google.com // the other's. If both are 0 then genID() will compute the next ID. 2123e292aa398dc40f5188bc4f0b36c8916ac552308robertphillips@google.com if (0 == fGenerationID) { 2133e292aa398dc40f5188bc4f0b36c8916ac552308robertphillips@google.com fGenerationID = ref.genID(); 2143e292aa398dc40f5188bc4f0b36c8916ac552308robertphillips@google.com } else if (0 == ref.fGenerationID) { 2153e292aa398dc40f5188bc4f0b36c8916ac552308robertphillips@google.com ref.fGenerationID = this->genID(); 2163e292aa398dc40f5188bc4f0b36c8916ac552308robertphillips@google.com } 2173e292aa398dc40f5188bc4f0b36c8916ac552308robertphillips@google.com return true; 2183e292aa398dc40f5188bc4f0b36c8916ac552308robertphillips@google.com} 2193e292aa398dc40f5188bc4f0b36c8916ac552308robertphillips@google.com 2206b8dbb668f1f069270d35a47cfe98decd059c625robertphillips@google.comvoid SkPathRef::writeToBuffer(SkWBuffer* buffer) const { 22103087072483378a43f7b3f7a47944614187275ebrobertphillips@google.com SkDEBUGCODE(this->validate();) 222ca0c8389e2fd1c7f528869beb77a6c8587d59f29robertphillips@google.com SkDEBUGCODE(size_t beforePos = buffer->pos();) 223ca0c8389e2fd1c7f528869beb77a6c8587d59f29robertphillips@google.com 224ca0c8389e2fd1c7f528869beb77a6c8587d59f29robertphillips@google.com // Call getBounds() to ensure (as a side-effect) that fBounds 225ca0c8389e2fd1c7f528869beb77a6c8587d59f29robertphillips@google.com // and fIsFinite are computed. 226ca0c8389e2fd1c7f528869beb77a6c8587d59f29robertphillips@google.com const SkRect& bounds = this->getBounds(); 227ca0c8389e2fd1c7f528869beb77a6c8587d59f29robertphillips@google.com 228466310dbd3073add2ec934e336c30deaaf702eaerobertphillips@google.com int32_t packed = ((fIsFinite & 1) << kIsFinite_SerializationShift) | 2296b8dbb668f1f069270d35a47cfe98decd059c625robertphillips@google.com ((fIsOval & 1) << kIsOval_SerializationShift) | 2306b8dbb668f1f069270d35a47cfe98decd059c625robertphillips@google.com (fSegmentMask << kSegmentMask_SerializationShift); 231ca0c8389e2fd1c7f528869beb77a6c8587d59f29robertphillips@google.com buffer->write32(packed); 232ca0c8389e2fd1c7f528869beb77a6c8587d59f29robertphillips@google.com 233ca0c8389e2fd1c7f528869beb77a6c8587d59f29robertphillips@google.com // TODO: write gen ID here. Problem: We don't know if we're cross process or not from 234ca0c8389e2fd1c7f528869beb77a6c8587d59f29robertphillips@google.com // SkWBuffer. Until this is fixed we write 0. 235ca0c8389e2fd1c7f528869beb77a6c8587d59f29robertphillips@google.com buffer->write32(0); 236ca0c8389e2fd1c7f528869beb77a6c8587d59f29robertphillips@google.com buffer->write32(fVerbCnt); 237ca0c8389e2fd1c7f528869beb77a6c8587d59f29robertphillips@google.com buffer->write32(fPointCnt); 238ca0c8389e2fd1c7f528869beb77a6c8587d59f29robertphillips@google.com buffer->write32(fConicWeights.count()); 239ca0c8389e2fd1c7f528869beb77a6c8587d59f29robertphillips@google.com buffer->write(verbsMemBegin(), fVerbCnt * sizeof(uint8_t)); 240ca0c8389e2fd1c7f528869beb77a6c8587d59f29robertphillips@google.com buffer->write(fPoints, fPointCnt * sizeof(SkPoint)); 241ca0c8389e2fd1c7f528869beb77a6c8587d59f29robertphillips@google.com buffer->write(fConicWeights.begin(), fConicWeights.bytes()); 242ca0c8389e2fd1c7f528869beb77a6c8587d59f29robertphillips@google.com buffer->write(&bounds, sizeof(bounds)); 243ca0c8389e2fd1c7f528869beb77a6c8587d59f29robertphillips@google.com 244ca0c8389e2fd1c7f528869beb77a6c8587d59f29robertphillips@google.com SkASSERT(buffer->pos() - beforePos == (size_t) this->writeSize()); 245ca0c8389e2fd1c7f528869beb77a6c8587d59f29robertphillips@google.com} 2463e292aa398dc40f5188bc4f0b36c8916ac552308robertphillips@google.com 2476b8dbb668f1f069270d35a47cfe98decd059c625robertphillips@google.comuint32_t SkPathRef::writeSize() const { 2483e292aa398dc40f5188bc4f0b36c8916ac552308robertphillips@google.com return uint32_t(5 * sizeof(uint32_t) + 2493e292aa398dc40f5188bc4f0b36c8916ac552308robertphillips@google.com fVerbCnt * sizeof(uint8_t) + 2503e292aa398dc40f5188bc4f0b36c8916ac552308robertphillips@google.com fPointCnt * sizeof(SkPoint) + 2513e292aa398dc40f5188bc4f0b36c8916ac552308robertphillips@google.com fConicWeights.bytes() + 2523e292aa398dc40f5188bc4f0b36c8916ac552308robertphillips@google.com sizeof(SkRect)); 2533e292aa398dc40f5188bc4f0b36c8916ac552308robertphillips@google.com} 2543e292aa398dc40f5188bc4f0b36c8916ac552308robertphillips@google.com 25550df4d013f840749f70d1759c23c4217e727fd54skia.committer@gmail.comvoid SkPathRef::copy(const SkPathRef& ref, 25650df4d013f840749f70d1759c23c4217e727fd54skia.committer@gmail.com int additionalReserveVerbs, 2573e292aa398dc40f5188bc4f0b36c8916ac552308robertphillips@google.com int additionalReservePoints) { 25803087072483378a43f7b3f7a47944614187275ebrobertphillips@google.com SkDEBUGCODE(this->validate();) 2593e292aa398dc40f5188bc4f0b36c8916ac552308robertphillips@google.com this->resetToSize(ref.fVerbCnt, ref.fPointCnt, ref.fConicWeights.count(), 2603e292aa398dc40f5188bc4f0b36c8916ac552308robertphillips@google.com additionalReserveVerbs, additionalReservePoints); 2613e292aa398dc40f5188bc4f0b36c8916ac552308robertphillips@google.com memcpy(this->verbsMemWritable(), ref.verbsMemBegin(), ref.fVerbCnt * sizeof(uint8_t)); 2623e292aa398dc40f5188bc4f0b36c8916ac552308robertphillips@google.com memcpy(this->fPoints, ref.fPoints, ref.fPointCnt * sizeof(SkPoint)); 2633e292aa398dc40f5188bc4f0b36c8916ac552308robertphillips@google.com fConicWeights = ref.fConicWeights; 2643e292aa398dc40f5188bc4f0b36c8916ac552308robertphillips@google.com // We could call genID() here to force a real ID (instead of 0). However, if we're making 2653e292aa398dc40f5188bc4f0b36c8916ac552308robertphillips@google.com // a copy then presumably we intend to make a modification immediately afterwards. 2663e292aa398dc40f5188bc4f0b36c8916ac552308robertphillips@google.com fGenerationID = ref.fGenerationID; 2673e292aa398dc40f5188bc4f0b36c8916ac552308robertphillips@google.com fBoundsIsDirty = ref.fBoundsIsDirty; 2683e292aa398dc40f5188bc4f0b36c8916ac552308robertphillips@google.com if (!fBoundsIsDirty) { 2693e292aa398dc40f5188bc4f0b36c8916ac552308robertphillips@google.com fBounds = ref.fBounds; 2703e292aa398dc40f5188bc4f0b36c8916ac552308robertphillips@google.com fIsFinite = ref.fIsFinite; 2713e292aa398dc40f5188bc4f0b36c8916ac552308robertphillips@google.com } 2726b8dbb668f1f069270d35a47cfe98decd059c625robertphillips@google.com fSegmentMask = ref.fSegmentMask; 273466310dbd3073add2ec934e336c30deaaf702eaerobertphillips@google.com fIsOval = ref.fIsOval; 27403087072483378a43f7b3f7a47944614187275ebrobertphillips@google.com SkDEBUGCODE(this->validate();) 2753e292aa398dc40f5188bc4f0b36c8916ac552308robertphillips@google.com} 2763e292aa398dc40f5188bc4f0b36c8916ac552308robertphillips@google.com 27796f5fa02e996e39179f2eb88d57e8ed6114b06c5skia.committer@gmail.comSkPoint* SkPathRef::growForRepeatedVerb(int /*SkPath::Verb*/ verb, 27896f5fa02e996e39179f2eb88d57e8ed6114b06c5skia.committer@gmail.com int numVbs, 2796b8dbb668f1f069270d35a47cfe98decd059c625robertphillips@google.com SkScalar** weights) { 2806b8dbb668f1f069270d35a47cfe98decd059c625robertphillips@google.com // This value is just made-up for now. When count is 4, calling memset was much 2816b8dbb668f1f069270d35a47cfe98decd059c625robertphillips@google.com // slower than just writing the loop. This seems odd, and hopefully in the 2826b8dbb668f1f069270d35a47cfe98decd059c625robertphillips@google.com // future this will appear to have been a fluke... 2836b8dbb668f1f069270d35a47cfe98decd059c625robertphillips@google.com static const unsigned int kMIN_COUNT_FOR_MEMSET_TO_BE_FAST = 16; 2846b8dbb668f1f069270d35a47cfe98decd059c625robertphillips@google.com 2856b8dbb668f1f069270d35a47cfe98decd059c625robertphillips@google.com SkDEBUGCODE(this->validate();) 2866b8dbb668f1f069270d35a47cfe98decd059c625robertphillips@google.com int pCnt; 2876b8dbb668f1f069270d35a47cfe98decd059c625robertphillips@google.com bool dirtyAfterEdit = true; 2886b8dbb668f1f069270d35a47cfe98decd059c625robertphillips@google.com switch (verb) { 2896b8dbb668f1f069270d35a47cfe98decd059c625robertphillips@google.com case SkPath::kMove_Verb: 2906b8dbb668f1f069270d35a47cfe98decd059c625robertphillips@google.com pCnt = numVbs; 2916b8dbb668f1f069270d35a47cfe98decd059c625robertphillips@google.com dirtyAfterEdit = false; 2926b8dbb668f1f069270d35a47cfe98decd059c625robertphillips@google.com break; 2936b8dbb668f1f069270d35a47cfe98decd059c625robertphillips@google.com case SkPath::kLine_Verb: 2946b8dbb668f1f069270d35a47cfe98decd059c625robertphillips@google.com fSegmentMask |= SkPath::kLine_SegmentMask; 2956b8dbb668f1f069270d35a47cfe98decd059c625robertphillips@google.com pCnt = numVbs; 2966b8dbb668f1f069270d35a47cfe98decd059c625robertphillips@google.com break; 2976b8dbb668f1f069270d35a47cfe98decd059c625robertphillips@google.com case SkPath::kQuad_Verb: 2986b8dbb668f1f069270d35a47cfe98decd059c625robertphillips@google.com fSegmentMask |= SkPath::kQuad_SegmentMask; 2996b8dbb668f1f069270d35a47cfe98decd059c625robertphillips@google.com pCnt = 2 * numVbs; 3006b8dbb668f1f069270d35a47cfe98decd059c625robertphillips@google.com break; 3016b8dbb668f1f069270d35a47cfe98decd059c625robertphillips@google.com case SkPath::kConic_Verb: 3026b8dbb668f1f069270d35a47cfe98decd059c625robertphillips@google.com fSegmentMask |= SkPath::kConic_SegmentMask; 3036b8dbb668f1f069270d35a47cfe98decd059c625robertphillips@google.com pCnt = 2 * numVbs; 3046b8dbb668f1f069270d35a47cfe98decd059c625robertphillips@google.com break; 3056b8dbb668f1f069270d35a47cfe98decd059c625robertphillips@google.com case SkPath::kCubic_Verb: 3066b8dbb668f1f069270d35a47cfe98decd059c625robertphillips@google.com fSegmentMask |= SkPath::kCubic_SegmentMask; 3076b8dbb668f1f069270d35a47cfe98decd059c625robertphillips@google.com pCnt = 3 * numVbs; 3086b8dbb668f1f069270d35a47cfe98decd059c625robertphillips@google.com break; 3096b8dbb668f1f069270d35a47cfe98decd059c625robertphillips@google.com case SkPath::kClose_Verb: 3106b8dbb668f1f069270d35a47cfe98decd059c625robertphillips@google.com SkDEBUGFAIL("growForRepeatedVerb called for kClose_Verb"); 3116b8dbb668f1f069270d35a47cfe98decd059c625robertphillips@google.com pCnt = 0; 3126b8dbb668f1f069270d35a47cfe98decd059c625robertphillips@google.com dirtyAfterEdit = false; 3136b8dbb668f1f069270d35a47cfe98decd059c625robertphillips@google.com break; 3146b8dbb668f1f069270d35a47cfe98decd059c625robertphillips@google.com case SkPath::kDone_Verb: 3156b8dbb668f1f069270d35a47cfe98decd059c625robertphillips@google.com SkDEBUGFAIL("growForRepeatedVerb called for kDone"); 3166b8dbb668f1f069270d35a47cfe98decd059c625robertphillips@google.com // fall through 3176b8dbb668f1f069270d35a47cfe98decd059c625robertphillips@google.com default: 3186b8dbb668f1f069270d35a47cfe98decd059c625robertphillips@google.com SkDEBUGFAIL("default should not be reached"); 3196b8dbb668f1f069270d35a47cfe98decd059c625robertphillips@google.com pCnt = 0; 3206b8dbb668f1f069270d35a47cfe98decd059c625robertphillips@google.com dirtyAfterEdit = false; 3216b8dbb668f1f069270d35a47cfe98decd059c625robertphillips@google.com } 3226b8dbb668f1f069270d35a47cfe98decd059c625robertphillips@google.com 3236b8dbb668f1f069270d35a47cfe98decd059c625robertphillips@google.com size_t space = numVbs * sizeof(uint8_t) + pCnt * sizeof (SkPoint); 3246b8dbb668f1f069270d35a47cfe98decd059c625robertphillips@google.com this->makeSpace(space); 3256b8dbb668f1f069270d35a47cfe98decd059c625robertphillips@google.com 3266b8dbb668f1f069270d35a47cfe98decd059c625robertphillips@google.com SkPoint* ret = fPoints + fPointCnt; 3276b8dbb668f1f069270d35a47cfe98decd059c625robertphillips@google.com uint8_t* vb = fVerbs - fVerbCnt; 3286b8dbb668f1f069270d35a47cfe98decd059c625robertphillips@google.com 3296b8dbb668f1f069270d35a47cfe98decd059c625robertphillips@google.com // cast to unsigned, so if kMIN_COUNT_FOR_MEMSET_TO_BE_FAST is defined to 3306b8dbb668f1f069270d35a47cfe98decd059c625robertphillips@google.com // be 0, the compiler will remove the test/branch entirely. 3316b8dbb668f1f069270d35a47cfe98decd059c625robertphillips@google.com if ((unsigned)numVbs >= kMIN_COUNT_FOR_MEMSET_TO_BE_FAST) { 3326b8dbb668f1f069270d35a47cfe98decd059c625robertphillips@google.com memset(vb - numVbs, verb, numVbs); 3336b8dbb668f1f069270d35a47cfe98decd059c625robertphillips@google.com } else { 3346b8dbb668f1f069270d35a47cfe98decd059c625robertphillips@google.com for (int i = 0; i < numVbs; ++i) { 3356b8dbb668f1f069270d35a47cfe98decd059c625robertphillips@google.com vb[~i] = verb; 3366b8dbb668f1f069270d35a47cfe98decd059c625robertphillips@google.com } 3376b8dbb668f1f069270d35a47cfe98decd059c625robertphillips@google.com } 3386b8dbb668f1f069270d35a47cfe98decd059c625robertphillips@google.com 3396b8dbb668f1f069270d35a47cfe98decd059c625robertphillips@google.com fVerbCnt += numVbs; 3406b8dbb668f1f069270d35a47cfe98decd059c625robertphillips@google.com fPointCnt += pCnt; 3416b8dbb668f1f069270d35a47cfe98decd059c625robertphillips@google.com fFreeSpace -= space; 3426b8dbb668f1f069270d35a47cfe98decd059c625robertphillips@google.com fBoundsIsDirty = true; // this also invalidates fIsFinite 3436b8dbb668f1f069270d35a47cfe98decd059c625robertphillips@google.com if (dirtyAfterEdit) { 3446b8dbb668f1f069270d35a47cfe98decd059c625robertphillips@google.com fIsOval = false; 3456b8dbb668f1f069270d35a47cfe98decd059c625robertphillips@google.com } 3466b8dbb668f1f069270d35a47cfe98decd059c625robertphillips@google.com 3476b8dbb668f1f069270d35a47cfe98decd059c625robertphillips@google.com if (SkPath::kConic_Verb == verb) { 34849f085dddff10473b6ebf832a974288300224e60bsalomon SkASSERT(weights); 3496b8dbb668f1f069270d35a47cfe98decd059c625robertphillips@google.com *weights = fConicWeights.append(numVbs); 3506b8dbb668f1f069270d35a47cfe98decd059c625robertphillips@google.com } 3516b8dbb668f1f069270d35a47cfe98decd059c625robertphillips@google.com 3526b8dbb668f1f069270d35a47cfe98decd059c625robertphillips@google.com SkDEBUGCODE(this->validate();) 3536b8dbb668f1f069270d35a47cfe98decd059c625robertphillips@google.com return ret; 3546b8dbb668f1f069270d35a47cfe98decd059c625robertphillips@google.com} 3556b8dbb668f1f069270d35a47cfe98decd059c625robertphillips@google.com 3566b8dbb668f1f069270d35a47cfe98decd059c625robertphillips@google.comSkPoint* SkPathRef::growForVerb(int /* SkPath::Verb*/ verb, SkScalar weight) { 35703087072483378a43f7b3f7a47944614187275ebrobertphillips@google.com SkDEBUGCODE(this->validate();) 3583e292aa398dc40f5188bc4f0b36c8916ac552308robertphillips@google.com int pCnt; 359466310dbd3073add2ec934e336c30deaaf702eaerobertphillips@google.com bool dirtyAfterEdit = true; 3603e292aa398dc40f5188bc4f0b36c8916ac552308robertphillips@google.com switch (verb) { 3613e292aa398dc40f5188bc4f0b36c8916ac552308robertphillips@google.com case SkPath::kMove_Verb: 3623e292aa398dc40f5188bc4f0b36c8916ac552308robertphillips@google.com pCnt = 1; 363466310dbd3073add2ec934e336c30deaaf702eaerobertphillips@google.com dirtyAfterEdit = false; 3643e292aa398dc40f5188bc4f0b36c8916ac552308robertphillips@google.com break; 3653e292aa398dc40f5188bc4f0b36c8916ac552308robertphillips@google.com case SkPath::kLine_Verb: 3666b8dbb668f1f069270d35a47cfe98decd059c625robertphillips@google.com fSegmentMask |= SkPath::kLine_SegmentMask; 3673e292aa398dc40f5188bc4f0b36c8916ac552308robertphillips@google.com pCnt = 1; 3683e292aa398dc40f5188bc4f0b36c8916ac552308robertphillips@google.com break; 3693e292aa398dc40f5188bc4f0b36c8916ac552308robertphillips@google.com case SkPath::kQuad_Verb: 3706b8dbb668f1f069270d35a47cfe98decd059c625robertphillips@google.com fSegmentMask |= SkPath::kQuad_SegmentMask; 3716b8dbb668f1f069270d35a47cfe98decd059c625robertphillips@google.com pCnt = 2; 3726b8dbb668f1f069270d35a47cfe98decd059c625robertphillips@google.com break; 3733e292aa398dc40f5188bc4f0b36c8916ac552308robertphillips@google.com case SkPath::kConic_Verb: 3746b8dbb668f1f069270d35a47cfe98decd059c625robertphillips@google.com fSegmentMask |= SkPath::kConic_SegmentMask; 3753e292aa398dc40f5188bc4f0b36c8916ac552308robertphillips@google.com pCnt = 2; 3763e292aa398dc40f5188bc4f0b36c8916ac552308robertphillips@google.com break; 3773e292aa398dc40f5188bc4f0b36c8916ac552308robertphillips@google.com case SkPath::kCubic_Verb: 3786b8dbb668f1f069270d35a47cfe98decd059c625robertphillips@google.com fSegmentMask |= SkPath::kCubic_SegmentMask; 3793e292aa398dc40f5188bc4f0b36c8916ac552308robertphillips@google.com pCnt = 3; 3803e292aa398dc40f5188bc4f0b36c8916ac552308robertphillips@google.com break; 3813e292aa398dc40f5188bc4f0b36c8916ac552308robertphillips@google.com case SkPath::kClose_Verb: 3823e292aa398dc40f5188bc4f0b36c8916ac552308robertphillips@google.com pCnt = 0; 383466310dbd3073add2ec934e336c30deaaf702eaerobertphillips@google.com dirtyAfterEdit = false; 3843e292aa398dc40f5188bc4f0b36c8916ac552308robertphillips@google.com break; 3853e292aa398dc40f5188bc4f0b36c8916ac552308robertphillips@google.com case SkPath::kDone_Verb: 3863e292aa398dc40f5188bc4f0b36c8916ac552308robertphillips@google.com SkDEBUGFAIL("growForVerb called for kDone"); 3873e292aa398dc40f5188bc4f0b36c8916ac552308robertphillips@google.com // fall through 3883e292aa398dc40f5188bc4f0b36c8916ac552308robertphillips@google.com default: 3893e292aa398dc40f5188bc4f0b36c8916ac552308robertphillips@google.com SkDEBUGFAIL("default is not reached"); 390466310dbd3073add2ec934e336c30deaaf702eaerobertphillips@google.com dirtyAfterEdit = false; 3913e292aa398dc40f5188bc4f0b36c8916ac552308robertphillips@google.com pCnt = 0; 3923e292aa398dc40f5188bc4f0b36c8916ac552308robertphillips@google.com } 3933e292aa398dc40f5188bc4f0b36c8916ac552308robertphillips@google.com size_t space = sizeof(uint8_t) + pCnt * sizeof (SkPoint); 3943e292aa398dc40f5188bc4f0b36c8916ac552308robertphillips@google.com this->makeSpace(space); 3953e292aa398dc40f5188bc4f0b36c8916ac552308robertphillips@google.com this->fVerbs[~fVerbCnt] = verb; 3963e292aa398dc40f5188bc4f0b36c8916ac552308robertphillips@google.com SkPoint* ret = fPoints + fPointCnt; 3973e292aa398dc40f5188bc4f0b36c8916ac552308robertphillips@google.com fVerbCnt += 1; 3983e292aa398dc40f5188bc4f0b36c8916ac552308robertphillips@google.com fPointCnt += pCnt; 3993e292aa398dc40f5188bc4f0b36c8916ac552308robertphillips@google.com fFreeSpace -= space; 4003e292aa398dc40f5188bc4f0b36c8916ac552308robertphillips@google.com fBoundsIsDirty = true; // this also invalidates fIsFinite 401466310dbd3073add2ec934e336c30deaaf702eaerobertphillips@google.com if (dirtyAfterEdit) { 402466310dbd3073add2ec934e336c30deaaf702eaerobertphillips@google.com fIsOval = false; 403466310dbd3073add2ec934e336c30deaaf702eaerobertphillips@google.com } 4046b8dbb668f1f069270d35a47cfe98decd059c625robertphillips@google.com 4056b8dbb668f1f069270d35a47cfe98decd059c625robertphillips@google.com if (SkPath::kConic_Verb == verb) { 4066b8dbb668f1f069270d35a47cfe98decd059c625robertphillips@google.com *fConicWeights.append() = weight; 4076b8dbb668f1f069270d35a47cfe98decd059c625robertphillips@google.com } 4086b8dbb668f1f069270d35a47cfe98decd059c625robertphillips@google.com 40903087072483378a43f7b3f7a47944614187275ebrobertphillips@google.com SkDEBUGCODE(this->validate();) 4103e292aa398dc40f5188bc4f0b36c8916ac552308robertphillips@google.com return ret; 4113e292aa398dc40f5188bc4f0b36c8916ac552308robertphillips@google.com} 4123e292aa398dc40f5188bc4f0b36c8916ac552308robertphillips@google.com 4131ab9f737f000e530f0c7713c8fad282f39e26efecommit-bot@chromium.orguint32_t SkPathRef::genID() const { 4143e292aa398dc40f5188bc4f0b36c8916ac552308robertphillips@google.com SkASSERT(!fEditorsAttached); 4151ab9f737f000e530f0c7713c8fad282f39e26efecommit-bot@chromium.org static const uint32_t kMask = (static_cast<int64_t>(1) << SkPath::kPathRefGenIDBitCnt) - 1; 4163e292aa398dc40f5188bc4f0b36c8916ac552308robertphillips@google.com if (!fGenerationID) { 4173e292aa398dc40f5188bc4f0b36c8916ac552308robertphillips@google.com if (0 == fPointCnt && 0 == fVerbCnt) { 4183e292aa398dc40f5188bc4f0b36c8916ac552308robertphillips@google.com fGenerationID = kEmptyGenID; 4193e292aa398dc40f5188bc4f0b36c8916ac552308robertphillips@google.com } else { 4203e292aa398dc40f5188bc4f0b36c8916ac552308robertphillips@google.com static int32_t gPathRefGenerationID; 4213e292aa398dc40f5188bc4f0b36c8916ac552308robertphillips@google.com // do a loop in case our global wraps around, as we never want to return a 0 or the 4223e292aa398dc40f5188bc4f0b36c8916ac552308robertphillips@google.com // empty ID 4233e292aa398dc40f5188bc4f0b36c8916ac552308robertphillips@google.com do { 4241ab9f737f000e530f0c7713c8fad282f39e26efecommit-bot@chromium.org fGenerationID = (sk_atomic_inc(&gPathRefGenerationID) + 1) & kMask; 4253e292aa398dc40f5188bc4f0b36c8916ac552308robertphillips@google.com } while (fGenerationID <= kEmptyGenID); 4263e292aa398dc40f5188bc4f0b36c8916ac552308robertphillips@google.com } 4273e292aa398dc40f5188bc4f0b36c8916ac552308robertphillips@google.com } 4283e292aa398dc40f5188bc4f0b36c8916ac552308robertphillips@google.com return fGenerationID; 4293e292aa398dc40f5188bc4f0b36c8916ac552308robertphillips@google.com} 4303e292aa398dc40f5188bc4f0b36c8916ac552308robertphillips@google.com 43103087072483378a43f7b3f7a47944614187275ebrobertphillips@google.com#ifdef SK_DEBUG 4323e292aa398dc40f5188bc4f0b36c8916ac552308robertphillips@google.comvoid SkPathRef::validate() const { 43303087072483378a43f7b3f7a47944614187275ebrobertphillips@google.com this->INHERITED::validate(); 4343e292aa398dc40f5188bc4f0b36c8916ac552308robertphillips@google.com SkASSERT(static_cast<ptrdiff_t>(fFreeSpace) >= 0); 4353e292aa398dc40f5188bc4f0b36c8916ac552308robertphillips@google.com SkASSERT(reinterpret_cast<intptr_t>(fVerbs) - reinterpret_cast<intptr_t>(fPoints) >= 0); 4363e292aa398dc40f5188bc4f0b36c8916ac552308robertphillips@google.com SkASSERT((NULL == fPoints) == (NULL == fVerbs)); 4373e292aa398dc40f5188bc4f0b36c8916ac552308robertphillips@google.com SkASSERT(!(NULL == fPoints && 0 != fFreeSpace)); 4383e292aa398dc40f5188bc4f0b36c8916ac552308robertphillips@google.com SkASSERT(!(NULL == fPoints && 0 != fFreeSpace)); 4393e292aa398dc40f5188bc4f0b36c8916ac552308robertphillips@google.com SkASSERT(!(NULL == fPoints && fPointCnt)); 4403e292aa398dc40f5188bc4f0b36c8916ac552308robertphillips@google.com SkASSERT(!(NULL == fVerbs && fVerbCnt)); 4413e292aa398dc40f5188bc4f0b36c8916ac552308robertphillips@google.com SkASSERT(this->currSize() == 4423e292aa398dc40f5188bc4f0b36c8916ac552308robertphillips@google.com fFreeSpace + sizeof(SkPoint) * fPointCnt + sizeof(uint8_t) * fVerbCnt); 4433e292aa398dc40f5188bc4f0b36c8916ac552308robertphillips@google.com 4440b544ae222aab1c5d9122a8dfe2800451b31d979mtklein if (!fBoundsIsDirty && !fBounds->isEmpty()) { 4453e292aa398dc40f5188bc4f0b36c8916ac552308robertphillips@google.com bool isFinite = true; 4463e292aa398dc40f5188bc4f0b36c8916ac552308robertphillips@google.com for (int i = 0; i < fPointCnt; ++i) { 447a1a097ee814d05a92487d85db8ad02e1d852fd6fcommit-bot@chromium.org SkASSERT(!fPoints[i].isFinite() || ( 4480b544ae222aab1c5d9122a8dfe2800451b31d979mtklein fBounds->fLeft - fPoints[i].fX < SK_ScalarNearlyZero && 4490b544ae222aab1c5d9122a8dfe2800451b31d979mtklein fPoints[i].fX - fBounds->fRight < SK_ScalarNearlyZero && 4500b544ae222aab1c5d9122a8dfe2800451b31d979mtklein fBounds->fTop - fPoints[i].fY < SK_ScalarNearlyZero && 4510b544ae222aab1c5d9122a8dfe2800451b31d979mtklein fPoints[i].fY - fBounds->fBottom < SK_ScalarNearlyZero)); 4523e292aa398dc40f5188bc4f0b36c8916ac552308robertphillips@google.com if (!fPoints[i].isFinite()) { 4533e292aa398dc40f5188bc4f0b36c8916ac552308robertphillips@google.com isFinite = false; 4543e292aa398dc40f5188bc4f0b36c8916ac552308robertphillips@google.com } 4553e292aa398dc40f5188bc4f0b36c8916ac552308robertphillips@google.com } 4563e292aa398dc40f5188bc4f0b36c8916ac552308robertphillips@google.com SkASSERT(SkToBool(fIsFinite) == isFinite); 4573e292aa398dc40f5188bc4f0b36c8916ac552308robertphillips@google.com } 4586b8dbb668f1f069270d35a47cfe98decd059c625robertphillips@google.com 4596b8dbb668f1f069270d35a47cfe98decd059c625robertphillips@google.com#ifdef SK_DEBUG_PATH 4606b8dbb668f1f069270d35a47cfe98decd059c625robertphillips@google.com uint32_t mask = 0; 4616b8dbb668f1f069270d35a47cfe98decd059c625robertphillips@google.com for (int i = 0; i < fVerbCnt; ++i) { 4626b8dbb668f1f069270d35a47cfe98decd059c625robertphillips@google.com switch (fVerbs[~i]) { 4636b8dbb668f1f069270d35a47cfe98decd059c625robertphillips@google.com case SkPath::kMove_Verb: 4646b8dbb668f1f069270d35a47cfe98decd059c625robertphillips@google.com break; 4656b8dbb668f1f069270d35a47cfe98decd059c625robertphillips@google.com case SkPath::kLine_Verb: 4666b8dbb668f1f069270d35a47cfe98decd059c625robertphillips@google.com mask |= SkPath::kLine_SegmentMask; 4676b8dbb668f1f069270d35a47cfe98decd059c625robertphillips@google.com break; 4686b8dbb668f1f069270d35a47cfe98decd059c625robertphillips@google.com case SkPath::kQuad_Verb: 4696b8dbb668f1f069270d35a47cfe98decd059c625robertphillips@google.com mask |= SkPath::kQuad_SegmentMask; 4706b8dbb668f1f069270d35a47cfe98decd059c625robertphillips@google.com break; 4716b8dbb668f1f069270d35a47cfe98decd059c625robertphillips@google.com case SkPath::kConic_Verb: 4726b8dbb668f1f069270d35a47cfe98decd059c625robertphillips@google.com mask |= SkPath::kConic_SegmentMask; 4736b8dbb668f1f069270d35a47cfe98decd059c625robertphillips@google.com break; 4746b8dbb668f1f069270d35a47cfe98decd059c625robertphillips@google.com case SkPath::kCubic_Verb: 4756b8dbb668f1f069270d35a47cfe98decd059c625robertphillips@google.com mask |= SkPath::kCubic_SegmentMask; 4766b8dbb668f1f069270d35a47cfe98decd059c625robertphillips@google.com break; 4776b8dbb668f1f069270d35a47cfe98decd059c625robertphillips@google.com case SkPath::kClose_Verb: 4786b8dbb668f1f069270d35a47cfe98decd059c625robertphillips@google.com break; 4796b8dbb668f1f069270d35a47cfe98decd059c625robertphillips@google.com case SkPath::kDone_Verb: 4806b8dbb668f1f069270d35a47cfe98decd059c625robertphillips@google.com SkDEBUGFAIL("Done verb shouldn't be recorded."); 4816b8dbb668f1f069270d35a47cfe98decd059c625robertphillips@google.com break; 4826b8dbb668f1f069270d35a47cfe98decd059c625robertphillips@google.com default: 4836b8dbb668f1f069270d35a47cfe98decd059c625robertphillips@google.com SkDEBUGFAIL("Unknown Verb"); 4846b8dbb668f1f069270d35a47cfe98decd059c625robertphillips@google.com break; 4856b8dbb668f1f069270d35a47cfe98decd059c625robertphillips@google.com } 4866b8dbb668f1f069270d35a47cfe98decd059c625robertphillips@google.com } 4876b8dbb668f1f069270d35a47cfe98decd059c625robertphillips@google.com SkASSERT(mask == fSegmentMask); 4886b8dbb668f1f069270d35a47cfe98decd059c625robertphillips@google.com#endif // SK_DEBUG_PATH 4893e292aa398dc40f5188bc4f0b36c8916ac552308robertphillips@google.com} 49003087072483378a43f7b3f7a47944614187275ebrobertphillips@google.com#endif 491