Пример #1
0
TEST_F(VisualRectMappingTest, ContainerOverflowHidden) {
  setBodyInnerHTML(
      "<div id='container' style='position: absolute; top: 111px; left: 222px;"
      "    border: 10px solid red; overflow: hidden; width: 50px; height: "
      "80px;'>"
      "    <div id='target' style='box-shadow: 40px 20px black; width: 100px; "
      "height: 90px'></div>"
      "</div>");

  LayoutBlock* container =
      toLayoutBlock(getLayoutObjectByElementId("container"));
  EXPECT_EQ(LayoutUnit(), container->scrollTop());
  EXPECT_EQ(LayoutUnit(), container->scrollLeft());
  container->setScrollTop(LayoutUnit(27));
  container->setScrollLeft(LayoutUnit(28));
  document().view()->updateAllLifecyclePhases();

  LayoutBlock* target = toLayoutBlock(getLayoutObjectByElementId("target"));
  LayoutRect targetVisualRect = target->localVisualRect();
  // 140 = width(100) + box_shadow_offset_x(40)
  // 110 = height(90) + box_shadow_offset_y(20)
  EXPECT_EQ(LayoutRect(0, 0, 140, 110), targetVisualRect);
  LayoutRect rect = targetVisualRect;
  EXPECT_TRUE(target->mapToVisualRectInAncestorSpace(target, rect));
  EXPECT_EQ(LayoutRect(0, 0, 140, 110), rect);

  rect = targetVisualRect;
  EXPECT_TRUE(target->mapToVisualRectInAncestorSpace(container, rect));
  // Rect is not clipped by container's overflow clip.
  EXPECT_EQ(LayoutRect(10, 10, 140, 110), rect);
}
Пример #2
0
TEST_F(LayoutSVGRootTest, VisualRectMappingWithViewportClipAndBorder) {
  setBodyInnerHTML(
      "<svg id='root' style='border: 10px solid red; width: 200px; height: "
      "100px; overflow: hidden' viewBox='0 0 200 100'>"
      "   <rect id='rect' x='80' y='80' width='100' height='100'/>"
      "</svg>");

  const LayoutSVGRoot& root =
      *toLayoutSVGRoot(getLayoutObjectByElementId("root"));
  const LayoutSVGShape& svgRect =
      *toLayoutSVGShape(getLayoutObjectByElementId("rect"));

  LayoutRect rect = SVGLayoutSupport::visualRectInAncestorSpace(svgRect, root);
  // (80, 80, 100, 100) added by root's content rect offset from border rect,
  // clipped by (10, 10, 200, 100).
  EXPECT_EQ(LayoutRect(90, 90, 100, 20), rect);

  LayoutRect rootVisualRect =
      static_cast<const LayoutObject&>(root).localVisualRect();
  // SVG root with overflow:hidden doesn't include overflow from children, just
  // border box rect.
  EXPECT_EQ(LayoutRect(0, 0, 220, 120), rootVisualRect);

  rect = rootVisualRect;
  EXPECT_TRUE(root.mapToVisualRectInAncestorSpace(&root, rect));
  // LayoutSVGRoot should not apply overflow clip on its own rect.
  EXPECT_EQ(LayoutRect(0, 0, 220, 120), rect);
}
Пример #3
0
TEST_F(LayoutSVGRootTest, VisualRectMappingWithViewportClipWithoutBorder) {
  setBodyInnerHTML(
      "<svg id='root' style='width: 200px; height: 100px; overflow: hidden' "
      "viewBox='0 0 200 100'>"
      "   <rect id='rect' x='80' y='80' width='100' height='100'/>"
      "</svg>");

  const LayoutSVGRoot& root =
      *toLayoutSVGRoot(getLayoutObjectByElementId("root"));
  const LayoutSVGShape& svgRect =
      *toLayoutSVGShape(getLayoutObjectByElementId("rect"));

  LayoutRect rect = SVGLayoutSupport::visualRectInAncestorSpace(svgRect, root);
  // (80, 80, 100, 100) clipped by (0, 0, 200, 100).
  EXPECT_EQ(LayoutRect(80, 80, 100, 20), rect);

  LayoutRect rootVisualRect =
      static_cast<const LayoutObject&>(root).localVisualRect();
  // SVG root doesn't have box decoration background, so just use clipped
  // overflow of children.
  EXPECT_EQ(LayoutRect(80, 80, 100, 20), rootVisualRect);

  rect = rootVisualRect;
  EXPECT_TRUE(root.mapToVisualRectInAncestorSpace(&root, rect));
  EXPECT_EQ(LayoutRect(80, 80, 100, 20), rect);
}
Пример #4
0
TEST_F(LayoutSVGRootTest, VisualRectMappingWithoutViewportClipWithBorder) {
  setBodyInnerHTML(
      "<svg id='root' style='border: 10px solid red; width: 200px; height: "
      "100px; overflow: visible' viewBox='0 0 200 100'>"
      "   <rect id='rect' x='80' y='80' width='100' height='100'/>"
      "</svg>");

  const LayoutSVGRoot& root =
      *toLayoutSVGRoot(getLayoutObjectByElementId("root"));
  const LayoutSVGShape& svgRect =
      *toLayoutSVGShape(getLayoutObjectByElementId("rect"));

  LayoutRect rect = SVGLayoutSupport::visualRectInAncestorSpace(svgRect, root);
  // (80, 80, 100, 100) added by root's content rect offset from border rect,
  // not clipped.
  EXPECT_EQ(LayoutRect(90, 90, 100, 100), rect);

  LayoutRect rootVisualRect =
      static_cast<const LayoutObject&>(root).localVisualRect();
  // SVG root's overflow includes overflow from descendants.
  EXPECT_EQ(LayoutRect(0, 0, 220, 190), rootVisualRect);

  rect = rootVisualRect;
  EXPECT_TRUE(root.mapToVisualRectInAncestorSpace(&root, rect));
  EXPECT_EQ(LayoutRect(0, 0, 220, 190), rect);
}
Пример #5
0
TEST_F(VisualRectMappingTest, ContainerFlippedWritingMode) {
  setBodyInnerHTML(
      "<div id='container' style='writing-mode: vertical-rl; position: "
      "absolute; top: 111px; left: 222px'>"
      "    <div id='target' style='box-shadow: 40px 20px black; width: 100px; "
      "height: 90px'></div>"
      "    <div style='width: 100px; height: 100px'></div>"
      "</div>");

  LayoutBlock* target = toLayoutBlock(getLayoutObjectByElementId("target"));
  LayoutRect targetVisualRect = target->localVisualRect();
  // -40 = -box_shadow_offset_x(40) (with target's top-right corner as the
  // origin)
  // 140 = width(100) + box_shadow_offset_x(40)
  // 110 = height(90) + box_shadow_offset_y(20)
  EXPECT_EQ(LayoutRect(-40, 0, 140, 110), targetVisualRect);

  LayoutRect rect = targetVisualRect;
  target->flipForWritingMode(rect);
  EXPECT_TRUE(target->mapToVisualRectInAncestorSpace(target, rect));
  // This rect is in physical coordinates of target.
  EXPECT_EQ(LayoutRect(0, 0, 140, 110), rect);

  LayoutBlock* container =
      toLayoutBlock(getLayoutObjectByElementId("container"));
  rect = targetVisualRect;
  target->flipForWritingMode(rect);
  EXPECT_TRUE(target->mapToVisualRectInAncestorSpace(container, rect));
  // 100 is the physical x location of target in container.
  EXPECT_EQ(LayoutRect(100, 0, 140, 110), rect);
  rect = targetVisualRect;
  target->flipForWritingMode(rect);
  EXPECT_TRUE(target->mapToVisualRectInAncestorSpace(&layoutView(), rect));
  EXPECT_EQ(LayoutRect(322, 111, 140, 110), rect);
  checkPaintInvalidationStateRectMapping(rect, targetVisualRect, *target,
                                         layoutView(), layoutView());

  LayoutRect containerVisualRect = container->localVisualRect();
  EXPECT_EQ(LayoutRect(0, 0, 200, 100), containerVisualRect);
  rect = containerVisualRect;
  container->flipForWritingMode(rect);
  EXPECT_TRUE(container->mapToVisualRectInAncestorSpace(container, rect));
  EXPECT_EQ(LayoutRect(0, 0, 200, 100), rect);
  rect = containerVisualRect;
  container->flipForWritingMode(rect);
  EXPECT_TRUE(container->mapToVisualRectInAncestorSpace(&layoutView(), rect));
  EXPECT_EQ(LayoutRect(222, 111, 200, 100), rect);
  checkPaintInvalidationStateRectMapping(rect, containerVisualRect, *container,
                                         layoutView(), layoutView());
}
Пример #6
0
TEST_F(LayoutObjectTest, PaintingLayerOfOverflowClipLayerUnderColumnSpanAll) {
  setBodyInnerHTML(
      "<div id='columns' style='columns: 3'>"
      "  <div style='column-span: all'>"
      "    <div id='overflow-clip-layer' style='height: 100px; overflow: "
      "hidden'></div>"
      "  </div>"
      "</div>");

  LayoutObject* overflowClipObject =
      getLayoutObjectByElementId("overflow-clip-layer");
  LayoutBlock* columns = toLayoutBlock(getLayoutObjectByElementId("columns"));
  EXPECT_EQ(columns->layer(), overflowClipObject->paintingLayer());
}
Пример #7
0
TEST_F(VisualRectMappingTest,
       DifferentPaintInvalidaitionContainerForAbsolutePosition) {
  enableCompositing();
  document().frame()->settings()->setPreferCompositingToLCDTextEnabled(true);

  setBodyInnerHTML(
      "<div id='stacking-context' style='opacity: 0.9; background: blue; "
      "will-change: transform'>"
      "    <div id='scroller' style='overflow: scroll; width: 80px; height: "
      "80px'>"
      "        <div id='absolute' style='position: absolute; top: 111px; left: "
      "222px; width: 50px; height: 50px; background: green'></div>"
      "        <div id='normal-flow' style='width: 2000px; height: 2000px; "
      "background: yellow'></div>"
      "    </div>"
      "</div>");

  LayoutBlock* scroller = toLayoutBlock(getLayoutObjectByElementId("scroller"));
  scroller->setScrollTop(LayoutUnit(77));
  scroller->setScrollLeft(LayoutUnit(88));
  document().view()->updateAllLifecyclePhases();

  LayoutBlock* normalFlow =
      toLayoutBlock(getLayoutObjectByElementId("normal-flow"));
  EXPECT_EQ(scroller, &normalFlow->containerForPaintInvalidation());

  LayoutRect normalFlowVisualRect = normalFlow->localVisualRect();
  EXPECT_EQ(LayoutRect(0, 0, 2000, 2000), normalFlowVisualRect);
  LayoutRect rect = normalFlowVisualRect;
  EXPECT_TRUE(normalFlow->mapToVisualRectInAncestorSpace(scroller, rect));
  EXPECT_EQ(LayoutRect(0, 0, 2000, 2000), rect);
  checkPaintInvalidationStateRectMapping(rect, normalFlowVisualRect,
                                         *normalFlow, layoutView(), *scroller);

  LayoutBlock* stackingContext =
      toLayoutBlock(getLayoutObjectByElementId("stacking-context"));
  LayoutBlock* absolute = toLayoutBlock(getLayoutObjectByElementId("absolute"));
  EXPECT_EQ(stackingContext, &absolute->containerForPaintInvalidation());
  EXPECT_EQ(stackingContext, absolute->container());

  LayoutRect absoluteVisualRect = absolute->localVisualRect();
  EXPECT_EQ(LayoutRect(0, 0, 50, 50), absoluteVisualRect);
  rect = absoluteVisualRect;
  EXPECT_TRUE(absolute->mapToVisualRectInAncestorSpace(stackingContext, rect));
  EXPECT_EQ(LayoutRect(222, 111, 50, 50), rect);
  checkPaintInvalidationStateRectMapping(rect, absoluteVisualRect, *absolute,
                                         layoutView(), *stackingContext);
}
Пример #8
0
TEST_F(PaintLayerClipperTest, NestedContainPaintClip) {
  setBodyInnerHTML(
      "<div style='contain: paint; width: 200px; height: 200px; overflow: "
      "auto'>"
      "  <div id='target' style='contain: paint; height: 400px'>"
      "  </div>"
      "</div>");

  LayoutRect infiniteRect(LayoutRect::infiniteIntRect());
  PaintLayer* layer =
      toLayoutBoxModelObject(getLayoutObjectByElementId("target"))->layer();
  ClipRectsContext context(layer->parent(),
                           PaintingClipRectsIgnoringOverflowClip);
  LayoutRect layerBounds;
  ClipRect backgroundRect, foregroundRect;
  layer->clipper().calculateRects(context, infiniteRect, layerBounds,
                                  backgroundRect, foregroundRect);
  EXPECT_EQ(LayoutRect(0, 0, 200, 400), backgroundRect.rect());
  EXPECT_EQ(LayoutRect(0, 0, 200, 400), foregroundRect.rect());
  EXPECT_EQ(LayoutRect(0, 0, 200, 400), layerBounds);

  ClipRectsContext contextClip(layer->parent(), PaintingClipRects);
  layer->clipper().calculateRects(contextClip, infiniteRect, layerBounds,
                                  backgroundRect, foregroundRect);
  EXPECT_EQ(LayoutRect(0, 0, 200, 200), backgroundRect.rect());
  EXPECT_EQ(LayoutRect(0, 0, 200, 200), foregroundRect.rect());
  EXPECT_EQ(LayoutRect(0, 0, 200, 400), layerBounds);
}
Пример #9
0
TEST_F(PaintControllerPaintTestForSlimmingPaintV2, CompositingFold) {
  setBodyInnerHTML(
      "<div id='div' style='width: 200px; height: 200px; opacity: 0.5'>"
      "  <div style='width: 100px; height: 100px; background-color: "
      "blue'></div>"
      "</div>");
  PaintLayer& htmlLayer =
      *toLayoutBoxModelObject(document().documentElement()->layoutObject())
           ->layer();
  LayoutBlock& div = *toLayoutBlock(getLayoutObjectByElementId("div"));
  LayoutObject& subDiv = *div.firstChild();

  EXPECT_DISPLAY_LIST(
      rootPaintController().getDisplayItemList(), 8,
      TestDisplayItem(layoutView(),
                      DisplayItem::kClipFrameToVisibleContentRect),
      TestDisplayItem(*layoutView().layer(), DisplayItem::kSubsequence),
      TestDisplayItem(layoutView(), documentBackgroundType),
      TestDisplayItem(htmlLayer, DisplayItem::kSubsequence),
      // The begin and end compositing display items have been folded into this
      // one.
      TestDisplayItem(subDiv, backgroundType),
      TestDisplayItem(htmlLayer, DisplayItem::kEndSubsequence),
      TestDisplayItem(*layoutView().layer(), DisplayItem::kEndSubsequence),
      TestDisplayItem(layoutView(),
                      DisplayItem::clipTypeToEndClipType(
                          DisplayItem::kClipFrameToVisibleContentRect)));
}
Пример #10
0
TEST_F(VisualRectMappingTest, LayoutInline) {
  document().setBaseURLOverride(KURL(ParsedURLString, "http://test.com"));
  setBodyInnerHTML(
      "<style>body { margin: 0; }</style>"
      "<div id='container' style='overflow: scroll; width: 50px; height: 50px'>"
      "  <span><img style='width: 20px; height: 100px'></span>"
      "  <span id=leaf></span></div>");

  LayoutBlock* container =
      toLayoutBlock(getLayoutObjectByElementId("container"));
  LayoutObject* leaf = container->lastChild();

  container->setScrollTop(LayoutUnit(50));
  LayoutRect originalRect(0, 60, 20, 80);
  LayoutRect rect = originalRect;
  EXPECT_TRUE(leaf->mapToVisualRectInAncestorSpace(container, rect));
  rect.move(-container->scrolledContentOffset());
  EXPECT_EQ(rect, LayoutRect(0, 10, 20, 80));

  rect = originalRect;
  EXPECT_TRUE(leaf->mapToVisualRectInAncestorSpace(&layoutView(), rect));
  EXPECT_EQ(rect, LayoutRect(0, 10, 20, 40));
  checkPaintInvalidationStateRectMapping(rect, originalRect, *leaf,
                                         layoutView(), layoutView());

  rect = LayoutRect(0, 60, 80, 0);
  EXPECT_TRUE(
      leaf->mapToVisualRectInAncestorSpace(container, rect, EdgeInclusive));
  rect.move(-container->scrolledContentOffset());
  EXPECT_EQ(rect, LayoutRect(0, 10, 80, 0));
}
Пример #11
0
TEST_F(VisualRectMappingTest, LayoutText) {
  setBodyInnerHTML(
      "<style>body { margin: 0; }</style>"
      "<div id='container' style='overflow: scroll; width: 50px; height: 50px'>"
      "  <span><img style='width: 20px; height: 100px'></span>"
      "  text text text text text text text"
      "</div>");

  LayoutBlock* container =
      toLayoutBlock(getLayoutObjectByElementId("container"));
  LayoutText* text = toLayoutText(container->lastChild());

  container->setScrollTop(LayoutUnit(50));
  LayoutRect originalRect(0, 60, 20, 80);
  LayoutRect rect = originalRect;
  EXPECT_TRUE(text->mapToVisualRectInAncestorSpace(container, rect));
  rect.move(-container->scrolledContentOffset());
  EXPECT_EQ(rect, LayoutRect(0, 10, 20, 80));

  rect = originalRect;
  EXPECT_TRUE(text->mapToVisualRectInAncestorSpace(&layoutView(), rect));
  EXPECT_EQ(rect, LayoutRect(0, 10, 20, 40));
  checkPaintInvalidationStateRectMapping(rect, originalRect, *text,
                                         layoutView(), layoutView());

  rect = LayoutRect(0, 60, 80, 0);
  EXPECT_TRUE(
      text->mapToVisualRectInAncestorSpace(container, rect, EdgeInclusive));
  rect.move(-container->scrolledContentOffset());
  EXPECT_EQ(rect, LayoutRect(0, 10, 80, 0));
}
Пример #12
0
TEST_F(VisualRectMappingTest, SelfFlippedWritingMode) {
  setBodyInnerHTML(
      "<div id='target' style='writing-mode: vertical-rl; box-shadow: 40px "
      "20px black;"
      "    width: 100px; height: 50px; position: absolute; top: 111px; left: "
      "222px'>"
      "</div>");

  LayoutBlock* target = toLayoutBlock(getLayoutObjectByElementId("target"));
  LayoutRect visualRect = target->localVisualRect();
  // -40 = -box_shadow_offset_x(40) (with target's top-right corner as the
  // origin)
  // 140 = width(100) + box_shadow_offset_x(40)
  // 70 = height(50) + box_shadow_offset_y(20)
  EXPECT_EQ(LayoutRect(-40, 0, 140, 70), visualRect);

  LayoutRect rect = visualRect;
  // TODO(wkorman): The calls to flipForWritingMode() here and in other test
  // cases below are necessary because mapToVisualRectInAncestorSpace()
  // currently expects the input rect to be in "physical coordinates" (*not*
  // "physical coordinates with flipped block-flow direction"), see
  // LayoutBoxModelObject.h.
  target->flipForWritingMode(rect);
  EXPECT_TRUE(target->mapToVisualRectInAncestorSpace(target, rect));
  // This rect is in physical coordinates of target.
  EXPECT_EQ(LayoutRect(0, 0, 140, 70), rect);

  rect = visualRect;
  target->flipForWritingMode(rect);
  EXPECT_TRUE(target->mapToVisualRectInAncestorSpace(&layoutView(), rect));
  EXPECT_EQ(LayoutRect(222, 111, 140, 70), rect);
  checkPaintInvalidationStateRectMapping(rect, visualRect, *target,
                                         layoutView(), layoutView());
}
Пример #13
0
TEST_F(VisualRectMappingTest, LayoutViewSubpixelRounding) {
  document().setBaseURLOverride(KURL(ParsedURLString, "http://test.com"));
  setBodyInnerHTML(
      "<style>body { margin: 0; }</style>"
      "<div id=frameContainer style='position: relative; left: 0.5px'>"
      "  <iframe style='position: relative; left: 0.5px' "
      "src='http://test.com' width='200' height='200' frameBorder='0'></iframe>"
      "</div>");
  setChildFrameHTML(
      "<style>body { margin: 0; }</style><div id='target' style='position: "
      "relative; width: 100px; height: 100px; left: 0.5px'>");

  document().view()->updateAllLifecyclePhases();

  LayoutBlock* frameContainer =
      toLayoutBlock(getLayoutObjectByElementId("frameContainer"));
  LayoutObject* target =
      childDocument().getElementById("target")->layoutObject();
  LayoutRect rect(0, 0, 100, 100);
  EXPECT_TRUE(target->mapToVisualRectInAncestorSpace(frameContainer, rect));
  // When passing from the iframe to the parent frame, the rect of (0.5, 0, 100,
  // 100) is expanded to (0, 0, 100, 100), and then offset by the 0.5 offset of
  // frameContainer.
  EXPECT_EQ(LayoutRect(LayoutPoint(DoublePoint(0.5, 0)), LayoutSize(101, 100)),
            rect);
}
TEST_F(LayoutBoxTest, BackgroundObscuredInRect)
{
    setBodyInnerHTML("<style>.column { width: 295.4px; padding-left: 10.4px; } .white-background { background: red; position: relative; overflow: hidden; border-radius: 1px; }"
        ".black-background { height: 100px; background: black; color: white; } </style>"
        "<div class='column'> <div> <div id='target' class='white-background'> <div class='black-background'></div> </div> </div> </div>");
    LayoutObject* layoutObject = getLayoutObjectByElementId("target");
    ASSERT_TRUE(layoutObject);
    ASSERT_TRUE(layoutObject->boxDecorationBackgroundIsKnownToBeObscured());
}
Пример #15
0
TEST_F(VisualRectMappingTest, ContainerAndTargetDifferentFlippedWritingMode) {
  setBodyInnerHTML(
      "<div id='container' style='writing-mode: vertical-rl; position: "
      "absolute; top: 111px; left: 222px;"
      "    border: solid red; border-width: 10px 20px 30px 40px;"
      "    overflow: scroll; width: 50px; height: 80px'>"
      "    <div id='target' style='writing-mode: vertical-lr; box-shadow: 40px "
      "20px black; width: 100px; height: 90px'></div>"
      "    <div style='width: 100px; height: 100px'></div>"
      "</div>");

  LayoutBlock* container =
      toLayoutBlock(getLayoutObjectByElementId("container"));
  EXPECT_EQ(LayoutUnit(), container->scrollTop());
  // The initial scroll offset is to the left-most because of flipped blocks
  // writing mode.
  // 150 = total_layout_overflow(100 + 100) - width(50)
  EXPECT_EQ(LayoutUnit(150), container->scrollLeft());
  container->setScrollTop(LayoutUnit(7));
  container->setScrollLeft(
      LayoutUnit(142));  // Scroll to the right by 8 pixels.
  document().view()->updateAllLifecyclePhases();

  LayoutBlock* target = toLayoutBlock(getLayoutObjectByElementId("target"));
  LayoutRect targetVisualRect = target->localVisualRect();
  // 140 = width(100) + box_shadow_offset_x(40)
  // 110 = height(90) + box_shadow_offset_y(20)
  EXPECT_EQ(LayoutRect(0, 0, 140, 110), targetVisualRect);

  LayoutRect rect = targetVisualRect;
  EXPECT_TRUE(target->mapToVisualRectInAncestorSpace(target, rect));
  // This rect is in physical coordinates of target.
  EXPECT_EQ(LayoutRect(0, 0, 140, 110), rect);

  rect = targetVisualRect;
  EXPECT_TRUE(target->mapToVisualRectInAncestorSpace(container, rect));
  rect.move(-container->scrolledContentOffset());
  // -2 = target_physical_x(100) + container_border_left(40) - scroll_left(142)
  // 3 = target_y(0) + container_border_top(10) - scroll_top(7)
  // Rect is not clipped by container's overflow clip.
  EXPECT_EQ(LayoutRect(-2, 3, 140, 110), rect);
}
Пример #16
0
TEST_F(VisualRectMappingTest, ContainerFlippedWritingModeAndOverflowHidden) {
  setBodyInnerHTML(
      "<div id='container' style='writing-mode: vertical-rl; position: "
      "absolute; top: 111px; left: 222px;"
      "    border: solid red; border-width: 10px 20px 30px 40px;"
      "    overflow: hidden; width: 50px; height: 80px'>"
      "    <div id='target' style='box-shadow: 40px 20px black; width: 100px; "
      "height: 90px'></div>"
      "    <div style='width: 100px; height: 100px'></div>"
      "</div>");

  LayoutBlock* container =
      toLayoutBlock(getLayoutObjectByElementId("container"));
  EXPECT_EQ(LayoutUnit(), container->scrollTop());
  // The initial scroll offset is to the left-most because of flipped blocks
  // writing mode.
  // 150 = total_layout_overflow(100 + 100) - width(50)
  EXPECT_EQ(LayoutUnit(150), container->scrollLeft());
  container->setScrollTop(LayoutUnit(7));
  container->setScrollLeft(LayoutUnit(82));  // Scroll to the right by 8 pixels.
  document().view()->updateAllLifecyclePhases();

  LayoutBlock* target = toLayoutBlock(getLayoutObjectByElementId("target"));
  LayoutRect targetVisualRect = target->localVisualRect();
  // -40 = -box_shadow_offset_x(40) (with target's top-right corner as the
  // origin)
  // 140 = width(100) + box_shadow_offset_x(40)
  // 110 = height(90) + box_shadow_offset_y(20)
  EXPECT_EQ(LayoutRect(-40, 0, 140, 110), targetVisualRect);

  LayoutRect rect = targetVisualRect;
  target->flipForWritingMode(rect);
  EXPECT_TRUE(target->mapToVisualRectInAncestorSpace(target, rect));
  // This rect is in physical coordinates of target.
  EXPECT_EQ(LayoutRect(0, 0, 140, 110), rect);

  rect = targetVisualRect;
  target->flipForWritingMode(rect);
  EXPECT_TRUE(target->mapToVisualRectInAncestorSpace(container, rect));
  // 58 = target_physical_x(100) + container_border_left(40) - scroll_left(58)
  EXPECT_EQ(LayoutRect(-10, 10, 140, 110), rect);
}
Пример #17
0
TEST_F(PaintLayerTest, PaintingExtentReflectionWithTransform) {
  setBodyInnerHTML(
      "<div id='target' style='background-color: blue; position: absolute;"
      "    width: 110px; height: 120px; top: 40px; left: 60px;"
      "    -webkit-box-reflect: below 3px; transform: translateX(30px)'>"
      "</div>");

  PaintLayer* layer =
      toLayoutBoxModelObject(getLayoutObjectByElementId("target"))->layer();
  EXPECT_EQ(
      LayoutRect(90, 40, 110, 243),
      layer->paintingExtent(document().layoutView()->layer(), LayoutSize(), 0));
}
Пример #18
0
TEST_F(PaintLayerClipperTest, LocalClipRectFixedUnderTransform) {
  setBodyInnerHTML(
      "<div id='transformed'"
      "    style='will-change: transform; width: 100px; height: 100px;"
      "    overflow: hidden'>"
      "  <div id='fixed' "
      "      style='position: fixed; width: 100px; height: 100px;"
      "      top: -50px'>"
      "   </div>"
      "</div>");

  LayoutRect infiniteRect(LayoutRect::infiniteIntRect());
  PaintLayer* transformed =
      toLayoutBoxModelObject(getLayoutObjectByElementId("transformed"))
          ->layer();
  PaintLayer* fixed =
      toLayoutBoxModelObject(getLayoutObjectByElementId("fixed"))->layer();

  EXPECT_EQ(LayoutRect(0, 0, 100, 100),
            transformed->clipper().localClipRect(transformed));
  EXPECT_EQ(LayoutRect(0, 50, 100, 100),
            fixed->clipper().localClipRect(transformed));
}
Пример #19
0
TEST_F(VisualRectMappingTest,
       ContainerOfAbsoluteAbovePaintInvalidationContainer) {
  enableCompositing();
  document().frame()->settings()->setPreferCompositingToLCDTextEnabled(true);

  setBodyInnerHTML(
      "<div id='container' style='position: absolute; top: 88px; left: 99px'>"
      "    <div style='height: 222px'></div>"
      // This div makes stacking-context composited.
      "    <div style='position: absolute; width: 1px; height: 1px; "
      "background:yellow; will-change: transform'></div>"
      // This stacking context is paintInvalidationContainer of the absolute
      // child, but not a container of it.
      "    <div id='stacking-context' style='opacity: 0.9'>"
      "        <div id='absolute' style='position: absolute; top: 50px; left: "
      "50px; width: 50px; height: 50px; background: green'></div>"
      "    </div>"
      "</div>");

  LayoutBlock* stackingContext =
      toLayoutBlock(getLayoutObjectByElementId("stacking-context"));
  LayoutBlock* absolute = toLayoutBlock(getLayoutObjectByElementId("absolute"));
  LayoutBlock* container =
      toLayoutBlock(getLayoutObjectByElementId("container"));
  EXPECT_EQ(stackingContext, &absolute->containerForPaintInvalidation());
  EXPECT_EQ(container, absolute->container());

  LayoutRect absoluteVisualRect = absolute->localVisualRect();
  EXPECT_EQ(LayoutRect(0, 0, 50, 50), absoluteVisualRect);
  LayoutRect rect = absoluteVisualRect;
  EXPECT_TRUE(absolute->mapToVisualRectInAncestorSpace(stackingContext, rect));
  // -172 = top(50) - y_offset_of_stacking_context(222)
  EXPECT_EQ(LayoutRect(50, -172, 50, 50), rect);
  checkPaintInvalidationStateRectMapping(rect, absoluteVisualRect, *absolute,
                                         layoutView(), *stackingContext);
}
Пример #20
0
TEST_F(PaintControllerPaintTestForSlimmingPaintV2, ChunkIdClientCacheFlag) {
  setBodyInnerHTML(
      "<div id='div' style='width: 200px; height: 200px; opacity: 0.5'>"
      "  <div style='width: 100px; height: 100px; background-color: "
      "blue'></div>"
      "  <div style='width: 100px; height: 100px; background-color: "
      "blue'></div>"
      "</div>");
  PaintLayer& htmlLayer =
      *toLayoutBoxModelObject(document().documentElement()->layoutObject())
           ->layer();
  LayoutBlock& div = *toLayoutBlock(getLayoutObjectByElementId("div"));
  LayoutObject& subDiv = *div.firstChild();
  LayoutObject& subDiv2 = *subDiv.nextSibling();
  EXPECT_DISPLAY_LIST(
      rootPaintController().getDisplayItemList(), 11,
      TestDisplayItem(layoutView(),
                      DisplayItem::kClipFrameToVisibleContentRect),
      TestDisplayItem(*layoutView().layer(), DisplayItem::kSubsequence),
      TestDisplayItem(layoutView(), documentBackgroundType),
      TestDisplayItem(htmlLayer, DisplayItem::kSubsequence),
      TestDisplayItem(div, DisplayItem::kBeginCompositing),
      TestDisplayItem(subDiv, backgroundType),
      TestDisplayItem(subDiv2, backgroundType),
      TestDisplayItem(div, DisplayItem::kEndCompositing),
      TestDisplayItem(htmlLayer, DisplayItem::kEndSubsequence),
      TestDisplayItem(*layoutView().layer(), DisplayItem::kEndSubsequence),
      TestDisplayItem(layoutView(),
                      DisplayItem::clipTypeToEndClipType(
                          DisplayItem::kClipFrameToVisibleContentRect)));

  const PaintChunk& backgroundChunk = rootPaintController().paintChunks()[0];
  EXPECT_TRUE(backgroundChunk.properties.scroll->isRoot());

  const EffectPaintPropertyNode* effectNode = div.paintProperties()->effect();
  EXPECT_EQ(0.5f, effectNode->opacity());
  const PaintChunk& chunk = rootPaintController().paintChunks()[1];
  EXPECT_EQ(*div.layer(), chunk.id->client);
  EXPECT_EQ(effectNode, chunk.properties.effect.get());

  EXPECT_FALSE(div.layer()->isJustCreated());
  // Client used by only paint chunks and non-cachaeable display items but not
  // by any cacheable display items won't be marked as validly cached.
  EXPECT_FALSE(rootPaintController().clientCacheIsValid(*div.layer()));
  EXPECT_FALSE(rootPaintController().clientCacheIsValid(div));
  EXPECT_TRUE(rootPaintController().clientCacheIsValid(subDiv));
}
Пример #21
0
TEST_F(VisualRectMappingTest, ContainPaint) {
  setBodyInnerHTML(
      "<div id='container' style='position: absolute; top: 0px; left: 0px; "
      "width: 200px; height: 200px; contain: paint'>"
      "    <div id='target' style='width: 400px; height: 400px'></div>"
      "    </div>"
      "</div>");

  LayoutBox* target = toLayoutBox(getLayoutObjectByElementId("target"));

  LayoutRect targetVisualRect = target->localVisualRect();
  EXPECT_EQ(LayoutRect(0, 0, 400, 400), targetVisualRect);
  LayoutRect rect = targetVisualRect;
  EXPECT_TRUE(target->mapToVisualRectInAncestorSpace(&layoutView(), rect));
  EXPECT_EQ(LayoutRect(0, 0, 200, 200), rect);
  checkPaintInvalidationStateRectMapping(rect, targetVisualRect, *target,
                                         layoutView(), layoutView());
}
Пример #22
0
TEST_F(VisualRectMappingTest, LayoutView) {
  document().setBaseURLOverride(KURL(ParsedURLString, "http://test.com"));
  setBodyInnerHTML(
      "<style>body { margin: 0; }</style>"
      "<div id=frameContainer>"
      "  <iframe src='http://test.com' width='50' height='50' "
      "frameBorder='0'></iframe>"
      "</div>");
  setChildFrameHTML(
      "<style>body { margin: 0; }</style><span><img style='width: 20px; "
      "height: 100px'></span>text text text");

  document().view()->updateAllLifecyclePhases();

  LayoutBlock* frameContainer =
      toLayoutBlock(getLayoutObjectByElementId("frameContainer"));
  LayoutBlock* frameBody =
      toLayoutBlock(childDocument().body()->layoutObject());
  LayoutText* frameText = toLayoutText(frameBody->lastChild());

  // This case involves clipping: frame height is 50, y-coordinate of result
  // rect is 13, so height should be clipped to (50 - 13) == 37.
  childDocument().view()->setScrollOffset(ScrollOffset(0, 47),
                                          ProgrammaticScroll);
  LayoutRect originalRect(4, 60, 20, 80);
  LayoutRect rect = originalRect;
  EXPECT_TRUE(frameText->mapToVisualRectInAncestorSpace(frameContainer, rect));
  EXPECT_EQ(rect, LayoutRect(4, 13, 20, 37));

  rect = originalRect;
  EXPECT_TRUE(frameText->mapToVisualRectInAncestorSpace(&layoutView(), rect));
  EXPECT_EQ(rect, LayoutRect(4, 13, 20, 37));
  checkPaintInvalidationStateRectMapping(rect, originalRect, *frameText,
                                         layoutView(), layoutView());

  rect = LayoutRect(4, 60, 0, 80);
  EXPECT_TRUE(frameText->mapToVisualRectInAncestorSpace(frameContainer, rect,
                                                        EdgeInclusive));
  EXPECT_EQ(rect, LayoutRect(4, 13, 0, 37));
}
Пример #23
0
TEST_F(VisualRectMappingTest, LayoutViewDisplayNone) {
  document().setBaseURLOverride(KURL(ParsedURLString, "http://test.com"));
  setBodyInnerHTML(
      "<style>body { margin: 0; }</style>"
      "<div id=frameContainer>"
      "  <iframe id='frame' src='http://test.com' width='50' height='50' "
      "frameBorder='0'></iframe>"
      "</div>");
  setChildFrameHTML(
      "<style>body { margin: 0; }</style><div "
      "style='width:100px;height:100px;'></div>");

  document().view()->updateAllLifecyclePhases();

  LayoutBlock* frameContainer =
      toLayoutBlock(getLayoutObjectByElementId("frameContainer"));
  LayoutBlock* frameBody =
      toLayoutBlock(childDocument().body()->layoutObject());
  LayoutBlock* frameDiv = toLayoutBlock(frameBody->lastChild());

  // This part is copied from the LayoutView test, just to ensure that the
  // mapped rect is valid before display:none is set on the iframe.
  childDocument().view()->setScrollOffset(ScrollOffset(0, 47),
                                          ProgrammaticScroll);
  LayoutRect originalRect(4, 60, 20, 80);
  LayoutRect rect = originalRect;
  EXPECT_TRUE(frameDiv->mapToVisualRectInAncestorSpace(frameContainer, rect));
  EXPECT_EQ(rect, LayoutRect(4, 13, 20, 37));

  Element* frameElement = document().getElementById("frame");
  frameElement->setInlineStyleProperty(CSSPropertyDisplay, "none");
  document().view()->updateAllLifecyclePhases();

  rect = originalRect;
  EXPECT_FALSE(frameDiv->mapToVisualRectInAncestorSpace(&layoutView(), rect));
  EXPECT_EQ(rect, LayoutRect());
}
Пример #24
0
TEST_F(VisualRectMappingTest, ContainerFlippedWritingModeAndOverflowScroll) {
  setBodyInnerHTML(
      "<div id='container' style='writing-mode: vertical-rl; position: "
      "absolute; top: 111px; left: 222px;"
      "    border: solid red; border-width: 10px 20px 30px 40px;"
      "    overflow: scroll; width: 50px; height: 80px'>"
      "    <div id='target' style='box-shadow: 40px 20px black; width: 100px; "
      "height: 90px'></div>"
      "    <div style='width: 100px; height: 100px'></div>"
      "</div>");

  LayoutBlock* container =
      toLayoutBlock(getLayoutObjectByElementId("container"));
  EXPECT_EQ(LayoutUnit(), container->scrollTop());
  // The initial scroll offset is to the left-most because of flipped blocks
  // writing mode.
  // 150 = total_layout_overflow(100 + 100) - width(50)
  EXPECT_EQ(LayoutUnit(150), container->scrollLeft());
  container->setScrollTop(LayoutUnit(7));
  container->setScrollLeft(
      LayoutUnit(142));  // Scroll to the right by 8 pixels.
  document().view()->updateAllLifecyclePhases();

  LayoutBlock* target = toLayoutBlock(getLayoutObjectByElementId("target"));
  LayoutRect targetVisualRect = target->localVisualRect();
  // -40 = -box_shadow_offset_x(40) (with target's top-right corner as the
  // origin)
  // 140 = width(100) + box_shadow_offset_x(40)
  // 110 = height(90) + box_shadow_offset_y(20)
  EXPECT_EQ(LayoutRect(-40, 0, 140, 110), targetVisualRect);

  LayoutRect rect = targetVisualRect;
  target->flipForWritingMode(rect);
  EXPECT_TRUE(target->mapToVisualRectInAncestorSpace(target, rect));
  // This rect is in physical coordinates of target.
  EXPECT_EQ(LayoutRect(0, 0, 140, 110), rect);

  rect = targetVisualRect;
  target->flipForWritingMode(rect);
  EXPECT_TRUE(target->mapToVisualRectInAncestorSpace(container, rect));
  rect.move(-container->scrolledContentOffset());
  // -2 = target_physical_x(100) + container_border_left(40) - scroll_left(142)
  // 3 = target_y(0) + container_border_top(10) - scroll_top(7)
  // Rect is clipped by container's overflow clip because of overflow:scroll.
  EXPECT_EQ(LayoutRect(-2, 3, 140, 110), rect);

  rect = targetVisualRect;
  target->flipForWritingMode(rect);
  EXPECT_TRUE(target->mapToVisualRectInAncestorSpace(&layoutView(), rect));
  // (-2, 3, 140, 100) is first clipped by container's overflow clip, to
  // (40, 10, 50, 80), then is added by container's offset in LayoutView
  // (111, 222).
  // TODO(crbug.com/600039): rect.x() should be 262 (left + border-left), but is
  // offset
  // by extra horizontal border-widths because of layout error.
  EXPECT_EQ(LayoutRect(322, 121, 50, 80), rect);
  checkPaintInvalidationStateRectMapping(rect, targetVisualRect, *target,
                                         layoutView(), layoutView());

  LayoutRect containerVisualRect = container->localVisualRect();
  // Because container has overflow clip, its visual overflow doesn't include
  // overflow from children.
  // 110 = width(50) + border_left_width(40) + border_right_width(20)
  // 120 = height(80) + border_top_width(10) + border_bottom_width(30)
  EXPECT_EQ(LayoutRect(0, 0, 110, 120), containerVisualRect);

  rect = containerVisualRect;
  container->flipForWritingMode(rect);
  EXPECT_TRUE(container->mapToVisualRectInAncestorSpace(container, rect));
  EXPECT_EQ(LayoutRect(0, 0, 110, 120), rect);

  rect = containerVisualRect;
  container->flipForWritingMode(rect);
  EXPECT_TRUE(container->mapToVisualRectInAncestorSpace(&layoutView(), rect));
  // TODO(crbug.com/600039): rect.x() should be 222 (left), but is offset by
  // extra horizontal
  // border-widths because of layout error.
  EXPECT_EQ(LayoutRect(282, 111, 110, 120), rect);
  checkPaintInvalidationStateRectMapping(rect, containerVisualRect, *container,
                                         layoutView(), layoutView());
}
Пример #25
0
TEST_F(VisualRectMappingTest, ContainerOverflowScroll) {
  setBodyInnerHTML(
      "<div id='container' style='position: absolute; top: 111px; left: 222px;"
      "    border: 10px solid red; overflow: scroll; width: 50px; height: "
      "80px;'>"
      "    <div id='target' style='box-shadow: 40px 20px black; width: 100px; "
      "height: 90px'></div>"
      "</div>");

  LayoutBlock* container =
      toLayoutBlock(getLayoutObjectByElementId("container"));
  EXPECT_EQ(LayoutUnit(), container->scrollTop());
  EXPECT_EQ(LayoutUnit(), container->scrollLeft());
  container->setScrollTop(LayoutUnit(7));
  container->setScrollLeft(LayoutUnit(8));
  document().view()->updateAllLifecyclePhases();

  LayoutBlock* target = toLayoutBlock(getLayoutObjectByElementId("target"));
  LayoutRect targetVisualRect = target->localVisualRect();
  // 140 = width(100) + box_shadow_offset_x(40)
  // 110 = height(90) + box_shadow_offset_y(20)
  EXPECT_EQ(LayoutRect(0, 0, 140, 110), targetVisualRect);
  LayoutRect rect = targetVisualRect;
  EXPECT_TRUE(target->mapToVisualRectInAncestorSpace(target, rect));
  EXPECT_EQ(LayoutRect(0, 0, 140, 110), rect);

  rect = targetVisualRect;
  EXPECT_TRUE(target->mapToVisualRectInAncestorSpace(container, rect));
  rect.move(-container->scrolledContentOffset());
  // 2 = target_x(0) + container_border_left(10) - scroll_left(8)
  // 3 = target_y(0) + container_border_top(10) - scroll_top(7)
  // Rect is not clipped by container's overflow clip because of
  // overflow:scroll.
  EXPECT_EQ(LayoutRect(2, 3, 140, 110), rect);

  rect = targetVisualRect;
  EXPECT_TRUE(target->mapToVisualRectInAncestorSpace(&layoutView(), rect));
  // (2, 3, 140, 100) is first clipped by container's overflow clip, to
  // (10, 10, 50, 80), then is by added container's offset in LayoutView
  // (111, 222).
  EXPECT_EQ(LayoutRect(232, 121, 50, 80), rect);
  checkPaintInvalidationStateRectMapping(rect, targetVisualRect, *target,
                                         layoutView(), layoutView());

  LayoutRect containerVisualRect = container->localVisualRect();
  // Because container has overflow clip, its visual overflow doesn't include
  // overflow from children.
  // 70 = width(50) + border_left_width(10) + border_right_width(10)
  // 100 = height(80) + border_top_width(10) + border_bottom_width(10)
  EXPECT_EQ(LayoutRect(0, 0, 70, 100), containerVisualRect);
  rect = containerVisualRect;
  EXPECT_TRUE(container->mapToVisualRectInAncestorSpace(container, rect));
  // Container should not apply overflow clip on its own overflow rect.
  EXPECT_EQ(LayoutRect(0, 0, 70, 100), rect);

  rect = containerVisualRect;
  EXPECT_TRUE(container->mapToVisualRectInAncestorSpace(&layoutView(), rect));
  EXPECT_EQ(LayoutRect(222, 111, 70, 100), rect);
  checkPaintInvalidationStateRectMapping(rect, containerVisualRect, *container,
                                         layoutView(), layoutView());
}
 bool canPaintBackgroundOntoScrollingContentsLayer(const char* elementId) {
   PaintLayer* paintLayer =
       toLayoutBlock(getLayoutObjectByElementId(elementId))->layer();
   return paintLayer->canPaintBackgroundOntoScrollingContentsLayer();
 }