void SkTileGrid::insert(void* data, const SkRect& fbounds, bool) { SkASSERT(!fbounds.isEmpty()); SkIRect dilatedBounds; if (fbounds.isLargest()) { // Dilating the largest SkIRect will overflow. Other nearly-largest rects may overflow too, // but we don't make active use of them like we do the largest. dilatedBounds.setLargest(); } else { fbounds.roundOut(&dilatedBounds); dilatedBounds.outset(fInfo.fMargin.width(), fInfo.fMargin.height()); dilatedBounds.offset(fInfo.fOffset); } const SkIRect gridBounds = { 0, 0, fInfo.fTileInterval.width() * fXTiles, fInfo.fTileInterval.height() * fYTiles }; if (!SkIRect::Intersects(dilatedBounds, gridBounds)) { return; } // Note: SkIRects are non-inclusive of the right() column and bottom() row, // hence the "-1"s in the computations of maxX and maxY. int minX = SkMax32(0, SkMin32(dilatedBounds.left() / fInfo.fTileInterval.width(), fXTiles - 1)); int minY = SkMax32(0, SkMin32(dilatedBounds.top() / fInfo.fTileInterval.height(), fYTiles - 1)); int maxX = SkMax32(0, SkMin32((dilatedBounds.right() - 1) / fInfo.fTileInterval.width(), fXTiles - 1)); int maxY = SkMax32(0, SkMin32((dilatedBounds.bottom() - 1) / fInfo.fTileInterval.height(), fYTiles - 1)); Entry entry = { fCount++, data }; for (int y = minY; y <= maxY; y++) { for (int x = minX; x <= maxX; x++) { fTiles[y * fXTiles + x].push(entry); } } }
void SkRTree::insert(void* data, const SkRect& fbounds, bool defer) { SkIRect bounds; if (fbounds.isLargest()) { bounds.setLargest(); } else { fbounds.roundOut(&bounds); } this->validate(); if (bounds.isEmpty()) { SkASSERT(false); return; } Branch newBranch; newBranch.fBounds = bounds; newBranch.fChild.data = data; if (this->isEmpty()) { // since a bulk-load into an existing tree is as of yet unimplemented (and arguably not // of vital importance right now), we only batch up inserts if the tree is empty. if (defer) { fDeferredInserts.push(newBranch); return; } else { fRoot.fChild.subtree = allocateNode(0); fRoot.fChild.subtree->fNumChildren = 0; } } Branch* newSibling = insert(fRoot.fChild.subtree, &newBranch); fRoot.fBounds = this->computeBounds(fRoot.fChild.subtree); if (NULL != newSibling) { Node* oldRoot = fRoot.fChild.subtree; Node* newRoot = this->allocateNode(oldRoot->fLevel + 1); newRoot->fNumChildren = 2; *newRoot->child(0) = fRoot; *newRoot->child(1) = *newSibling; fRoot.fChild.subtree = newRoot; fRoot.fBounds = this->computeBounds(fRoot.fChild.subtree); } ++fCount; this->validate(); }