blob: 96e5861e1e39247e60e764c842c9f668f867058e [file] [log] [blame]
// Copyright 2016 The Cobalt Authors. 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/clear_rect_node.h"
#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/lottie_node.h"
#include "cobalt/render_tree/matrix_transform_3d_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(ClearRectNode* clear_rect) override;
void Visit(CompositionNode* composition) override;
void Visit(FilterNode* text) override;
void Visit(ImageNode* image) override;
void Visit(LottieNode* lottie) override;
void Visit(MatrixTransform3DNode* transform) 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(ClearRectNode* clear_rect) {
AddNamedNodeString(clear_rect, "ClearRectNode");
result_ << "\n";
}
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(LottieNode* lottie) {
AddNamedNodeString(lottie, "LottieNode");
result_ << "\n";
}
void DebugTreePrinter::Visit(MatrixTransform3DNode* transform) {
AddNamedNodeString(transform, "MatrixTransform3DNode");
result_ << "\n";
ScopedIncrement scoped_increment(&indent_);
transform->data().source->Accept(this);
}
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";
}
namespace {
class BrushPrinterVisitor : public render_tree::BrushVisitor {
public:
BrushPrinterVisitor() {}
void Visit(
const cobalt::render_tree::SolidColorBrush* solid_color_brush) override {
brush_type_ = "(SolidColorBrush)";
}
void Visit(const cobalt::render_tree::LinearGradientBrush*
linear_gradient_brush) override {
brush_type_ = "(LinearGradientBrush)";
}
void Visit(const cobalt::render_tree::RadialGradientBrush*
radial_gradient_brush) override {
brush_type_ = "(RadialGradientBrush)";
}
const std::string& brush_type() const { return brush_type_; }
private:
std::string brush_type_;
};
} // namespace
void DebugTreePrinter::Visit(RectNode* rect) {
AddNamedNodeString(rect, "RectNode ");
if (rect->data().background_brush) {
BrushPrinterVisitor printer_brush_visitor;
rect->data().background_brush->Accept(&printer_brush_visitor);
result_ << printer_brush_visitor.brush_type();
}
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