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

Side by Side Diff: third_party/WebKit/Source/core/layout/LayoutBlock.cpp

Issue 1544423002: Improve positioned/percentHeight descendant/container tracking (Closed) Base URL: https://chromium.googlesource.com/chromium/src.git@master
Patch Set: virtual destructor Created 4 years, 11 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
1 /* 1 /*
2 * Copyright (C) 1999 Lars Knoll (knoll@kde.org) 2 * Copyright (C) 1999 Lars Knoll (knoll@kde.org)
3 * (C) 1999 Antti Koivisto (koivisto@kde.org) 3 * (C) 1999 Antti Koivisto (koivisto@kde.org)
4 * (C) 2007 David Smith (catfish.man@gmail.com) 4 * (C) 2007 David Smith (catfish.man@gmail.com)
5 * Copyright (C) 2003, 2004, 2005, 2006, 2007, 2008, 2009, 2010, 2011 Apple Inc. All rights reserved. 5 * Copyright (C) 2003, 2004, 2005, 2006, 2007, 2008, 2009, 2010, 2011 Apple Inc. All rights reserved.
6 * Copyright (C) Research In Motion Limited 2010. All rights reserved. 6 * Copyright (C) Research In Motion Limited 2010. All rights reserved.
7 * 7 *
8 * This library is free software; you can redistribute it and/or 8 * This library is free software; you can redistribute it and/or
9 * modify it under the terms of the GNU Library General Public 9 * modify it under the terms of the GNU Library General Public
10 * License as published by the Free Software Foundation; either 10 * License as published by the Free Software Foundation; either
(...skipping 69 matching lines...) Expand 10 before | Expand all | Expand 10 after
80 using namespace HTMLNames; 80 using namespace HTMLNames;
81 81
82 struct SameSizeAsLayoutBlock : public LayoutBox { 82 struct SameSizeAsLayoutBlock : public LayoutBox {
83 LayoutObjectChildList children; 83 LayoutObjectChildList children;
84 LineBoxList lineBoxes; 84 LineBoxList lineBoxes;
85 uint32_t bitfields; 85 uint32_t bitfields;
86 }; 86 };
87 87
88 static_assert(sizeof(LayoutBlock) == sizeof(SameSizeAsLayoutBlock), "LayoutBlock should stay small"); 88 static_assert(sizeof(LayoutBlock) == sizeof(SameSizeAsLayoutBlock), "LayoutBlock should stay small");
89 89
90 // This map keeps track of the positioned objects associated with a containing
91 // block.
92 //
93 // This map is populated during layout. It is kept across layouts to handle
94 // that we skip unchanged sub-trees during layout, in such a way that we are
95 // able to lay out deeply nested out-of-flow descendants if their containing
96 // block got laid out. The map could be invalidated during style change but
97 // keeping track of containing blocks at that time is complicated (we are in
98 // the middle of recomputing the style so we can't rely on any of its
99 // information), which is why it's easier to just update it for every layout.
100 static TrackedDescendantsMap* gPositionedDescendantsMap = nullptr;
101
102 // This map keeps track of the descendants whose 'height' is percentage associat ed
103 // with a containing block. Like |gPositionedDescendantsMap|, it is also recompu ted
104 // for every layout (see the comment above about why).
105 static TrackedDescendantsMap* gPercentHeightDescendantsMap = nullptr;
106
107 static TrackedContainerMap* gPositionedContainerMap = nullptr;
108 static TrackedContainerMap* gPercentHeightContainerMap = nullptr;
109
110 struct ScrollInfo { 90 struct ScrollInfo {
111 ScrollInfo() : autoHorizontalScrollBarChanged(false), autoVerticalScrollBarC hanged(false) {} 91 ScrollInfo() : autoHorizontalScrollBarChanged(false), autoVerticalScrollBarC hanged(false) {}
112 DoubleSize scrollOffset; 92 DoubleSize scrollOffset;
113 bool autoHorizontalScrollBarChanged; 93 bool autoHorizontalScrollBarChanged;
114 bool autoVerticalScrollBarChanged; 94 bool autoVerticalScrollBarChanged;
115 bool hasOffset() const { return scrollOffset != DoubleSize(); } 95 bool hasOffset() const { return scrollOffset != DoubleSize(); }
116 bool scrollBarsChanged() const { return autoHorizontalScrollBarChanged || au toVerticalScrollBarChanged; } 96 bool scrollBarsChanged() const { return autoHorizontalScrollBarChanged || au toVerticalScrollBarChanged; }
117 void merge(const ScrollInfo& other) 97 void merge(const ScrollInfo& other)
118 { 98 {
119 // We always keep the first scrollOffset we saw for this block, so don't copy that field. 99 // We always keep the first scrollOffset we saw for this block, so don't copy that field.
(...skipping 13 matching lines...) Expand all
133 , m_hasMarkupTruncation(false) 113 , m_hasMarkupTruncation(false)
134 , m_widthAvailableToChildrenChanged(false) 114 , m_widthAvailableToChildrenChanged(false)
135 , m_hasOnlySelfCollapsingChildren(false) 115 , m_hasOnlySelfCollapsingChildren(false)
136 , m_descendantsWithFloatsMarkedForLayout(false) 116 , m_descendantsWithFloatsMarkedForLayout(false)
137 , m_needsRecalcLogicalWidthAfterLayoutChildren(false) 117 , m_needsRecalcLogicalWidthAfterLayoutChildren(false)
138 { 118 {
139 // LayoutBlockFlow calls setChildrenInline(true). 119 // LayoutBlockFlow calls setChildrenInline(true).
140 // By default, subclasses do not have inline children. 120 // By default, subclasses do not have inline children.
141 } 121 }
142 122
143 static void removeBlockFromDescendantAndContainerMaps(LayoutBlock* block, Tracke dDescendantsMap*& descendantMap, TrackedContainerMap*& containerMap) 123 LayoutBlock::~LayoutBlock()
144 { 124 {
145 if (OwnPtr<TrackedLayoutBoxListHashSet> descendantSet = descendantMap->take( block)) { 125 if (TrackedLayoutBoxListHashSet* descendants = positionedObjects()) {
146 for (auto& descendant : *descendantSet) { 126 for (LayoutBox* descendant : *descendants) {
147 TrackedContainerMap::iterator it = containerMap->find(descendant); 127 ASSERT(descendant->positionedContainer() == this);
148 ASSERT(it != containerMap->end()); 128 descendant->setPositionedContainer(nullptr);
149 if (it == containerMap->end()) 129 }
150 continue; 130 }
151 HashSet<LayoutBlock*>* containerSet = it->value.get(); 131 if (TrackedLayoutBoxListHashSet* descendants = percentHeightDescendants()) {
152 ASSERT(containerSet->contains(block)); 132 for (LayoutBox* descendant : *descendants) {
153 containerSet->remove(block); 133 ASSERT(descendant->percentHeightContainer() == this);
154 if (containerSet->isEmpty()) 134 descendant->setPercentHeightContainer(nullptr);
155 containerMap->remove(it);
156 } 135 }
157 } 136 }
158 } 137 }
159 138
160 void LayoutBlock::removeFromGlobalMaps()
161 {
162 if (gPercentHeightDescendantsMap)
163 removeBlockFromDescendantAndContainerMaps(this, gPercentHeightDescendant sMap, gPercentHeightContainerMap);
164 if (gPositionedDescendantsMap)
165 removeBlockFromDescendantAndContainerMaps(this, gPositionedDescendantsMa p, gPositionedContainerMap);
166 }
167
168 LayoutBlock::~LayoutBlock()
169 {
170 removeFromGlobalMaps();
171 }
172
173 void LayoutBlock::willBeDestroyed() 139 void LayoutBlock::willBeDestroyed()
174 { 140 {
175 // Mark as being destroyed to avoid trouble with merges in removeChild(). 141 // Mark as being destroyed to avoid trouble with merges in removeChild().
176 m_beingDestroyed = true; 142 m_beingDestroyed = true;
177 143
178 // Make sure to destroy anonymous children first while they are still connec ted to the rest of the tree, so that they will 144 // Make sure to destroy anonymous children first while they are still connec ted to the rest of the tree, so that they will
179 // properly dirty line boxes that they are removed from. Effects that do :be fore/:after only on hover could crash otherwise. 145 // properly dirty line boxes that they are removed from. Effects that do :be fore/:after only on hover could crash otherwise.
180 children()->destroyLeftoverChildren(); 146 children()->destroyLeftoverChildren();
181 147
182 // Destroy our continuation before anything other than anonymous children. 148 // Destroy our continuation before anything other than anonymous children.
(...skipping 1206 matching lines...) Expand 10 before | Expand all | Expand 10 after
1389 } 1355 }
1390 1356
1391 void LayoutBlock::setSelectionState(SelectionState state) 1357 void LayoutBlock::setSelectionState(SelectionState state)
1392 { 1358 {
1393 LayoutBox::setSelectionState(state); 1359 LayoutBox::setSelectionState(state);
1394 1360
1395 if (inlineBoxWrapper() && canUpdateSelectionOnRootLineBoxes()) 1361 if (inlineBoxWrapper() && canUpdateSelectionOnRootLineBoxes())
1396 inlineBoxWrapper()->root().setHasSelectedChildren(state != SelectionNone ); 1362 inlineBoxWrapper()->root().setHasSelectedChildren(state != SelectionNone );
1397 } 1363 }
1398 1364
1399 void LayoutBlock::insertIntoTrackedLayoutBoxMaps(LayoutBox* descendant, TrackedD escendantsMap*& descendantsMap, TrackedContainerMap*& containerMap) 1365 void LayoutBlock::insertPositionedObject(LayoutBox* descendant)
1400 { 1366 {
1401 if (!descendantsMap) { 1367 ASSERT(!isAnonymousBlock());
1402 descendantsMap = new TrackedDescendantsMap; 1368 OwnPtr<TrackedLayoutBoxListHashSet>& positionedDescendants = ensureLayoutBlo ckRareData().m_positionedDescendants;
1403 containerMap = new TrackedContainerMap; 1369 if (!positionedDescendants)
1370 positionedDescendants = adoptPtr(new TrackedLayoutBoxListHashSet);
1371 if (descendant->positionedContainer()) {
1372 if (descendant->positionedContainer() == this) {
1373 ASSERT(positionedDescendants->contains(descendant));
1374 return;
1375 }
1376 descendant->removeFromPositionedContainer();
1404 } 1377 }
1378 positionedDescendants->add(descendant);
1379 descendant->setPositionedContainer(this);
1380 }
1405 1381
1406 TrackedLayoutBoxListHashSet* descendantSet = descendantsMap->get(this); 1382 void LayoutBlock::removePositionedObject(LayoutBox* descendant)
1407 if (!descendantSet) { 1383 {
1408 descendantSet = new TrackedLayoutBoxListHashSet; 1384 TrackedLayoutBoxListHashSet* positionedDescendants = positionedObjects();
1409 descendantsMap->set(this, adoptPtr(descendantSet)); 1385 if (!descendant->positionedContainer()) {
1410 } 1386 ASSERT(!positionedDescendants || !positionedDescendants->contains(descen dant));
1411 bool added = descendantSet->add(descendant).isNewEntry;
1412 if (!added) {
1413 ASSERT(containerMap->get(descendant));
1414 ASSERT(containerMap->get(descendant)->contains(this));
1415 return; 1387 return;
1416 } 1388 }
1417 1389 ASSERT(descendant->positionedContainer() == this);
1418 HashSet<LayoutBlock*>* containerSet = containerMap->get(descendant); 1390 ASSERT(positionedDescendants && positionedDescendants->contains(descendant)) ;
1419 if (!containerSet) { 1391 positionedDescendants->remove(descendant);
1420 containerSet = new HashSet<LayoutBlock*>; 1392 descendant->setPositionedContainer(nullptr);
1421 containerMap->set(descendant, adoptPtr(containerSet));
1422 }
1423 ASSERT(!containerSet->contains(this));
1424 containerSet->add(this);
1425 }
1426
1427 void LayoutBlock::removeFromTrackedLayoutBoxMaps(LayoutBox* descendant, TrackedD escendantsMap*& descendantsMap, TrackedContainerMap*& containerMap)
1428 {
1429 if (!descendantsMap)
1430 return;
1431
1432 OwnPtr<HashSet<LayoutBlock*>> containerSet = containerMap->take(descendant);
1433 if (!containerSet)
1434 return;
1435
1436 for (auto* container : *containerSet) {
1437 // FIXME: Disabling this assert temporarily until we fix the layout
1438 // bugs associated with positioned objects not properly cleared from
1439 // their ancestor chain before being moved. See webkit bug 93766.
1440 // ASSERT(descendant->isDescendantOf(container));
1441
1442 TrackedDescendantsMap::iterator descendantsMapIterator = descendantsMap- >find(container);
1443 ASSERT(descendantsMapIterator != descendantsMap->end());
1444 if (descendantsMapIterator == descendantsMap->end())
1445 continue;
1446 TrackedLayoutBoxListHashSet* descendantSet = descendantsMapIterator->val ue.get();
1447 ASSERT(descendantSet->contains(descendant));
1448 descendantSet->remove(descendant);
1449 if (descendantSet->isEmpty())
1450 descendantsMap->remove(descendantsMapIterator);
1451 }
1452 }
1453
1454 TrackedLayoutBoxListHashSet* LayoutBlock::positionedObjects() const
1455 {
1456 if (gPositionedDescendantsMap)
1457 return gPositionedDescendantsMap->get(this);
1458 return nullptr;
1459 }
1460
1461 void LayoutBlock::insertPositionedObject(LayoutBox* o)
1462 {
1463 ASSERT(!isAnonymousBlock());
1464 insertIntoTrackedLayoutBoxMaps(o, gPositionedDescendantsMap, gPositionedCont ainerMap);
1465 }
1466
1467 void LayoutBlock::removePositionedObject(LayoutBox* o)
1468 {
1469 removeFromTrackedLayoutBoxMaps(o, gPositionedDescendantsMap, gPositionedCont ainerMap);
1470 } 1393 }
1471 1394
1472 void LayoutBlock::removePositionedObjects(LayoutBlock* o, ContainingBlockState c ontainingBlockState) 1395 void LayoutBlock::removePositionedObjects(LayoutBlock* o, ContainingBlockState c ontainingBlockState)
1473 { 1396 {
1474 TrackedLayoutBoxListHashSet* positionedDescendants = positionedObjects(); 1397 TrackedLayoutBoxListHashSet* positionedDescendants = positionedObjects();
1475 if (!positionedDescendants) 1398 if (!positionedDescendants)
1476 return; 1399 return;
1477 1400
1478 Vector<LayoutBox*, 16> deadObjects; 1401 Vector<LayoutBox*, 16> deadObjects;
1479 for (auto* positionedObject : *positionedDescendants) { 1402 for (auto* positionedObject : *positionedDescendants) {
(...skipping 18 matching lines...) Expand all
1498 LayoutObject* p = positionedObject->parent(); 1421 LayoutObject* p = positionedObject->parent();
1499 while (p && !p->isLayoutBlock()) 1422 while (p && !p->isLayoutBlock())
1500 p = p->parent(); 1423 p = p->parent();
1501 if (p) 1424 if (p)
1502 p->setChildNeedsLayout(); 1425 p->setChildNeedsLayout();
1503 1426
1504 deadObjects.append(positionedObject); 1427 deadObjects.append(positionedObject);
1505 } 1428 }
1506 } 1429 }
1507 1430
1508 for (unsigned i = 0; i < deadObjects.size(); i++) 1431 for (auto* deadObject : deadObjects)
1509 removePositionedObject(deadObjects.at(i)); 1432 deadObject->removeFromPositionedContainer();
1510 } 1433 }
1511 1434
1512 void LayoutBlock::addPercentHeightDescendant(LayoutBox* descendant) 1435 void LayoutBlock::addPercentHeightDescendant(LayoutBox* descendant)
1513 { 1436 {
1514 insertIntoTrackedLayoutBoxMaps(descendant, gPercentHeightDescendantsMap, gPe rcentHeightContainerMap); 1437 OwnPtr<TrackedLayoutBoxListHashSet>& percentHeightDescendants = ensureLayout BlockRareData().m_percentHeightDescendants;
1438 if (!percentHeightDescendants)
1439 percentHeightDescendants = adoptPtr(new TrackedLayoutBoxListHashSet);
1440 if (descendant->percentHeightContainer()) {
1441 if (descendant->percentHeightContainer() == this) {
1442 ASSERT(percentHeightDescendants->contains(descendant));
1443 return;
1444 }
1445 descendant->removeFromPercentHeightContainer();
1446 }
1447 percentHeightDescendants->add(descendant);
1448 descendant->setPercentHeightContainer(this);
1515 } 1449 }
1516 1450
1517 void LayoutBlock::removePercentHeightDescendant(LayoutBox* descendant) 1451 void LayoutBlock::removePercentHeightDescendant(LayoutBox* descendant)
1518 { 1452 {
1519 removeFromTrackedLayoutBoxMaps(descendant, gPercentHeightDescendantsMap, gPe rcentHeightContainerMap); 1453 TrackedLayoutBoxListHashSet* percentHeightDescendants = this->percentHeightD escendants();
1520 } 1454 if (!descendant->percentHeightContainer()) {
1521 1455 ASSERT(!percentHeightDescendants || !percentHeightDescendants->contains( descendant));
1522 TrackedLayoutBoxListHashSet* LayoutBlock::percentHeightDescendants() const 1456 return;
1523 { 1457 }
1524 return gPercentHeightDescendantsMap ? gPercentHeightDescendantsMap->get(this ) : 0; 1458 ASSERT(descendant->percentHeightContainer() == this);
1525 } 1459 ASSERT(percentHeightDescendants && percentHeightDescendants->contains(descen dant));
1526 1460 percentHeightDescendants->remove(descendant);
1527 bool LayoutBlock::hasPercentHeightContainerMap() 1461 descendant->setPercentHeightContainer(nullptr);
1528 {
1529 return gPercentHeightContainerMap;
1530 } 1462 }
1531 1463
1532 bool LayoutBlock::hasPercentHeightDescendant(LayoutBox* descendant) 1464 bool LayoutBlock::hasPercentHeightDescendant(LayoutBox* descendant)
1533 { 1465 {
1534 // We don't null check gPercentHeightContainerMap since the caller 1466 return percentHeightDescendants() && percentHeightDescendants()->contains(de scendant);
1535 // already ensures this and we need to call this function on every
1536 // descendant in clearPercentHeightDescendantsFrom().
1537 ASSERT(gPercentHeightContainerMap);
1538 return gPercentHeightContainerMap->contains(descendant);
1539 } 1467 }
1540 1468
1541 void LayoutBlock::dirtyForLayoutFromPercentageHeightDescendants(SubtreeLayoutSco pe& layoutScope) 1469 void LayoutBlock::dirtyForLayoutFromPercentageHeightDescendants(SubtreeLayoutSco pe& layoutScope)
1542 { 1470 {
1543 if (!gPercentHeightDescendantsMap) 1471 TrackedLayoutBoxListHashSet* percentHeightDescendants = this->percentHeightD escendants();
1472 if (!percentHeightDescendants)
1544 return; 1473 return;
1545 1474
1546 TrackedLayoutBoxListHashSet* descendants = gPercentHeightDescendantsMap->get (this); 1475 for (auto* box : *percentHeightDescendants) {
1547 if (!descendants)
1548 return;
1549
1550 for (auto* box : *descendants) {
1551 ASSERT(box->isDescendantOf(this)); 1476 ASSERT(box->isDescendantOf(this));
1552 while (box != this) { 1477 while (box != this) {
1553 if (box->normalChildNeedsLayout()) 1478 if (box->normalChildNeedsLayout())
1554 break; 1479 break;
1555 layoutScope.setChildNeedsLayout(box); 1480 layoutScope.setChildNeedsLayout(box);
1556 box = box->containingBlock(); 1481 box = box->containingBlock();
1557 ASSERT(box); 1482 ASSERT(box);
1558 if (!box) 1483 if (!box)
1559 break; 1484 break;
1560 } 1485 }
1561 } 1486 }
1562 } 1487 }
1563 1488
1564 void LayoutBlock::removePercentHeightDescendantIfNeeded(LayoutBox* descendant)
1565 {
1566 // We query the map directly, rather than looking at style's
1567 // logicalHeight()/logicalMinHeight()/logicalMaxHeight() since those
1568 // can change with writing mode/directional changes.
1569 if (!hasPercentHeightContainerMap())
1570 return;
1571
1572 if (!hasPercentHeightDescendant(descendant))
1573 return;
1574
1575 removePercentHeightDescendant(descendant);
1576 }
1577
1578 void LayoutBlock::clearPercentHeightDescendantsFrom(LayoutBox* parent)
1579 {
1580 ASSERT(gPercentHeightContainerMap);
1581 for (LayoutObject* curr = parent->slowFirstChild(); curr; curr = curr->nextI nPreOrder(parent)) {
1582 if (!curr->isBox())
1583 continue;
1584
1585 LayoutBox* box = toLayoutBox(curr);
1586 if (!hasPercentHeightDescendant(box))
1587 continue;
1588
1589 removePercentHeightDescendant(box);
1590 }
1591 }
1592
1593 LayoutUnit LayoutBlock::textIndentOffset() const 1489 LayoutUnit LayoutBlock::textIndentOffset() const
1594 { 1490 {
1595 LayoutUnit cw = 0; 1491 LayoutUnit cw = 0;
1596 if (style()->textIndent().hasPercent()) 1492 if (style()->textIndent().hasPercent())
1597 cw = containingBlock()->availableLogicalWidth(); 1493 cw = containingBlock()->availableLogicalWidth();
1598 return minimumValueForLength(style()->textIndent(), cw); 1494 return minimumValueForLength(style()->textIndent(), cw);
1599 } 1495 }
1600 1496
1601 void LayoutBlock::markLinesDirtyInBlockRange(LayoutUnit logicalTop, LayoutUnit l ogicalBottom, RootInlineBox* highest) 1497 void LayoutBlock::markLinesDirtyInBlockRange(LayoutUnit logicalTop, LayoutUnit l ogicalBottom, RootInlineBox* highest)
1602 { 1498 {
(...skipping 1266 matching lines...) Expand 10 before | Expand all | Expand 10 after
2869 setLogicalTop(computedValues.m_position); 2765 setLogicalTop(computedValues.m_position);
2870 setMarginBefore(computedValues.m_margins.m_before); 2766 setMarginBefore(computedValues.m_margins.m_before);
2871 setMarginAfter(computedValues.m_margins.m_after); 2767 setMarginAfter(computedValues.m_margins.m_after);
2872 2768
2873 return true; 2769 return true;
2874 } 2770 }
2875 2771
2876 #if ENABLE(ASSERT) 2772 #if ENABLE(ASSERT)
2877 void LayoutBlock::checkPositionedObjectsNeedLayout() 2773 void LayoutBlock::checkPositionedObjectsNeedLayout()
2878 { 2774 {
2879 if (!gPositionedDescendantsMap)
2880 return;
2881
2882 if (TrackedLayoutBoxListHashSet* positionedDescendantSet = positionedObjects ()) { 2775 if (TrackedLayoutBoxListHashSet* positionedDescendantSet = positionedObjects ()) {
2883 TrackedLayoutBoxListHashSet::const_iterator end = positionedDescendantSe t->end(); 2776 for (LayoutBox* box : *positionedDescendantSet)
2884 for (TrackedLayoutBoxListHashSet::const_iterator it = positionedDescenda ntSet->begin(); it != end; ++it) { 2777 ASSERT(!box->needsLayout());
2885 LayoutBox* currBox = *it;
2886 ASSERT(!currBox->needsLayout());
2887 }
2888 } 2778 }
2889 } 2779 }
2890 2780
2891 #endif 2781 #endif
2892 2782
2893 #ifndef NDEBUG 2783 #ifndef NDEBUG
2894 2784
2895 void LayoutBlock::showLineTreeAndMark(const InlineBox* markedBox1, const char* m arkedLabel1, const InlineBox* markedBox2, const char* markedLabel2, const Layout Object* obj) const 2785 void LayoutBlock::showLineTreeAndMark(const InlineBox* markedBox1, const char* m arkedLabel1, const InlineBox* markedBox2, const char* markedLabel2, const Layout Object* obj) const
2896 { 2786 {
2897 showLayoutObject(); 2787 showLayoutObject();
2898 for (const RootInlineBox* root = firstRootBox(); root; root = root->nextRoot Box()) 2788 for (const RootInlineBox* root = firstRootBox(); root; root = root->nextRoot Box())
2899 root->showLineTreeAndMark(markedBox1, markedLabel1, markedBox2, markedLa bel2, obj, 1); 2789 root->showLineTreeAndMark(markedBox1, markedLabel1, markedBox2, markedLa bel2, obj, 1);
2900 } 2790 }
2901 2791
2902 #endif 2792 #endif
2903 2793
2904 } // namespace blink 2794 } // namespace blink
OLDNEW

Powered by Google App Engine
This is Rietveld 408576698