Thu, 22 Jan 2015 13:21:57 +0100
Incorporate requested changes from Mozilla in review:
https://bugzilla.mozilla.org/show_bug.cgi?id=1123480#c6
1 /* -*- Mode: C++; tab-width: 2; indent-tabs-mode: nil; c-basic-offset: 2 -*- */
2 /* This Source Code Form is subject to the terms of the Mozilla Public
3 * License, v. 2.0. If a copy of the MPL was not distributed with this
4 * file, You can obtain one at http://mozilla.org/MPL/2.0/. */
6 /*
7 * implementation of interface that allows layout-debug extension access
8 * to some internals of layout
9 */
11 #include "nsILayoutDebugger.h"
12 #include "nsFrame.h"
13 #include "nsDisplayList.h"
14 #include "FrameLayerBuilder.h"
15 #include "nsPrintfCString.h"
17 #include <stdio.h>
19 using namespace mozilla;
20 using namespace mozilla::layers;
22 #ifdef DEBUG
23 class nsLayoutDebugger : public nsILayoutDebugger {
24 public:
25 nsLayoutDebugger();
26 virtual ~nsLayoutDebugger();
28 NS_DECL_ISUPPORTS
30 NS_IMETHOD SetShowFrameBorders(bool aEnable) MOZ_OVERRIDE;
32 NS_IMETHOD GetShowFrameBorders(bool* aResult) MOZ_OVERRIDE;
34 NS_IMETHOD SetShowEventTargetFrameBorder(bool aEnable) MOZ_OVERRIDE;
36 NS_IMETHOD GetShowEventTargetFrameBorder(bool* aResult) MOZ_OVERRIDE;
38 NS_IMETHOD GetContentSize(nsIDocument* aDocument,
39 int32_t* aSizeInBytesResult) MOZ_OVERRIDE;
41 NS_IMETHOD GetFrameSize(nsIPresShell* aPresentation,
42 int32_t* aSizeInBytesResult) MOZ_OVERRIDE;
44 NS_IMETHOD GetStyleSize(nsIPresShell* aPresentation,
45 int32_t* aSizeInBytesResult) MOZ_OVERRIDE;
47 };
49 nsresult
50 NS_NewLayoutDebugger(nsILayoutDebugger** aResult)
51 {
52 NS_PRECONDITION(aResult, "null OUT ptr");
53 if (!aResult) {
54 return NS_ERROR_NULL_POINTER;
55 }
56 nsLayoutDebugger* it = new nsLayoutDebugger();
57 return it->QueryInterface(NS_GET_IID(nsILayoutDebugger), (void**)aResult);
58 }
60 nsLayoutDebugger::nsLayoutDebugger()
61 {
62 }
64 nsLayoutDebugger::~nsLayoutDebugger()
65 {
66 }
68 NS_IMPL_ISUPPORTS(nsLayoutDebugger, nsILayoutDebugger)
70 NS_IMETHODIMP
71 nsLayoutDebugger::SetShowFrameBorders(bool aEnable)
72 {
73 nsFrame::ShowFrameBorders(aEnable);
74 return NS_OK;
75 }
77 NS_IMETHODIMP
78 nsLayoutDebugger::GetShowFrameBorders(bool* aResult)
79 {
80 *aResult = nsFrame::GetShowFrameBorders();
81 return NS_OK;
82 }
84 NS_IMETHODIMP
85 nsLayoutDebugger::SetShowEventTargetFrameBorder(bool aEnable)
86 {
87 nsFrame::ShowEventTargetFrameBorder(aEnable);
88 return NS_OK;
89 }
91 NS_IMETHODIMP
92 nsLayoutDebugger::GetShowEventTargetFrameBorder(bool* aResult)
93 {
94 *aResult = nsFrame::GetShowEventTargetFrameBorder();
95 return NS_OK;
96 }
98 NS_IMETHODIMP
99 nsLayoutDebugger::GetContentSize(nsIDocument* aDocument,
100 int32_t* aSizeInBytesResult)
101 {
102 *aSizeInBytesResult = 0;
103 return NS_ERROR_FAILURE;
104 }
106 NS_IMETHODIMP
107 nsLayoutDebugger::GetFrameSize(nsIPresShell* aPresentation,
108 int32_t* aSizeInBytesResult)
109 {
110 *aSizeInBytesResult = 0;
111 return NS_ERROR_FAILURE;
112 }
114 NS_IMETHODIMP
115 nsLayoutDebugger::GetStyleSize(nsIPresShell* aPresentation,
116 int32_t* aSizeInBytesResult)
117 {
118 *aSizeInBytesResult = 0;
119 return NS_ERROR_FAILURE;
120 }
121 #endif
123 #ifdef MOZ_DUMP_PAINTING
124 static void
125 PrintDisplayListTo(nsDisplayListBuilder* aBuilder, const nsDisplayList& aList,
126 FILE* aOutput, uint32_t aIndent, bool aDumpHtml);
128 static void
129 PrintDisplayItemTo(nsDisplayListBuilder* aBuilder, nsDisplayItem* aItem,
130 FILE* aOutput, uint32_t aIndent, bool aDumpSublist, bool aDumpHtml)
131 {
132 nsCString str;
133 if (!aDumpHtml) {
134 for (uint32_t indent = 0; indent < aIndent; indent++) {
135 str += " ";
136 }
137 }
138 nsIFrame* f = aItem->Frame();
139 nsAutoString fName;
140 #ifdef DEBUG_FRAME_DUMP
141 f->GetFrameName(fName);
142 #endif
143 bool snap;
144 nsRect rect = aItem->GetBounds(aBuilder, &snap);
145 nscolor color;
146 nsRect vis = aItem->GetVisibleRect();
147 nsRect component = aItem->GetComponentAlphaBounds(aBuilder);
148 nsDisplayList* list = aItem->GetChildren();
149 const DisplayItemClip& clip = aItem->GetClip();
150 nsRegion opaque;
151 if (!list || list->DidComputeVisibility()) {
152 opaque = aItem->GetOpaqueRegion(aBuilder, &snap);
153 }
154 if (aDumpHtml && aItem->Painted()) {
155 nsCString string(aItem->Name());
156 string.Append("-");
157 string.AppendInt((uint64_t)aItem);
158 str += nsPrintfCString("<a href=\"javascript:ViewImage('%s')\">", string.BeginReading());
159 }
160 str += nsPrintfCString("%s %p(%s) bounds(%d,%d,%d,%d) visible(%d,%d,%d,%d) componentAlpha(%d,%d,%d,%d) clip(%s) %s",
161 aItem->Name(), (void*)f, NS_ConvertUTF16toUTF8(fName).get(),
162 rect.x, rect.y, rect.width, rect.height,
163 vis.x, vis.y, vis.width, vis.height,
164 component.x, component.y, component.width, component.height,
165 clip.ToString().get(),
166 aItem->IsUniform(aBuilder, &color) ? " uniform" : "");
167 nsRegionRectIterator iter(opaque);
168 for (const nsRect* r = iter.Next(); r; r = iter.Next()) {
169 str += nsPrintfCString(" (opaque %d,%d,%d,%d)", r->x, r->y, r->width, r->height);
170 }
171 aItem->WriteDebugInfo(str);
172 if (aDumpHtml && aItem->Painted()) {
173 str += "</a>";
174 }
175 uint32_t key = aItem->GetPerFrameKey();
176 Layer* layer = mozilla::FrameLayerBuilder::GetDebugOldLayerFor(f, key);
177 if (layer) {
178 if (aDumpHtml) {
179 str += nsPrintfCString(" <a href=\"#%p\">layer=%p</a>", layer, layer);
180 } else {
181 str += nsPrintfCString(" layer=%p", layer);
182 }
183 }
184 if (aItem->GetType() == nsDisplayItem::TYPE_SVG_EFFECTS) {
185 (static_cast<nsDisplaySVGEffects*>(aItem))->PrintEffects(str);
186 }
187 fprintf_stderr(aOutput, "%s\n", str.get());
188 if (aDumpSublist && list) {
189 PrintDisplayListTo(aBuilder, *list, aOutput, aIndent+1, aDumpHtml);
190 }
191 }
193 static void
194 PrintDisplayListTo(nsDisplayListBuilder* aBuilder, const nsDisplayList& aList,
195 FILE* aOutput, uint32_t aIndent, bool aDumpHtml)
196 {
197 if (aDumpHtml) {
198 fprintf_stderr(aOutput, "<ul>");
199 }
201 for (nsDisplayItem* i = aList.GetBottom(); i != nullptr; i = i->GetAbove()) {
202 if (aDumpHtml) {
203 fprintf_stderr(aOutput, "<li>");
204 }
205 PrintDisplayItemTo(aBuilder, i, aOutput, aIndent, true, aDumpHtml);
206 if (aDumpHtml) {
207 fprintf_stderr(aOutput, "</li>");
208 }
209 }
211 if (aDumpHtml) {
212 fprintf_stderr(aOutput, "</ul>");
213 }
214 }
216 void
217 nsFrame::PrintDisplayItem(nsDisplayListBuilder* aBuilder,
218 nsDisplayItem* aItem,
219 FILE* aFile,
220 bool aDumpSublist,
221 bool aDumpHtml)
222 {
223 PrintDisplayItemTo(aBuilder, aItem, aFile, 0, aDumpSublist, aDumpHtml);
224 }
226 void
227 nsFrame::PrintDisplayList(nsDisplayListBuilder* aBuilder,
228 const nsDisplayList& aList,
229 FILE* aFile,
230 bool aDumpHtml)
231 {
232 PrintDisplayListTo(aBuilder, aList, aFile, 0, aDumpHtml);
233 }
235 static void
236 PrintDisplayListSetItem(nsDisplayListBuilder* aBuilder,
237 const char* aItemName,
238 const nsDisplayList& aList,
239 FILE* aFile,
240 bool aDumpHtml)
241 {
242 if (aDumpHtml) {
243 fprintf_stderr(aFile, "<li>");
244 }
245 fprintf_stderr(aFile, "%s", aItemName);
246 PrintDisplayListTo(aBuilder, aList, aFile, 0, aDumpHtml);
247 if (aDumpHtml) {
248 fprintf_stderr(aFile, "</li>");
249 }
250 }
252 void
253 nsFrame::PrintDisplayListSet(nsDisplayListBuilder* aBuilder,
254 const nsDisplayListSet& aSet,
255 FILE *aFile,
256 bool aDumpHtml)
257 {
258 if (aDumpHtml) {
259 fprintf_stderr(aFile, "<ul>");
260 }
261 PrintDisplayListSetItem(aBuilder, "[BorderBackground]", *(aSet.BorderBackground()), aFile, aDumpHtml);
262 PrintDisplayListSetItem(aBuilder, "[BlockBorderBackgrounds]", *(aSet.BlockBorderBackgrounds()), aFile, aDumpHtml);
263 PrintDisplayListSetItem(aBuilder, "[Floats]", *(aSet.Floats()), aFile, aDumpHtml);
264 PrintDisplayListSetItem(aBuilder, "[PositionedDescendants]", *(aSet.PositionedDescendants()), aFile, aDumpHtml);
265 PrintDisplayListSetItem(aBuilder, "[Outlines]", *(aSet.Outlines()), aFile, aDumpHtml);
266 PrintDisplayListSetItem(aBuilder, "[Content]", *(aSet.Content()), aFile, aDumpHtml);
267 if (aDumpHtml) {
268 fprintf_stderr(aFile, "</ul>");
269 }
270 }
272 #endif