1/*
2 * Copyright (C) 2013 Google Inc. All rights reserved.
3 * Copyright (C) 2013 Samsung Electronics. All rights reserved.
4 *
5 * Redistribution and use in source and binary forms, with or without
6 * modification, are permitted provided that the following conditions are
7 * met:
8 *
9 *     * Redistributions of source code must retain the above copyright
10 * notice, this list of conditions and the following disclaimer.
11 *     * Redistributions in binary form must reproduce the above
12 * copyright notice, this list of conditions and the following disclaimer
13 * in the documentation and/or other materials provided with the
14 * distribution.
15 *     * Neither the name of Google Inc. nor the names of its
16 * contributors may be used to endorse or promote products derived from
17 * this software without specific prior written permission.
18 *
19 * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
20 * "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
21 * LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR
22 * A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT
23 * OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
24 * SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT
25 * LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
26 * DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
27 * THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
28 * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
29 * OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
30 */
31
32#include "config.h"
33#include "core/rendering/GraphicsContextAnnotator.h"
34
35#include "core/inspector/InspectorNodeIds.h"
36#include "core/rendering/PaintInfo.h"
37#include "core/rendering/RenderObject.h"
38#include "platform/graphics/GraphicsContextAnnotation.h"
39#include "wtf/text/StringBuilder.h"
40
41namespace {
42
43const char AnnotationKeyRendererName[]    = "RENDERER";
44const char AnnotationKeyPaintPhase[]      = "PHASE";
45const char AnnotationKeyElementId[]       = "ID";
46const char AnnotationKeyElementClass[]    = "CLASS";
47const char AnnotationKeyElementTag[]      = "TAG";
48const char AnnotationKeyInspectorNodeId[] = "INSPECTOR_ID";
49
50static const char* paintPhaseName(blink::PaintPhase phase)
51{
52    switch (phase) {
53    case blink::PaintPhaseBlockBackground:
54        return "BlockBackground";
55    case blink::PaintPhaseChildBlockBackground:
56        return "ChildBlockBackground";
57    case blink::PaintPhaseChildBlockBackgrounds:
58        return "ChildBlockBackgrounds";
59    case blink::PaintPhaseFloat:
60        return "Float";
61    case blink::PaintPhaseForeground:
62        return "Foreground";
63    case blink::PaintPhaseOutline:
64        return "Outline";
65    case blink::PaintPhaseChildOutlines:
66        return "ChildOutlines";
67    case blink::PaintPhaseSelfOutline:
68        return "SelfOutline";
69    case blink::PaintPhaseSelection:
70        return "Selection";
71    case blink::PaintPhaseCollapsedTableBorders:
72        return "CollapsedTableBorders";
73    case blink::PaintPhaseTextClip:
74        return "TextClip";
75    case blink::PaintPhaseMask:
76        return "Mask";
77    case blink::PaintPhaseClippingMask:
78        return "ClippingMask";
79    default:
80        ASSERT_NOT_REACHED();
81        return "<unknown>";
82    }
83}
84
85}
86
87namespace blink {
88
89void GraphicsContextAnnotator::annotate(const PaintInfo& paintInfo, const RenderObject* object)
90{
91    ASSERT(!m_context);
92
93    ASSERT(paintInfo.context);
94    ASSERT(object);
95
96    AnnotationList annotations;
97    AnnotationModeFlags mode = paintInfo.context->annotationMode();
98    Element* element = object->node() && object->node()->isElementNode() ? toElement(object->node()) : 0;
99
100    if (mode & AnnotateRendererName)
101        annotations.append(std::make_pair(AnnotationKeyRendererName, object->renderName()));
102
103    if (mode & AnnotatePaintPhase)
104        annotations.append(std::make_pair(AnnotationKeyPaintPhase, paintPhaseName(paintInfo.phase)));
105
106    if ((mode & AnnotateElementId) && element && element->hasID())
107        annotations.append(std::make_pair(AnnotationKeyElementId, element->getIdAttribute().string()));
108
109    if ((mode & AnnotateElementClass) && element && element->hasClass()) {
110        SpaceSplitString classes = element->classNames();
111        if (!classes.isNull() && classes.size() > 0) {
112            StringBuilder classBuilder;
113            for (size_t i = 0; i < classes.size(); ++i) {
114                if (i > 0)
115                    classBuilder.append(' ');
116                classBuilder.append(classes[i]);
117            }
118
119            annotations.append(std::make_pair(AnnotationKeyElementClass, classBuilder.toString()));
120        }
121    }
122
123    if ((mode & AnnotateElementTag) && element)
124        annotations.append(std::make_pair(AnnotationKeyElementTag, element->tagName()));
125
126    if (mode & AnnotateInspectorId) {
127        if (Node* ownerNode = object->generatingNode()) {
128            annotations.append(std::make_pair(AnnotationKeyInspectorNodeId,
129                String::number(InspectorNodeIds::idForNode(ownerNode))));
130        }
131    }
132
133    m_context = paintInfo.context;
134    m_context->beginAnnotation(annotations);
135}
136
137void GraphicsContextAnnotator::finishAnnotation()
138{
139    ASSERT(m_context);
140    m_context->endAnnotation();
141}
142
143} // namespace blink
144