Chromium Code Reviews
chromiumcodereview-hr@appspot.gserviceaccount.com (chromiumcodereview-hr) | Please choose your nickname with Settings | Help | Chromium Project | Gerrit Changes | Sign out
(5)

Side by Side Diff: third_party/WebKit/Source/core/editing/LayoutTreePrinter.cpp

Issue 1756763002: 2016-03-02T18:53:01 LayoutPosition Base URL: https://chromium.googlesource.com/chromium/src.git@master
Patch Set: 2016-04-25T19:02:18 Created 4 years, 8 months ago
Use n/p to move between diff chunks; N/P to move between comments. Draft comments are only viewable by you.
Jump to:
View unified diff | Download patch
OLDNEW
(Empty)
1 // Copyright 2016 The Chromium Authors. All rights reserved.
2 // Use of this source code is governed by a BSD-style license that can be
3 // found in the LICENSE file.
4
5 #include "core/editing/LayoutTreePrinter.h"
6
7 #include "core/editing/LayoutPosition.h"
8 #include "core/frame/FrameView.h"
9 #include "core/layout/LayoutBlock.h"
10 #include "core/layout/LayoutBox.h"
11 #include "core/layout/LayoutObject.h"
12 #include "core/layout/LayoutView.h"
13 #include "core/layout/api/LineLayoutAPIShim.h"
14 #include "core/layout/api/LineLayoutItem.h"
15 #include "core/layout/line/InlineTextBox.h"
16 #include "core/layout/line/LineBoxList.h"
17 #include "wtf/Allocator.h"
18 #include "wtf/Assertions.h"
19 #include "wtf/HexNumber.h"
20 #include "wtf/Noncopyable.h"
21 #include "wtf/text/StringBuilder.h"
22
23 #ifndef NDEBUG
24 #include <iostream> // NOLINT
25
26 namespace blink {
27
28 namespace {
29 struct LayoutTreeAsText {
30 const InlineBox* inlineBox;
31 const LayoutObject* layoutObject;
32
33 explicit LayoutTreeAsText(const InlineBox& passedInlineBox)
34 : inlineBox(&passedInlineBox)
35 , layoutObject(nullptr)
36 {
37 }
38
39 explicit LayoutTreeAsText(const LayoutObject& passedLayoutObject)
40 : inlineBox(nullptr)
41 , layoutObject(&passedLayoutObject)
42 {
43 }
44 };
45 } // namespace
46
47 class LayoutTreePrinter {
48 STACK_ALLOCATED();
49 WTF_MAKE_NONCOPYABLE(LayoutTreePrinter);
50 public:
51 LayoutTreePrinter(std::ostream*, const LayoutTreeAsText&);
52
53 static void print(const InlineBox*);
54 static void print(const LayoutObject*);
55 static void print(const LayoutPosition&);
56 void print();
57
58 private:
59 class ScopedIndent {
60 STACK_ALLOCATED();
61 WTF_MAKE_NONCOPYABLE(ScopedIndent);
62 public:
63 ScopedIndent(LayoutTreePrinter* Context, int amount)
64 : m_amount(amount)
65 , m_context(Context)
66 {
67 DCHECK_GE(m_amount, 1);
68 m_context->m_indentAmount += m_amount;
69 }
70
71 ~ScopedIndent()
72 {
73 DCHECK_GE(m_context->m_indentAmount, m_amount);
74 m_context->m_indentAmount -= m_amount;
75 }
76
77 private:
78 const int m_amount;
79 LayoutTreePrinter* const m_context;
80 };
81
82 void arrow() const;
83 void indent() const;
84 void visitInlineFlowBox(const InlineFlowBox&);
85 void visitLayoutObjct(const LayoutObject&);
86
87 int m_indentAmount = 0;
88 const InlineBox* const m_markedInlineBox;
89 const LayoutObject* const m_markedLayoutObject;
90 std::ostream* const m_stream;
91 };
92
93 namespace {
94
95 struct CodeUnitAsText {
96 UChar codeUnit;
97 explicit CodeUnitAsText(UChar passedCodeUnit)
98 : codeUnit(passedCodeUnit)
99 {
100 }
101 };
102
103 struct InlineBoxAsText {
104 const InlineBox* inlineBox;
105
106 explicit InlineBoxAsText(const InlineBox& passedInlineBox)
107 : inlineBox(&passedInlineBox)
108 {
109 }
110 };
111
112 struct LayoutObjectAsText {
113 const LayoutObject* layoutObject;
114
115 explicit LayoutObjectAsText(const LayoutObject& passedLayoutObject)
116 : layoutObject(&passedLayoutObject)
117 {
118 }
119 };
120
121 struct StringAsText {
122 const String* string;
123
124 explicit StringAsText(const String& passedString)
125 : string(&passedString)
126 {
127 }
128 };
129
130 struct NodeAsText {
131 const Node* node;
132
133 explicit NodeAsText(const Node& passedNode)
134 : node(&passedNode)
135 {
136 }
137 };
138
139 struct LayoutRectAsText {
140 const LayoutRect* layoutRect;
141
142 explicit LayoutRectAsText(const LayoutRect& passedLayoutRect)
143 : layoutRect(&passedLayoutRect)
144 {
145 }
146 };
147
148 // -- Printers
149 std::ostream& operator<<(std::ostream&, const CodeUnitAsText&);
150 std::ostream& operator<<(std::ostream&, const InlineBoxAsText&);
151 std::ostream& operator<<(std::ostream&, const LayoutObjectAsText&);
152 std::ostream& operator<<(std::ostream&, const LayoutRectAsText&);
153 std::ostream& operator<<(std::ostream&, const LayoutTreeAsText&);
154 std::ostream& operator<<(std::ostream&, const NodeAsText&);
155 std::ostream& operator<<(std::ostream&, const StringAsText&);
156
157 std::ostream& operator<<(std::ostream& ostream, const CodeUnitAsText& wrapper)
158 {
159 const UChar codeUnit = wrapper.codeUnit;
160 if (codeUnit == '\n')
161 return ostream << "\\n";
162 if (codeUnit == '\t')
163 return ostream << "\\t";
164 if (codeUnit == '"')
165 return ostream << "\\\"";
166 if (codeUnit == '\\')
167 return ostream << "\\\\";
168 if (codeUnit >= ' ' && codeUnit <= 0x7E)
169 return ostream << static_cast<char>(codeUnit);
170 StringBuilder builder;
171 appendUnsignedAsHexFixedSize(codeUnit, builder, 4);
172 return ostream << "\\u" << builder.toString().utf8().data();
173 }
174
175 std::ostream& operator<<(std::ostream& ostream, const LayoutRectAsText& wrapper)
176 {
177 const LayoutRect& rect = *wrapper.layoutRect;
178 return ostream << '(' << rect.x().toFloat() << ',' << rect.y().toFloat() << ")+" << rect.width().toFloat() << 'x' << rect.height().toFloat();
179 }
180
181 std::ostream& operator<<(std::ostream& ostream, const InlineBoxAsText& wrapper)
182 {
183 const InlineBox& inlineBox = *wrapper.inlineBox;
184 ostream << static_cast<const void*>(&inlineBox) << ' ' << inlineBox.boxName( );
185 if (Node* node = inlineBox.getLineLayoutItem().node()) {
186 if (!node->isTextNode())
187 ostream << ' ' << node->debugName().utf8().data();
188 } else {
189 ostream << " (anonymous)";
190 }
191 if (inlineBox.isInlineTextBox()) {
192 const InlineTextBox& textBox = toInlineTextBox(inlineBox);
193 ostream << " " << StringAsText(textBox.text()) << " start=" << textBox.s tart() << " end=" << textBox.end();
194 } else if (inlineBox.isInlineFlowBox()) {
195 ostream << " frameRect=" << LayoutRectAsText(toInlineFlowBox(inlineBox). frameRect());
196 }
197 return ostream << " bidiLevel=" << static_cast<int>(inlineBox.bidiLevel());
198 }
199
200 std::ostream& operator<<(std::ostream& ostream, const LayoutObjectAsText& wrappe r)
201 {
202 const LayoutObject& layoutObject = *wrapper.layoutObject;
203 ostream << static_cast<const void*>(&layoutObject) << ' ' << layoutObject.na me();
204 if (Node* node = layoutObject.node()) {
205 ostream << " {" << NodeAsText(*node) << '}';
206 if (node->hasEditableStyle())
207 ostream << " (editable)";
208 } else {
209 ostream << " (anonymous)";
210 }
211 if (layoutObject.isBox())
212 ostream << ' ' << LayoutRectAsText(toLayoutBox(layoutObject).frameRect( ));
213 return ostream;
214 }
215
216 std::ostream& operator<<(std::ostream& ostream, const LayoutTreeAsText& wrapper)
217 {
218 LayoutTreePrinter(&ostream, wrapper).print();
219 return ostream;
220 }
221
222 std::ostream& operator<<(std::ostream& ostream, const NodeAsText& wrapper)
223 {
224 const Node& node = *wrapper.node;
225 if (node.isTextNode())
226 ostream << StringAsText(toText(node).data());
227 else
228 ostream << node.debugName().utf8().data();
229 return ostream;
230 }
231
232 std::ostream& operator<<(std::ostream& ostream, const StringAsText& wrapper)
233 {
234 const String& string = *wrapper.string;
235 const int kMaxChars = 40;
236 ostream << '"';
237 if (string.is8Bit()) {
238 const LChar* const start = string.characters8();
239 const LChar* const end = start + string.length();
240 const LChar* const middle = std::min(start + kMaxChars / 2, end);
241 for (const LChar* runner = start; runner < middle; ++runner)
242 ostream << CodeUnitAsText(*runner);
243 if (end != middle)
244 ostream << " ... ";
245 for (const LChar* runner = middle; runner < end; ++runner)
246 ostream << CodeUnitAsText(*runner);
247 } else {
248 const UChar* const start = string.characters16();
249 const UChar* const end = start + string.length();
250 const UChar* const middle = std::min(start + kMaxChars / 2, end);
251 for (const UChar* runner = start; runner < middle; ++runner)
252 ostream << CodeUnitAsText(*runner);
253 if (end != middle)
254 ostream << " ... ";
255 for (const UChar* runner = middle; runner < end; ++runner)
256 ostream << CodeUnitAsText(*runner);
257 }
258 return ostream << '"';
259 }
260
261 } // namespace
262
263 // -- LayoutTreePrinter
264 LayoutTreePrinter::LayoutTreePrinter(std::ostream* stream, const LayoutTreeAsTex t& wrapper)
265 : m_markedInlineBox(wrapper.inlineBox)
266 , m_markedLayoutObject(wrapper.layoutObject)
267 , m_stream(stream)
268 {
269 }
270
271 void LayoutTreePrinter::arrow() const
272 {
273 for (int index = 0; index < m_indentAmount; ++index)
274 *m_stream << "---";
275 *m_stream << '>';
276 }
277
278 void LayoutTreePrinter::print()
279 {
280 if (m_markedInlineBox) {
281 visitLayoutObjct(*m_markedInlineBox->getLineLayoutItem().document().layo utView());
282 return;
283 }
284 visitLayoutObjct(*m_markedLayoutObject->document().layoutView());
285 }
286
287 void LayoutTreePrinter::indent() const
288 {
289 for (int index = 0; index < m_indentAmount; ++index)
290 *m_stream << "| ";
291 *m_stream << '+';
292 }
293
294 void LayoutTreePrinter::visitInlineFlowBox(const InlineFlowBox& inlineFlowBox)
295 {
296 if (m_markedInlineBox == &inlineFlowBox)
297 arrow();
298 else
299 indent();
300 *m_stream << '-' << InlineBoxAsText(inlineFlowBox) << std::endl;
301 ScopedIndent lineScope(this, 1);
302 for (const InlineBox* child = inlineFlowBox.firstChild(); child; child = chi ld->nextOnLine()) {
303 if (m_markedInlineBox == child)
304 arrow();
305 else
306 indent();
307 *m_stream << InlineBoxAsText(*child) << std::endl;
308 if (child->isLeaf())
309 continue;
310 visitInlineFlowBox(*toInlineFlowBox(child));
311 }
312 }
313
314 void LayoutTreePrinter::visitLayoutObjct(const LayoutObject& layoutObject)
315 {
316 if (m_markedLayoutObject == &layoutObject)
317 arrow();
318 else
319 indent();
320 *m_stream << LayoutObjectAsText(layoutObject) << std::endl;
321 ScopedIndent childrenScope(this, 1);
322 if (layoutObject.isLayoutBlock()) {
323 ScopedIndent linesScope(this, 2);
324 const auto& lines = toLayoutBlock(layoutObject).lineBoxes();
325 for (const InlineFlowBox* lineBox = lines.firstLineBox(); lineBox; lineB ox = lineBox->nextLineBox())
326 visitInlineFlowBox(*lineBox);
327 }
328 for (const LayoutObject* child = layoutObject.slowFirstChild(); child; child = child->nextSibling())
329 visitLayoutObjct(*child);
330 }
331
332 void LayoutTreePrinter::print(const InlineBox* inlineBox)
333 {
334 if (!inlineBox) {
335 VLOG(0) << "(null)";
336 return;
337 }
338 VLOG(0) << "Layout tree dump of " << static_cast<const void*>(inlineBox) << std::endl << LayoutTreeAsText(*inlineBox);
339 }
340
341 void LayoutTreePrinter::print(const LayoutObject* layoutObject)
342 {
343 if (!layoutObject) {
344 VLOG(0) << "(null)";
345 return;
346 }
347 VLOG(0) << "Layout tree dump of " << static_cast<const void*>(layoutObject) << std::endl << LayoutTreeAsText(*layoutObject);
348 }
349
350 void LayoutTreePrinter::print(const LayoutPosition& position)
351 {
352 if (position.isNull()) {
353 VLOG(0) << "(null)";
354 return;
355 }
356 if (const InlineBox* inlineBox = position.m_inlineBox) {
357 VLOG(0) << "Layout tree dump of " << position << std::endl << LayoutTree AsText(*inlineBox);
358 return;
359 }
360 VLOG(0) << "Layout tree dump of " << position << std::endl << LayoutTreeAsTe xt(*position.m_layoutObject);
361 }
362
363 } // namespace blink
364
365 void dumpLayoutTree(const blink::InlineBox* inlineBox)
366 {
367 blink::LayoutTreePrinter::print(inlineBox);
368 }
369
370 void dumpLayoutTree(const blink::LayoutObject* layoutObject)
371 {
372 blink::LayoutTreePrinter::print(layoutObject);
373 }
374
375 void dumpLayoutTree(const blink::LayoutPosition& position)
376 {
377 blink::LayoutTreePrinter::print(position);
378 }
379
380 void dumpLayoutTree(const blink::Node* node)
381 {
382 dumpLayoutTree(node->layoutObject());
383 }
384
385 void dumpLayoutTree(const blink::Position& position)
386 {
387 dumpLayoutTree(position.anchorNode());
388 }
389
390 void dumpLayoutTree(const blink::VisiblePosition& position)
391 {
392 dumpLayoutTree(position.deepEquivalent());
393 }
394
395 #endif
OLDNEW

Powered by Google App Engine
This is Rietveld 408576698