mirror of
https://github.com/servo/servo.git
synced 2025-06-06 16:45:39 +00:00
Auto merge of #7648 - mrobinson:print-tree, r=glennw
Improve printing of DisplayLists Use box tree characters to make DisplayLists easier to scan when printing them out. This is what the output looked like before: ``` #### start printing display list. "####" Stacking context at Rect(800px×608px at (0px,0px)) with overflow Rect(800px×608px at (0px,0px)): #### SolidColor(0,0,0,0). Rect(800px×608px at (0px,0px)) #### SolidColor(0,0,0,0). Rect(784px×0px at (8px,0px)) #### SolidColor(0,0.5019608,0,1). Rect(100px×100px at (0px,0px)) #### Child layers list length: 1 "########" Stacking context at Rect(100px×100px at (0px,0px)) with overflow Rect(100px×100px at (0px,0px)): ######## SolidColor(1,0,0,1). Rect(100px×100px at (0px,0px)) ######## Child layers list length: 1 "############" Stacking context at Rect(100px×100px at (0px,0px)) with overflow Rect(100px×100px at (0px,0px)): ``` This is what it looks like after this patch: ``` ┌ DisplayList │ ├─ Layered StackingContext at Rect(800px×608px at (0px,0px)) with overflow Rect(800px×608px at (0px,0px)): │ │ ├─ Block Backgrounds and Borders │ │ │ ├─ SolidColor rgba(0, 0, 0, 0) @ Rect(800px×608px at (0px,0px)) (7f926f46f1f0) │ │ │ └─ SolidColor rgba(0, 0, 0, 0) @ Rect(784px×0px at (8px,0px)) (7f926f46f2e0) │ │ ├─ Layered StackingContext at Rect(100px×100px at (0px,0px)) with overflow Rect(100px×100px at (0px,0px)): │ │ │ ├─ Backgrounds and Borders │ │ │ │ └─ SolidColor rgba(1, 0, 0, 1) @ Rect(100px×100px at (0px,0px)) (7f926f46f310) │ │ │ ├─ Layered StackingContext at Rect(100px×100px at (0px,0px)) with overflow Rect(100px×100px at (0px,0px)): │ │ ├─ Layered StackingContext at Rect(100px×100px at (0px,0px)) with overflow Rect(100px×100px at (0px,0px)): │ │ │ ├─ Backgrounds and Borders │ │ │ │ └─ SolidColor rgba(0, 0.5019608, 0, 1) @ Rect(100px×100px at (0px,0px)) (7f926f46f3a0) ``` <!-- Reviewable:start --> [<img src="https://reviewable.io/review_button.png" height=40 alt="Review on Reviewable"/>](https://reviewable.io/reviews/servo/servo/7648) <!-- Reviewable:end -->
This commit is contained in:
commit
4e9a888f1a
5 changed files with 127 additions and 85 deletions
|
@ -47,6 +47,7 @@ use util::geometry::{self, Au, MAX_RECT, ZERO_RECT};
|
|||
use util::linked_list::prepend_from;
|
||||
use util::mem::HeapSizeOf;
|
||||
use util::opts;
|
||||
use util::print_tree::PrintTree;
|
||||
use util::range::Range;
|
||||
|
||||
// It seems cleaner to have layout code not mention Azure directly, so let's just reexport this for
|
||||
|
@ -59,8 +60,6 @@ pub mod optimizer;
|
|||
/// items that involve a blur. This ensures that the display item boundaries include all the ink.
|
||||
pub static BLUR_INFLATION_FACTOR: i32 = 3;
|
||||
|
||||
const MIN_INDENTATION_LENGTH: usize = 4;
|
||||
|
||||
/// An opaque handle to a node. The only safe operation that can be performed on this node is to
|
||||
/// compare it to another opaque handle or to another node.
|
||||
///
|
||||
|
@ -201,62 +200,44 @@ impl DisplayList {
|
|||
result
|
||||
}
|
||||
|
||||
// Print the display list. Only makes sense to call it after performing reflow.
|
||||
pub fn print_items(&self, indentation: String) {
|
||||
// Closures are so nice!
|
||||
let doit = |items: &Vec<DisplayItem>| {
|
||||
for item in items {
|
||||
match *item {
|
||||
DisplayItem::SolidColorClass(ref solid_color) => {
|
||||
println!("{} SolidColor({},{},{},{}). {:?}",
|
||||
indentation,
|
||||
solid_color.color.r,
|
||||
solid_color.color.g,
|
||||
solid_color.color.b,
|
||||
solid_color.color.a,
|
||||
solid_color.base.bounds)
|
||||
}
|
||||
DisplayItem::TextClass(ref text) => {
|
||||
println!("{} Text. {:?}", indentation, text.base.bounds)
|
||||
}
|
||||
DisplayItem::ImageClass(ref image) => {
|
||||
println!("{} Image. {:?}", indentation, image.base.bounds)
|
||||
}
|
||||
DisplayItem::BorderClass(ref border) => {
|
||||
println!("{} Border. {:?}", indentation, border.base.bounds)
|
||||
}
|
||||
DisplayItem::GradientClass(ref gradient) => {
|
||||
println!("{} Gradient. {:?}", indentation, gradient.base.bounds)
|
||||
}
|
||||
DisplayItem::LineClass(ref line) => {
|
||||
println!("{} Line. {:?}", indentation, line.base.bounds)
|
||||
}
|
||||
DisplayItem::BoxShadowClass(ref box_shadow) => {
|
||||
println!("{} Box_shadow. {:?}", indentation, box_shadow.base.bounds)
|
||||
}
|
||||
}
|
||||
}
|
||||
println!("\n");
|
||||
};
|
||||
pub fn print(&self, title: String) {
|
||||
let mut print_tree = PrintTree::new(title);
|
||||
self.print_with_tree(&mut print_tree);
|
||||
}
|
||||
|
||||
doit(&(self.all_display_items()));
|
||||
if !self.children.is_empty() {
|
||||
println!("{} Children stacking contexts list length: {}",
|
||||
indentation,
|
||||
self.children.len());
|
||||
for stacking_context in &self.children {
|
||||
stacking_context.print(indentation.clone() +
|
||||
&indentation[0..MIN_INDENTATION_LENGTH]);
|
||||
pub fn print_with_tree(&self, print_tree: &mut PrintTree) {
|
||||
fn print_display_list_section(print_tree: &mut PrintTree,
|
||||
items: &LinkedList<DisplayItem>,
|
||||
title: &str) {
|
||||
if items.is_empty() {
|
||||
return;
|
||||
}
|
||||
|
||||
print_tree.new_level(title.to_owned());
|
||||
for item in items {
|
||||
print_tree.add_item(format!("{:?}", item));
|
||||
}
|
||||
print_tree.end_level();
|
||||
}
|
||||
if !self.layered_children.is_empty() {
|
||||
println!("{} Child layers list length: {}",
|
||||
indentation,
|
||||
self.layered_children.len());
|
||||
for paint_layer in &self.layered_children {
|
||||
paint_layer.stacking_context.print(indentation.clone() +
|
||||
&indentation[0..MIN_INDENTATION_LENGTH]);
|
||||
}
|
||||
|
||||
print_display_list_section(print_tree,
|
||||
&self.background_and_borders,
|
||||
"Backgrounds and Borders");
|
||||
print_display_list_section(print_tree,
|
||||
&self.block_backgrounds_and_borders,
|
||||
"Block Backgrounds and Borders");
|
||||
print_display_list_section(print_tree, &self.floats, "Floats");
|
||||
print_display_list_section(print_tree, &self.content, "Content");
|
||||
print_display_list_section(print_tree, &self.positioned_content, "Positioned Content");
|
||||
print_display_list_section(print_tree, &self.outlines, "Outlines");
|
||||
|
||||
|
||||
for stacking_context in &self.children {
|
||||
stacking_context.print_with_tree(print_tree);
|
||||
}
|
||||
|
||||
for paint_layer in &self.layered_children {
|
||||
paint_layer.stacking_context.print_with_tree(print_tree);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
@ -375,8 +356,8 @@ impl StackingContext {
|
|||
};
|
||||
|
||||
if opts::get().dump_display_list_optimized {
|
||||
println!("**** optimized display list. Tile bounds: {:?}", paint_context.page_rect);
|
||||
display_list.print_items("####".to_owned());
|
||||
display_list.print(format!("Optimized display list. Tile bounds: {:?}",
|
||||
paint_context.page_rect));
|
||||
}
|
||||
|
||||
// Set up our clip rect and transform.
|
||||
|
@ -645,25 +626,23 @@ impl StackingContext {
|
|||
self.display_list.background_and_borders.iter().rev())
|
||||
}
|
||||
|
||||
pub fn print(&self, mut indentation: String) {
|
||||
// We cover the case of an empty string.
|
||||
if indentation.is_empty() {
|
||||
indentation = "####".to_owned();
|
||||
pub fn print(&self, title: String) {
|
||||
let mut print_tree = PrintTree::new(title);
|
||||
self.print_with_tree(&mut print_tree);
|
||||
}
|
||||
|
||||
fn print_with_tree(&self, print_tree: &mut PrintTree) {
|
||||
if self.layer_id.is_some() {
|
||||
print_tree.new_level(format!("Layered StackingContext at {:?} with overflow {:?}:",
|
||||
self.bounds,
|
||||
self.overflow));
|
||||
} else {
|
||||
print_tree.new_level(format!("StackingContext at {:?} with overflow {:?}:",
|
||||
self.bounds,
|
||||
self.overflow));
|
||||
}
|
||||
|
||||
// We grow the indentation by 4 characters if needed.
|
||||
// I wish to push it all as a slice, but it won't work if the string is a single char.
|
||||
while indentation.len() < MIN_INDENTATION_LENGTH {
|
||||
let c = indentation.char_at(0);
|
||||
indentation.push(c);
|
||||
}
|
||||
|
||||
println!("{:?} Stacking context at {:?} with overflow {:?}:",
|
||||
indentation,
|
||||
self.bounds,
|
||||
self.overflow);
|
||||
|
||||
self.display_list.print_items(indentation);
|
||||
self.display_list.print_with_tree(print_tree);
|
||||
print_tree.end_level();
|
||||
}
|
||||
}
|
||||
|
||||
|
@ -1301,13 +1280,18 @@ impl fmt::Debug for DisplayItem {
|
|||
fn fmt(&self, f: &mut fmt::Formatter) -> fmt::Result {
|
||||
write!(f, "{} @ {:?} ({:x})",
|
||||
match *self {
|
||||
DisplayItem::SolidColorClass(_) => "SolidColor",
|
||||
DisplayItem::TextClass(_) => "Text",
|
||||
DisplayItem::ImageClass(_) => "Image",
|
||||
DisplayItem::BorderClass(_) => "Border",
|
||||
DisplayItem::GradientClass(_) => "Gradient",
|
||||
DisplayItem::LineClass(_) => "Line",
|
||||
DisplayItem::BoxShadowClass(_) => "BoxShadow",
|
||||
DisplayItem::SolidColorClass(ref solid_color) =>
|
||||
format!("SolidColor rgba({}, {}, {}, {})",
|
||||
solid_color.color.r,
|
||||
solid_color.color.g,
|
||||
solid_color.color.b,
|
||||
solid_color.color.a),
|
||||
DisplayItem::TextClass(_) => "Text".to_owned(),
|
||||
DisplayItem::ImageClass(_) => "Image".to_owned(),
|
||||
DisplayItem::BorderClass(_) => "Border".to_owned(),
|
||||
DisplayItem::GradientClass(_) => "Gradient".to_owned(),
|
||||
DisplayItem::LineClass(_) => "Line".to_owned(),
|
||||
DisplayItem::BoxShadowClass(_) => "BoxShadow".to_owned(),
|
||||
},
|
||||
self.base().bounds,
|
||||
self.base().metadata.node.id()
|
||||
|
|
|
@ -429,7 +429,6 @@ impl<C> PaintTask<C> where C: PaintListener + Send + 'static {
|
|||
&perspective,
|
||||
parent_id)
|
||||
}
|
||||
|
||||
}
|
||||
}
|
||||
}
|
||||
|
|
|
@ -1060,8 +1060,7 @@ impl LayoutTask {
|
|||
stacking_context.clone());
|
||||
|
||||
if opts::get().dump_display_list {
|
||||
println!("#### start printing display list.");
|
||||
stacking_context.print("#".to_owned());
|
||||
stacking_context.print("DisplayList".to_owned());
|
||||
}
|
||||
if opts::get().dump_display_list_json {
|
||||
println!("{}", serde_json::to_string_pretty(&stacking_context).unwrap());
|
||||
|
|
|
@ -61,6 +61,7 @@ pub mod mem;
|
|||
pub mod opts;
|
||||
pub mod persistent_list;
|
||||
pub mod prefs;
|
||||
pub mod print_tree;
|
||||
pub mod range;
|
||||
pub mod resource_files;
|
||||
pub mod str;
|
||||
|
|
59
components/util/print_tree.rs
Normal file
59
components/util/print_tree.rs
Normal file
|
@ -0,0 +1,59 @@
|
|||
/* This Source Code Form is subject to the terms of the Mozilla Public
|
||||
* License, v. 2.0. If a copy of the MPL was not distributed with this
|
||||
* file, You can obtain one at http://mozilla.org/MPL/2.0/. */
|
||||
|
||||
/// A struct that makes it easier to print out a pretty tree of data, which
|
||||
/// can be visually scanned more easily.
|
||||
pub struct PrintTree {
|
||||
/// The current level of recursion.
|
||||
level: u32,
|
||||
|
||||
/// An item which is queued up, so that we can determine if we need
|
||||
/// a mid-tree prefix or a branch ending prefix.
|
||||
queued_item: Option<String>,
|
||||
}
|
||||
|
||||
impl PrintTree {
|
||||
pub fn new(title: String) -> PrintTree {
|
||||
println!("┌ {}", title);
|
||||
PrintTree {
|
||||
level: 1,
|
||||
queued_item: None,
|
||||
}
|
||||
}
|
||||
|
||||
/// Descend one level in the tree with the given title.
|
||||
pub fn new_level(&mut self, title: String) {
|
||||
self.flush_queued_item("├─");
|
||||
|
||||
self.print_level_prefix();
|
||||
println!("├─ {}", title);
|
||||
|
||||
self.level = self.level + 1;
|
||||
}
|
||||
|
||||
/// Ascend one level in the tree.
|
||||
pub fn end_level(&mut self) {
|
||||
self.flush_queued_item("└─");
|
||||
self.level = self.level - 1;
|
||||
}
|
||||
|
||||
/// Add an item to the current level in the tree.
|
||||
pub fn add_item(&mut self, text: String) {
|
||||
self.flush_queued_item("├─");
|
||||
self.queued_item = Some(text);
|
||||
}
|
||||
|
||||
fn print_level_prefix(&self) {
|
||||
for _ in 0..self.level {
|
||||
print!("│ ");
|
||||
}
|
||||
}
|
||||
|
||||
fn flush_queued_item(&mut self, prefix: &str) {
|
||||
if let Some(queued_item) = self.queued_item.take() {
|
||||
self.print_level_prefix();
|
||||
println!("{} {}", prefix, queued_item);
|
||||
}
|
||||
}
|
||||
}
|
Loading…
Add table
Add a link
Reference in a new issue