diff options
Diffstat (limited to 'webkit/glue/stacking_order_iterator.cc')
-rwxr-xr-x | webkit/glue/stacking_order_iterator.cc | 137 |
1 files changed, 137 insertions, 0 deletions
diff --git a/webkit/glue/stacking_order_iterator.cc b/webkit/glue/stacking_order_iterator.cc new file mode 100755 index 0000000..b726a8a --- /dev/null +++ b/webkit/glue/stacking_order_iterator.cc @@ -0,0 +1,137 @@ +// Copyright (c) 2006-2008 The Chromium Authors. All rights reserved. +// Use of this source code is governed by a BSD-style license that can be +// found in the LICENSE file. + +#include "config.h" + +#pragma warning(push, 0) +#include "RenderLayer.h" +#include "RenderObject.h" +#pragma warning(pop) +#undef LOG + +#include "webkit/glue/stacking_order_iterator.h" + +// +// RenderLayerIterator +// + +RenderLayerIterator::RenderLayerIterator() { +} + +void RenderLayerIterator::Reset(WebCore::RenderLayer* rl) { + if (rl) { + context_stack_.push_back(Context(rl)); + } +} + +WebCore::RenderLayer* RenderLayerIterator::Next() { + while (context_stack_.size()) { + Context* ctx = &(context_stack_.back()); + if (ctx->HasMoreNeg()) { + context_stack_.push_back(ctx->NextNeg()); + } else if (ctx->HasSelf()) { + // Emit self. + return ctx->NextSelf(); + } else if (ctx->HasMoreOverflow()) { + context_stack_.push_back(ctx->NextOverflow()); + } else if (ctx->HasMorePos()) { + context_stack_.push_back(ctx->NextPos()); + } else { + // Nothing left in this context. Pop. + context_stack_.pop_back(); + } + } + return NULL; +} + +RenderLayerIterator::Context::Context(WebCore::RenderLayer* layer) + : layer_(layer), + next_neg_(0), + next_self_(0), + next_overflow_(0), + next_pos_(0) { + ASSERT(layer_); + layer_->updateZOrderLists(); + layer_->updateOverflowList(); +} + +bool RenderLayerIterator::Context::HasMoreNeg() { + return layer_->negZOrderList() && + next_neg_ < layer_->negZOrderList()->size(); +} + +RenderLayerIterator::Context RenderLayerIterator::Context::NextNeg() { + ASSERT(HasMoreNeg()); + return Context(layer_->negZOrderList()->at(next_neg_++)); +} + +bool RenderLayerIterator::Context::HasSelf() { + return next_self_ < 1; +} + +WebCore::RenderLayer* RenderLayerIterator::Context::NextSelf() { + ASSERT(HasSelf()); + next_self_ = 1; + return layer_; +} + +bool RenderLayerIterator::Context::HasMoreOverflow() { + return layer_->overflowList() && + next_overflow_ >= 0 && + next_overflow_ < layer_->overflowList()->size(); +} + +RenderLayerIterator::Context RenderLayerIterator::Context::NextOverflow() { + ASSERT(HasMoreOverflow()); + return Context(layer_->overflowList()->at(next_overflow_++)); +} + +bool RenderLayerIterator::Context::HasMorePos() { + return layer_->posZOrderList() && + next_pos_ < layer_->posZOrderList()->size(); +} + +RenderLayerIterator::Context RenderLayerIterator::Context::NextPos() { + ASSERT(HasMorePos()); + return Context(layer_->posZOrderList()->at(next_pos_++)); +} + +// +// StackingOrderIterator +// + +StackingOrderIterator::StackingOrderIterator() { + Reset(NULL); +} + +void StackingOrderIterator::Reset(WebCore::RenderLayer* rl) { + layer_iterator_.Reset(rl); + current_object_ = NULL; + current_layer_root_ = NULL; +} + +WebCore::RenderObject* StackingOrderIterator::Next() { + if (current_object_) { + // Get the next object inside the current layer. + current_object_ = current_object_->nextInPreOrder(current_layer_root_); + + // Skip any sub-layers we encounter along the way; they are + // visited (in the correct stacking order) by layer_iterator_. + while (current_object_ && current_object_->hasLayer()) { + current_object_ = current_object_-> + nextInPreOrderAfterChildren(current_layer_root_); + } + } + + if (!current_object_) { + // Start the next layer. + WebCore::RenderLayer* layer = layer_iterator_.Next(); + if (layer) { + current_object_ = layer->renderer(); + current_layer_root_ = current_object_; + } + // No more layers. + } + return current_object_; +} |