OLD | NEW |
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 * Copyright (C) 2003, 2004, 2005, 2006, 2007, 2008, 2009 Apple Inc. | 4 * Copyright (C) 2003, 2004, 2005, 2006, 2007, 2008, 2009 Apple Inc. |
5 * All rights reserved. | 5 * All rights reserved. |
6 * | 6 * |
7 * This library is free software; you can redistribute it and/or | 7 * This library is free software; you can redistribute it and/or |
8 * modify it under the terms of the GNU Library General Public | 8 * modify it under the terms of the GNU Library General Public |
9 * License as published by the Free Software Foundation; either | 9 * License as published by the Free Software Foundation; either |
10 * version 2 of the License, or (at your option) any later version. | 10 * version 2 of the License, or (at your option) any later version. |
(...skipping 160 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
171 for (LayoutInline* currCont = continuation; currCont; | 171 for (LayoutInline* currCont = continuation; currCont; |
172 currCont = currCont->inlineElementContinuation()) { | 172 currCont = currCont->inlineElementContinuation()) { |
173 LayoutBoxModelObject* nextCont = currCont->continuation(); | 173 LayoutBoxModelObject* nextCont = currCont->continuation(); |
174 currCont->setContinuation(nullptr); | 174 currCont->setContinuation(nullptr); |
175 currCont->setStyle(mutableStyle()); | 175 currCont->setStyle(mutableStyle()); |
176 currCont->setContinuation(nextCont); | 176 currCont->setContinuation(nextCont); |
177 endOfContinuation = currCont; | 177 endOfContinuation = currCont; |
178 } | 178 } |
179 | 179 |
180 if (continuation && oldStyle) { | 180 if (continuation && oldStyle) { |
181 ASSERT(endOfContinuation); | 181 DCHECK(endOfContinuation); |
182 LayoutObject* block = containingBlock()->nextSibling(); | 182 LayoutObject* block = containingBlock()->nextSibling(); |
183 // If an inline's in-flow positioning has changed then any descendant blocks | 183 // If an inline's in-flow positioning has changed then any descendant blocks |
184 // will need to change their styles accordingly. | 184 // will need to change their styles accordingly. |
185 if (block && block->isAnonymousBlock() && | 185 if (block && block->isAnonymousBlock() && |
186 newStyle.position() != oldStyle->position() && | 186 newStyle.position() != oldStyle->position() && |
187 (newStyle.hasInFlowPosition() || oldStyle->hasInFlowPosition())) | 187 (newStyle.hasInFlowPosition() || oldStyle->hasInFlowPosition())) |
188 updateInFlowPositionOfAnonymousBlockContinuations( | 188 updateInFlowPositionOfAnonymousBlockContinuations( |
189 block, newStyle, *oldStyle, endOfContinuation->containingBlock()); | 189 block, newStyle, *oldStyle, endOfContinuation->containingBlock()); |
190 } | 190 } |
191 | 191 |
(...skipping 195 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
387 to->addChildIgnoringContinuation( | 387 to->addChildIgnoringContinuation( |
388 children()->removeChildNode(this, currentChild), nullptr); | 388 children()->removeChildNode(this, currentChild), nullptr); |
389 } | 389 } |
390 } | 390 } |
391 | 391 |
392 void LayoutInline::splitInlines(LayoutBlockFlow* fromBlock, | 392 void LayoutInline::splitInlines(LayoutBlockFlow* fromBlock, |
393 LayoutBlockFlow* toBlock, | 393 LayoutBlockFlow* toBlock, |
394 LayoutBlockFlow* middleBlock, | 394 LayoutBlockFlow* middleBlock, |
395 LayoutObject* beforeChild, | 395 LayoutObject* beforeChild, |
396 LayoutBoxModelObject* oldCont) { | 396 LayoutBoxModelObject* oldCont) { |
397 ASSERT(isDescendantOf(fromBlock)); | 397 DCHECK(isDescendantOf(fromBlock)); |
398 | 398 |
399 // If we're splitting the inline containing the fullscreened element, | 399 // If we're splitting the inline containing the fullscreened element, |
400 // |beforeChild| may be the layoutObject for the fullscreened element. | 400 // |beforeChild| may be the layoutObject for the fullscreened element. |
401 // However, that layoutObject is wrapped in a LayoutFullScreen, so |this| is | 401 // However, that layoutObject is wrapped in a LayoutFullScreen, so |this| is |
402 // not its parent. Since the splitting logic expects |this| to be the parent, | 402 // not its parent. Since the splitting logic expects |this| to be the parent, |
403 // set |beforeChild| to be the LayoutFullScreen. | 403 // set |beforeChild| to be the LayoutFullScreen. |
404 if (Fullscreen* fullscreen = Fullscreen::fromIfExists(document())) { | 404 if (Fullscreen* fullscreen = Fullscreen::fromIfExists(document())) { |
405 const Element* fullScreenElement = fullscreen->currentFullScreenElement(); | 405 const Element* fullScreenElement = fullscreen->currentFullScreenElement(); |
406 if (fullScreenElement && beforeChild && | 406 if (fullScreenElement && beforeChild && |
407 beforeChild->node() == fullScreenElement) | 407 beforeChild->node() == fullScreenElement) |
(...skipping 55 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
463 // *after* |current| and append them all to the |cloneInlineParent|. | 463 // *after* |current| and append them all to the |cloneInlineParent|. |
464 currentParent->moveChildrenToIgnoringContinuation(cloneInlineParent, | 464 currentParent->moveChildrenToIgnoringContinuation(cloneInlineParent, |
465 current->nextSibling()); | 465 current->nextSibling()); |
466 | 466 |
467 currentParent = current; | 467 currentParent = current; |
468 cloneInlineParent = cloneInline; | 468 cloneInlineParent = cloneInline; |
469 } | 469 } |
470 | 470 |
471 // The last inline to clone is |this|, and the current |cloneInline| is cloned | 471 // The last inline to clone is |this|, and the current |cloneInline| is cloned |
472 // from |this|. | 472 // from |this|. |
473 ASSERT(this == inlinesToClone.front()); | 473 DCHECK_EQ(this, inlinesToClone.front()); |
474 | 474 |
475 // Hook |cloneInline| up as the continuation of the middle block. | 475 // Hook |cloneInline| up as the continuation of the middle block. |
476 cloneInline->setContinuation(oldCont); | 476 cloneInline->setContinuation(oldCont); |
477 middleBlock->setContinuation(cloneInline); | 477 middleBlock->setContinuation(cloneInline); |
478 | 478 |
479 // Now take all of the children from |beforeChild| to the end and remove | 479 // Now take all of the children from |beforeChild| to the end and remove |
480 // them from |this| and place them in the clone. | 480 // them from |this| and place them in the clone. |
481 moveChildrenToIgnoringContinuation(cloneInline, beforeChild); | 481 moveChildrenToIgnoringContinuation(cloneInline, beforeChild); |
482 } | 482 } |
483 | 483 |
(...skipping 67 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
551 LayoutInvalidationReason::AnonymousBlockChange); | 551 LayoutInvalidationReason::AnonymousBlockChange); |
552 post->setNeedsLayoutAndPrefWidthsRecalcAndFullPaintInvalidation( | 552 post->setNeedsLayoutAndPrefWidthsRecalcAndFullPaintInvalidation( |
553 LayoutInvalidationReason::AnonymousBlockChange); | 553 LayoutInvalidationReason::AnonymousBlockChange); |
554 } | 554 } |
555 | 555 |
556 void LayoutInline::addChildToContinuation(LayoutObject* newChild, | 556 void LayoutInline::addChildToContinuation(LayoutObject* newChild, |
557 LayoutObject* beforeChild) { | 557 LayoutObject* beforeChild) { |
558 // A continuation always consists of two potential candidates: an inline or an | 558 // A continuation always consists of two potential candidates: an inline or an |
559 // anonymous block box holding block children. | 559 // anonymous block box holding block children. |
560 LayoutBoxModelObject* flow = continuationBefore(beforeChild); | 560 LayoutBoxModelObject* flow = continuationBefore(beforeChild); |
561 ASSERT(!beforeChild || beforeChild->parent()->isAnonymousBlock() || | 561 DCHECK(!beforeChild || beforeChild->parent()->isAnonymousBlock() || |
562 beforeChild->parent()->isLayoutInline()); | 562 beforeChild->parent()->isLayoutInline()); |
563 LayoutBoxModelObject* beforeChildParent = nullptr; | 563 LayoutBoxModelObject* beforeChildParent = nullptr; |
564 if (beforeChild) { | 564 if (beforeChild) { |
565 beforeChildParent = toLayoutBoxModelObject(beforeChild->parent()); | 565 beforeChildParent = toLayoutBoxModelObject(beforeChild->parent()); |
566 } else { | 566 } else { |
567 LayoutBoxModelObject* cont = nextContinuation(flow); | 567 LayoutBoxModelObject* cont = nextContinuation(flow); |
568 if (cont) | 568 if (cont) |
569 beforeChildParent = cont; | 569 beforeChildParent = cont; |
570 else | 570 else |
571 beforeChildParent = flow; | 571 beforeChildParent = flow; |
(...skipping 42 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
614 | 614 |
615 static inline void computeItemTopHeight(const LayoutInline* container, | 615 static inline void computeItemTopHeight(const LayoutInline* container, |
616 const RootInlineBox& rootBox, | 616 const RootInlineBox& rootBox, |
617 LayoutUnit* top, | 617 LayoutUnit* top, |
618 LayoutUnit* height) { | 618 LayoutUnit* height) { |
619 bool firstLine = rootBox.isFirstLineStyle(); | 619 bool firstLine = rootBox.isFirstLineStyle(); |
620 const SimpleFontData* fontData = | 620 const SimpleFontData* fontData = |
621 rootBox.getLineLayoutItem().style(firstLine)->font().primaryFont(); | 621 rootBox.getLineLayoutItem().style(firstLine)->font().primaryFont(); |
622 const SimpleFontData* containerFontData = | 622 const SimpleFontData* containerFontData = |
623 container->style(firstLine)->font().primaryFont(); | 623 container->style(firstLine)->font().primaryFont(); |
624 DCHECK(fontData && containerFontData); | 624 DCHECK(fontData); |
| 625 DCHECK(containerFontData); |
625 if (!fontData || !containerFontData) { | 626 if (!fontData || !containerFontData) { |
626 *top = LayoutUnit(); | 627 *top = LayoutUnit(); |
627 *height = LayoutUnit(); | 628 *height = LayoutUnit(); |
628 return; | 629 return; |
629 } | 630 } |
630 auto metrics = fontData->getFontMetrics(); | 631 auto metrics = fontData->getFontMetrics(); |
631 auto containerMetrics = containerFontData->getFontMetrics(); | 632 auto containerMetrics = containerFontData->getFontMetrics(); |
632 *top = rootBox.logicalTop() + (metrics.ascent() - containerMetrics.ascent()); | 633 *top = rootBox.logicalTop() + (metrics.ascent() - containerMetrics.ascent()); |
633 *height = LayoutUnit(containerMetrics.height()); | 634 *height = LayoutUnit(containerMetrics.height()); |
634 } | 635 } |
(...skipping 258 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
893 Region& m_region; | 894 Region& m_region; |
894 const HitTestLocation& m_location; | 895 const HitTestLocation& m_location; |
895 }; | 896 }; |
896 | 897 |
897 } // unnamed namespace | 898 } // unnamed namespace |
898 | 899 |
899 bool LayoutInline::hitTestCulledInline( | 900 bool LayoutInline::hitTestCulledInline( |
900 HitTestResult& result, | 901 HitTestResult& result, |
901 const HitTestLocation& locationInContainer, | 902 const HitTestLocation& locationInContainer, |
902 const LayoutPoint& accumulatedOffset) { | 903 const LayoutPoint& accumulatedOffset) { |
903 ASSERT(!alwaysCreateLineBoxes()); | 904 DCHECK(!alwaysCreateLineBoxes()); |
904 if (!visibleToHitTestRequest(result.hitTestRequest())) | 905 if (!visibleToHitTestRequest(result.hitTestRequest())) |
905 return false; | 906 return false; |
906 | 907 |
907 HitTestLocation adjustedLocation(locationInContainer, | 908 HitTestLocation adjustedLocation(locationInContainer, |
908 -toLayoutSize(accumulatedOffset)); | 909 -toLayoutSize(accumulatedOffset)); |
909 | 910 |
910 Region regionResult; | 911 Region regionResult; |
911 HitTestCulledInlinesGeneratorContext context(regionResult, adjustedLocation); | 912 HitTestCulledInlinesGeneratorContext context(regionResult, adjustedLocation); |
912 generateCulledLineBoxRects(context, this); | 913 generateCulledLineBoxRects(context, this); |
913 | 914 |
(...skipping 37 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
951 void operator()(const LayoutRect& rect) { operator()(FloatRect(rect)); } | 952 void operator()(const LayoutRect& rect) { operator()(FloatRect(rect)); } |
952 | 953 |
953 private: | 954 private: |
954 FloatRect& m_rect; | 955 FloatRect& m_rect; |
955 }; | 956 }; |
956 | 957 |
957 } // unnamed namespace | 958 } // unnamed namespace |
958 | 959 |
959 LayoutRect LayoutInline::linesBoundingBox() const { | 960 LayoutRect LayoutInline::linesBoundingBox() const { |
960 if (!alwaysCreateLineBoxes()) { | 961 if (!alwaysCreateLineBoxes()) { |
961 ASSERT(!firstLineBox()); | 962 DCHECK(!firstLineBox()); |
962 FloatRect floatResult; | 963 FloatRect floatResult; |
963 LinesBoundingBoxGeneratorContext context(floatResult); | 964 LinesBoundingBoxGeneratorContext context(floatResult); |
964 generateCulledLineBoxRects(context, this); | 965 generateCulledLineBoxRects(context, this); |
965 return enclosingLayoutRect(floatResult); | 966 return enclosingLayoutRect(floatResult); |
966 } | 967 } |
967 | 968 |
968 LayoutRect result; | 969 LayoutRect result; |
969 | 970 |
970 // See <rdar://problem/5289721>, for an unknown reason the linked list here is | 971 // See <rdar://problem/5289721>, for an unknown reason the linked list here is |
971 // sometimes inconsistent, first is non-zero and last is zero. We have been | 972 // sometimes inconsistent, first is non-zero and last is zero. We have been |
972 // unable to reproduce this at all (and consequently unable to figure ot why | 973 // unable to reproduce this at all (and consequently unable to figure ot why |
973 // this is happening). The assert will hopefully catch the problem in debug | 974 // this is happening). The assert will hopefully catch the problem in debug |
974 // builds and help us someday figure out why. We also put in a redundant | 975 // builds and help us someday figure out why. We also put in a redundant |
975 // check of lastLineBox() to avoid the crash for now. | 976 // check of lastLineBox() to avoid the crash for now. |
976 ASSERT(!firstLineBox() == | 977 DCHECK_EQ(!firstLineBox(), |
977 !lastLineBox()); // Either both are null or both exist. | 978 !lastLineBox()); // Either both are null or both exist. |
978 if (firstLineBox() && lastLineBox()) { | 979 if (firstLineBox() && lastLineBox()) { |
979 // Return the width of the minimal left side and the maximal right side. | 980 // Return the width of the minimal left side and the maximal right side. |
980 LayoutUnit logicalLeftSide; | 981 LayoutUnit logicalLeftSide; |
981 LayoutUnit logicalRightSide; | 982 LayoutUnit logicalRightSide; |
982 for (InlineFlowBox* curr = firstLineBox(); curr; | 983 for (InlineFlowBox* curr = firstLineBox(); curr; |
983 curr = curr->nextLineBox()) { | 984 curr = curr->nextLineBox()) { |
984 if (curr == firstLineBox() || curr->logicalLeft() < logicalLeftSide) | 985 if (curr == firstLineBox() || curr->logicalLeft() < logicalLeftSide) |
985 logicalLeftSide = curr->logicalLeft(); | 986 logicalLeftSide = curr->logicalLeft(); |
986 if (curr == firstLineBox() || curr->logicalRight() > logicalRightSide) | 987 if (curr == firstLineBox() || curr->logicalRight() > logicalRightSide) |
987 logicalRightSide = curr->logicalRight(); | 988 logicalRightSide = curr->logicalRight(); |
(...skipping 212 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
1200 } | 1201 } |
1201 | 1202 |
1202 bool LayoutInline::mapToVisualRectInAncestorSpaceInternal( | 1203 bool LayoutInline::mapToVisualRectInAncestorSpaceInternal( |
1203 const LayoutBoxModelObject* ancestor, | 1204 const LayoutBoxModelObject* ancestor, |
1204 TransformState& transformState, | 1205 TransformState& transformState, |
1205 VisualRectFlags visualRectFlags) const { | 1206 VisualRectFlags visualRectFlags) const { |
1206 if (ancestor == this) | 1207 if (ancestor == this) |
1207 return true; | 1208 return true; |
1208 | 1209 |
1209 LayoutObject* container = this->container(); | 1210 LayoutObject* container = this->container(); |
1210 ASSERT(container == parent()); | 1211 DCHECK_EQ(container, parent()); |
1211 if (!container) | 1212 if (!container) |
1212 return true; | 1213 return true; |
1213 | 1214 |
1214 bool preserve3D = container->style()->preserves3D(); | 1215 bool preserve3D = container->style()->preserves3D(); |
1215 | 1216 |
1216 TransformState::TransformAccumulation accumulation = | 1217 TransformState::TransformAccumulation accumulation = |
1217 preserve3D ? TransformState::AccumulateTransform | 1218 preserve3D ? TransformState::AccumulateTransform |
1218 : TransformState::FlattenTransform; | 1219 : TransformState::FlattenTransform; |
1219 | 1220 |
1220 if (style()->hasInFlowPosition() && layer()) { | 1221 if (style()->hasInFlowPosition() && layer()) { |
(...skipping 18 matching lines...) Expand all Loading... |
1239 LayoutRect rect(transformState.lastPlanarQuad().boundingBox()); | 1240 LayoutRect rect(transformState.lastPlanarQuad().boundingBox()); |
1240 containerBox->flipForWritingMode(rect); | 1241 containerBox->flipForWritingMode(rect); |
1241 transformState.setQuad(FloatQuad(FloatRect(rect))); | 1242 transformState.setQuad(FloatQuad(FloatRect(rect))); |
1242 } | 1243 } |
1243 return container->mapToVisualRectInAncestorSpaceInternal( | 1244 return container->mapToVisualRectInAncestorSpaceInternal( |
1244 ancestor, transformState, visualRectFlags); | 1245 ancestor, transformState, visualRectFlags); |
1245 } | 1246 } |
1246 | 1247 |
1247 LayoutSize LayoutInline::offsetFromContainer( | 1248 LayoutSize LayoutInline::offsetFromContainer( |
1248 const LayoutObject* container) const { | 1249 const LayoutObject* container) const { |
1249 ASSERT(container == this->container()); | 1250 DCHECK_EQ(container, this->container()); |
1250 | 1251 |
1251 LayoutSize offset; | 1252 LayoutSize offset; |
1252 if (isInFlowPositioned()) | 1253 if (isInFlowPositioned()) |
1253 offset += offsetForInFlowPosition(); | 1254 offset += offsetForInFlowPosition(); |
1254 | 1255 |
1255 if (container->hasOverflowClip()) | 1256 if (container->hasOverflowClip()) |
1256 offset -= toLayoutBox(container)->scrolledContentOffset(); | 1257 offset -= toLayoutBox(container)->scrolledContentOffset(); |
1257 | 1258 |
1258 return offset; | 1259 return offset; |
1259 } | 1260 } |
(...skipping 96 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
1356 return LayoutUnit(s->computedLineHeight()); | 1357 return LayoutUnit(s->computedLineHeight()); |
1357 } | 1358 } |
1358 | 1359 |
1359 return LayoutUnit(style()->computedLineHeight()); | 1360 return LayoutUnit(style()->computedLineHeight()); |
1360 } | 1361 } |
1361 | 1362 |
1362 int LayoutInline::baselinePosition(FontBaseline baselineType, | 1363 int LayoutInline::baselinePosition(FontBaseline baselineType, |
1363 bool firstLine, | 1364 bool firstLine, |
1364 LineDirectionMode direction, | 1365 LineDirectionMode direction, |
1365 LinePositionMode linePositionMode) const { | 1366 LinePositionMode linePositionMode) const { |
1366 ASSERT(linePositionMode == PositionOnContainingLine); | 1367 DCHECK_EQ(linePositionMode, PositionOnContainingLine); |
1367 const SimpleFontData* fontData = style(firstLine)->font().primaryFont(); | 1368 const SimpleFontData* fontData = style(firstLine)->font().primaryFont(); |
1368 DCHECK(fontData); | 1369 DCHECK(fontData); |
1369 if (!fontData) | 1370 if (!fontData) |
1370 return -1; | 1371 return -1; |
1371 const FontMetrics& fontMetrics = fontData->getFontMetrics(); | 1372 const FontMetrics& fontMetrics = fontData->getFontMetrics(); |
1372 return (fontMetrics.ascent(baselineType) + | 1373 return (fontMetrics.ascent(baselineType) + |
1373 (lineHeight(firstLine, direction, linePositionMode) - | 1374 (lineHeight(firstLine, direction, linePositionMode) - |
1374 fontMetrics.height()) / | 1375 fontMetrics.height()) / |
1375 2) | 1376 2) |
1376 .toInt(); | 1377 .toInt(); |
1377 } | 1378 } |
1378 | 1379 |
1379 LayoutSize LayoutInline::offsetForInFlowPositionedInline( | 1380 LayoutSize LayoutInline::offsetForInFlowPositionedInline( |
1380 const LayoutBox& child) const { | 1381 const LayoutBox& child) const { |
1381 // FIXME: This function isn't right with mixed writing modes. | 1382 // FIXME: This function isn't right with mixed writing modes. |
1382 | 1383 |
1383 ASSERT(isInFlowPositioned()); | 1384 DCHECK(isInFlowPositioned()); |
1384 if (!isInFlowPositioned()) | 1385 if (!isInFlowPositioned()) |
1385 return LayoutSize(); | 1386 return LayoutSize(); |
1386 | 1387 |
1387 // When we have an enclosing relpositioned inline, we need to add in the | 1388 // When we have an enclosing relpositioned inline, we need to add in the |
1388 // offset of the first line box from the rest of the content, but only in the | 1389 // offset of the first line box from the rest of the content, but only in the |
1389 // cases where we know we're positioned relative to the inline itself. | 1390 // cases where we know we're positioned relative to the inline itself. |
1390 | 1391 |
1391 LayoutSize logicalOffset; | 1392 LayoutSize logicalOffset; |
1392 LayoutUnit inlinePosition; | 1393 LayoutUnit inlinePosition; |
1393 LayoutUnit blockPosition; | 1394 LayoutUnit blockPosition; |
(...skipping 140 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
1534 paintInvalidator.invalidateDisplayItemClient(*box, invalidationReason); | 1535 paintInvalidator.invalidateDisplayItemClient(*box, invalidationReason); |
1535 } | 1536 } |
1536 | 1537 |
1537 // TODO(lunalu): Not to just dump 0, 0 as the x and y here | 1538 // TODO(lunalu): Not to just dump 0, 0 as the x and y here |
1538 LayoutRect LayoutInline::debugRect() const { | 1539 LayoutRect LayoutInline::debugRect() const { |
1539 IntRect linesBox = enclosingIntRect(linesBoundingBox()); | 1540 IntRect linesBox = enclosingIntRect(linesBoundingBox()); |
1540 return LayoutRect(IntRect(0, 0, linesBox.width(), linesBox.height())); | 1541 return LayoutRect(IntRect(0, 0, linesBox.width(), linesBox.height())); |
1541 } | 1542 } |
1542 | 1543 |
1543 } // namespace blink | 1544 } // namespace blink |
OLD | NEW |