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