blob: 6fdc38e94e276ba573e72b2e455ab8cede81de8c [file] [log] [blame]
/*
* Copyright 2016 Google Inc. All Rights Reserved.
*
* Licensed under the Apache License, Version 2.0 (the "License");
* you may not use this file except in compliance with the License.
* You may obtain a copy of the License at
*
* http://www.apache.org/licenses/LICENSE-2.0
*
* Unless required by applicable law or agreed to in writing, software
* distributed under the License is distributed on an "AS IS" BASIS,
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
* See the License for the specific language governing permissions and
* limitations under the License.
*/
#include "cobalt/render_tree/dump_render_tree_to_string.h"
#include <sstream>
#include "cobalt/render_tree/composition_node.h"
#include "cobalt/render_tree/filter_node.h"
#include "cobalt/render_tree/image_node.h"
#include "cobalt/render_tree/matrix_transform_node.h"
#include "cobalt/render_tree/node_visitor.h"
#include "cobalt/render_tree/punch_through_video_node.h"
#include "cobalt/render_tree/rect_node.h"
#include "cobalt/render_tree/rect_shadow_node.h"
#include "cobalt/render_tree/text_node.h"
namespace cobalt {
namespace render_tree {
namespace animations {
class AnimateNode;
} // namespace animations
namespace {
// A render tree visitor that accumulates node dumps to text within a
// std::ostringstream object.
class DebugTreePrinter : public NodeVisitor {
public:
DebugTreePrinter() : indent_(0) {}
void Visit(animations::AnimateNode* /* animate */) OVERRIDE { NOTREACHED(); }
void Visit(CompositionNode* composition) OVERRIDE;
void Visit(FilterNode* text) OVERRIDE;
void Visit(ImageNode* image) OVERRIDE;
void Visit(MatrixTransformNode* transform) OVERRIDE;
void Visit(PunchThroughVideoNode* punch_through) OVERRIDE;
void Visit(RectNode* rect) OVERRIDE;
void Visit(RectShadowNode* rect) OVERRIDE;
void Visit(TextNode* text) OVERRIDE;
// Returns the final result after visitation is complete.
const std::string Result() const { return result_.str(); }
private:
// Adds an appropriate number of indent characters according to |indent_|.
void AddIndentString();
// Adds general render tree node information (e.g. bounds) for a given node.
void AddNodeInfoString(Node* node);
// A simple function that most of the time dumps all the generic information
// about a given node.
void AddNamedNodeString(Node* node, const char* type);
// Helper function to increment and decrement |indent_|.
class ScopedIncrement {
public:
explicit ScopedIncrement(int* value) : value_(value) { ++(*value_); }
~ScopedIncrement() { --(*value_); }
private:
int* value_;
};
// The results object in which we accumulate our string representation.
std::ostringstream result_;
// Our current indent when printing lines of information.
int indent_;
};
void DebugTreePrinter::Visit(CompositionNode* composition) {
AddNamedNodeString(composition, "CompositionNode");
result_ << "\n";
ScopedIncrement scoped_increment(&indent_);
const render_tree::CompositionNode::Children& children =
composition->data().children();
for (render_tree::CompositionNode::Children::const_iterator iter =
children.begin();
iter != children.end(); ++iter) {
(*iter)->Accept(this);
}
}
void DebugTreePrinter::Visit(FilterNode* filter) {
AddNamedNodeString(filter, "FilterNode");
// Add some additional information to the FilterNode output to indicate which
// filters were in effect.
result_ << " { Filters: (";
if (filter->data().opacity_filter) {
result_ << "opacity, ";
}
if (filter->data().viewport_filter) {
result_ << "viewport, ";
}
if (filter->data().blur_filter) {
result_ << "blur_filter, ";
}
result_ << ") }\n";
ScopedIncrement scoped_increment(&indent_);
filter->data().source->Accept(this);
}
void DebugTreePrinter::Visit(ImageNode* image) {
AddNamedNodeString(image, "ImageNode");
result_ << "\n";
}
void DebugTreePrinter::Visit(MatrixTransformNode* transform) {
AddNamedNodeString(transform, "MatrixTransformNode");
result_ << "\n";
ScopedIncrement scoped_increment(&indent_);
transform->data().source->Accept(this);
}
void DebugTreePrinter::Visit(PunchThroughVideoNode* punch_through) {
AddNamedNodeString(punch_through, "PunchThroughVideoNode");
result_ << "\n";
}
void DebugTreePrinter::Visit(RectNode* rect) {
AddNamedNodeString(rect, "RectNode");
result_ << "\n";
}
void DebugTreePrinter::Visit(RectShadowNode* rect) {
AddNamedNodeString(rect, "RectShadowNode");
result_ << "\n";
}
void DebugTreePrinter::Visit(TextNode* text) {
AddNamedNodeString(text, "TextNode");
result_ << "\n";
}
void DebugTreePrinter::AddIndentString() {
result_ << std::string(static_cast<size_t>(indent_) * 2, ' ');
}
void DebugTreePrinter::AddNodeInfoString(Node* node) {
const math::RectF bounds = node->GetBounds();
result_ << "{ Bounds: (" << bounds.x() << ", " << bounds.y() << ", "
<< bounds.width() << ", " << bounds.height() << ") }";
}
void DebugTreePrinter::AddNamedNodeString(Node* node, const char* type_name) {
AddIndentString();
result_ << type_name << " ";
AddNodeInfoString(node);
}
} // namespace
std::string DumpRenderTreeToString(render_tree::Node* node) {
DebugTreePrinter tree_printer;
node->Accept(&tree_printer);
return tree_printer.Result();
}
} // namespace render_tree
} // namespace cobalt