| 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 * (C) 2005 Allan Sandfeld Jensen (kde@carewolf.com) | 4 * (C) 2005 Allan Sandfeld Jensen (kde@carewolf.com) |
| 5 * (C) 2005, 2006 Samuel Weinig (sam.weinig@gmail.com) | 5 * (C) 2005, 2006 Samuel Weinig (sam.weinig@gmail.com) |
| 6 * Copyright (C) 2005, 2006, 2007, 2008, 2009, 2010 Apple Inc. All rights reserv
ed. | 6 * Copyright (C) 2005, 2006, 2007, 2008, 2009, 2010 Apple Inc. All rights reserv
ed. |
| 7 * Copyright (C) 2013 Adobe Systems Incorporated. All rights reserved. | 7 * Copyright (C) 2013 Adobe Systems Incorporated. All rights reserved. |
| 8 * | 8 * |
| 9 * This library is free software; you can redistribute it and/or | 9 * This library is free software; you can redistribute it and/or |
| 10 * modify it under the terms of the GNU Library General Public | 10 * modify it under the terms of the GNU Library General Public |
| (...skipping 464 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 475 | 475 |
| 476 LayoutRect localHitTestRect = hitTestRect; | 476 LayoutRect localHitTestRect = hitTestRect; |
| 477 HitTestLocation localHitTestLocation = hitTestLocation; | 477 HitTestLocation localHitTestLocation = hitTestLocation; |
| 478 | 478 |
| 479 // We need transform state for the first time, or to offset the container st
ate, or to accumulate the new transform. | 479 // We need transform state for the first time, or to offset the container st
ate, or to accumulate the new transform. |
| 480 if (layer()->transform() || transformState || layer()->has3DTransformedDesce
ndant() || layer()->preserves3D()) | 480 if (layer()->transform() || transformState || layer()->has3DTransformedDesce
ndant() || layer()->preserves3D()) |
| 481 localTransformState = createLocalTransformState(rootLayer, containerLaye
r, localHitTestRect, localHitTestLocation, transformState); | 481 localTransformState = createLocalTransformState(rootLayer, containerLaye
r, localHitTestRect, localHitTestLocation, transformState); |
| 482 | 482 |
| 483 // Apply a transform if we have one. | 483 // Apply a transform if we have one. |
| 484 if (layer()->transform()) { | 484 if (layer()->transform()) { |
| 485 // The RenderView cannot have transforms. |
| 486 ASSERT(parent()); |
| 485 // Make sure the parent's clip rects have been calculated. | 487 // Make sure the parent's clip rects have been calculated. |
| 486 if (parent()) { | 488 ClipRect clipRect = layer()->clipper().backgroundClipRect(ClipRectsConte
xt(rootLayer, RootRelativeClipRects)); |
| 487 ClipRect clipRect = layer()->clipper().backgroundClipRect(ClipRectsC
ontext(rootLayer, RootRelativeClipRects)); | 489 // Go ahead and test the enclosing clip now. |
| 488 // Go ahead and test the enclosing clip now. | 490 if (!clipRect.intersects(localHitTestLocation)) |
| 489 if (!clipRect.intersects(localHitTestLocation)) | 491 return 0; |
| 490 return 0; | |
| 491 } | |
| 492 | 492 |
| 493 // If the transform can't be inverted, then don't hit test this layer at
all. | 493 // If the transform can't be inverted, then don't hit test this layer at
all. |
| 494 if (!localTransformState->m_accumulatedTransform.isInvertible()) | 494 if (!localTransformState->m_accumulatedTransform.isInvertible()) |
| 495 return 0; | 495 return 0; |
| 496 | 496 |
| 497 // Compute the point and the hit test rect in the coords of this layer b
y using the values | 497 // Compute the point and the hit test rect in the coords of this layer b
y using the values |
| 498 // from the transformState, which store the point and quad in the coords
of the last flattened | 498 // from the transformState, which store the point and quad in the coords
of the last flattened |
| 499 // layer, and the accumulated transform which lets up map through preser
ve-3d layers. | 499 // layer, and the accumulated transform which lets up map through preser
ve-3d layers. |
| 500 // | 500 // |
| 501 // We can't just map hitTestLocation and hitTestRect because they may ha
ve been flattened (losing z) | 501 // We can't just map hitTestLocation and hitTestRect because they may ha
ve been flattened (losing z) |
| (...skipping 147 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 649 if (!opacity()) | 649 if (!opacity()) |
| 650 return; | 650 return; |
| 651 | 651 |
| 652 LayerPaintingInfo paintingInfo(rootLayer, rect, LayoutSize()); | 652 LayerPaintingInfo paintingInfo(rootLayer, rect, LayoutSize()); |
| 653 | 653 |
| 654 if (!layer()->paintsWithTransform()) { | 654 if (!layer()->paintsWithTransform()) { |
| 655 paintLayerContents(context, paintingInfo, rect); | 655 paintLayerContents(context, paintingInfo, rect); |
| 656 return; | 656 return; |
| 657 } | 657 } |
| 658 | 658 |
| 659 // The RenderView can't be transformed in Sky. |
| 660 ASSERT(layer()->parent()); |
| 661 |
| 659 TransformationMatrix layerTransform = layer()->renderableTransform(); | 662 TransformationMatrix layerTransform = layer()->renderableTransform(); |
| 660 // If the transform can't be inverted, then don't paint anything. | 663 // If the transform can't be inverted, then don't paint anything. |
| 661 if (!layerTransform.isInvertible()) | 664 if (!layerTransform.isInvertible()) |
| 662 return; | 665 return; |
| 663 | 666 |
| 664 // If we have a transparency layer enclosing us and we are the root of a tra
nsform, then we need to establish the transparency | 667 // If we have a transparency layer enclosing us and we are the root of a tra
nsform, then we need to establish the transparency |
| 665 // layer from the parent now, assuming there is a parent | 668 // layer from the parent now, assuming there is a parent |
| 666 if (layer()->isTransparent()) { | 669 if (layer()->isTransparent()) { |
| 667 // TODO(ojan): This should ASSERT(layer()->parent()) instead of branchin
g since the | 670 // TODO(ojan): This should ASSERT(layer()->parent()) instead of branchin
g since the |
| 668 // RenderView can't be transformed in sky. | 671 // RenderView can't be transformed in sky. |
| 669 if (layer()->parent()) | 672 if (layer()->parent()) |
| 670 layer()->parent()->beginTransparencyLayers(context, paintingInfo.roo
tLayer, paintingInfo.paintDirtyRect, paintingInfo.subPixelAccumulation); | 673 layer()->parent()->beginTransparencyLayers(context, paintingInfo.roo
tLayer, paintingInfo.paintDirtyRect, paintingInfo.subPixelAccumulation); |
| 671 else | 674 else |
| 672 layer()->beginTransparencyLayers(context, paintingInfo.rootLayer, pa
intingInfo.paintDirtyRect, paintingInfo.subPixelAccumulation); | 675 layer()->beginTransparencyLayers(context, paintingInfo.rootLayer, pa
intingInfo.paintDirtyRect, paintingInfo.subPixelAccumulation); |
| 673 } | 676 } |
| 674 | 677 |
| 675 // Make sure the parent's clip rects have been calculated. | 678 // Make sure the parent's clip rects have been calculated. |
| 676 ClipRect clipRect; | 679 ClipRectsContext clipRectsContext(paintingInfo.rootLayer, PaintingClipRects)
; |
| 677 // TODO(ojan): This should ASSERT(layer()->parent()) instead of branching si
nce the | 680 ClipRect clipRect = layer()->clipper().backgroundClipRect(clipRectsContext); |
| 678 // RenderView can't be transformed in sky. | 681 clipRect.intersect(paintingInfo.paintDirtyRect); |
| 679 if (layer()->parent()) { | |
| 680 ClipRectsContext clipRectsContext(paintingInfo.rootLayer, PaintingClipRe
cts); | |
| 681 clipRect = layer()->clipper().backgroundClipRect(clipRectsContext); | |
| 682 clipRect.intersect(paintingInfo.paintDirtyRect); | |
| 683 | 682 |
| 684 // Push the parent coordinate space's clip. | 683 // Push the parent coordinate space's clip. |
| 685 layer()->parent()->clipToRect(paintingInfo, context, clipRect); | 684 layer()->parent()->clipToRect(paintingInfo, context, clipRect); |
| 686 } | |
| 687 | 685 |
| 688 // This involves subtracting out the position of the layer in our current co
ordinate space, but preserving | 686 // This involves subtracting out the position of the layer in our current co
ordinate space, but preserving |
| 689 // the accumulated error for sub-pixel layout. | 687 // the accumulated error for sub-pixel layout. |
| 690 LayoutPoint delta; | 688 LayoutPoint delta; |
| 691 layer()->convertToLayerCoords(paintingInfo.rootLayer, delta); | 689 layer()->convertToLayerCoords(paintingInfo.rootLayer, delta); |
| 692 TransformationMatrix transform(layer()->renderableTransform()); | 690 TransformationMatrix transform(layer()->renderableTransform()); |
| 693 IntPoint roundedDelta = roundedIntPoint(delta); | 691 IntPoint roundedDelta = roundedIntPoint(delta); |
| 694 transform.translateRight(roundedDelta.x(), roundedDelta.y()); | 692 transform.translateRight(roundedDelta.x(), roundedDelta.y()); |
| 695 LayoutSize adjustedSubPixelAccumulation = paintingInfo.subPixelAccumulation
+ (delta - roundedDelta); | 693 LayoutSize adjustedSubPixelAccumulation = paintingInfo.subPixelAccumulation
+ (delta - roundedDelta); |
| 696 | 694 |
| 697 // Apply the transform. | 695 // Apply the transform. |
| 698 GraphicsContextStateSaver stateSaver(*context, false); | 696 GraphicsContextStateSaver stateSaver(*context, false); |
| 699 if (!transform.isIdentity()) { | 697 if (!transform.isIdentity()) { |
| 700 stateSaver.save(); | 698 stateSaver.save(); |
| 701 context->concatCTM(transform.toAffineTransform()); | 699 context->concatCTM(transform.toAffineTransform()); |
| 702 } | 700 } |
| 703 | 701 |
| 704 // Now do a paint with the root layer shifted to be us. | 702 // Now do a paint with the root layer shifted to be us. |
| 705 LayerPaintingInfo transformedPaintingInfo(layer(), enclosingIntRect(transfor
m.inverse().mapRect(paintingInfo.paintDirtyRect)), | 703 LayerPaintingInfo transformedPaintingInfo(layer(), enclosingIntRect(transfor
m.inverse().mapRect(paintingInfo.paintDirtyRect)), |
| 706 adjustedSubPixelAccumulation); | 704 adjustedSubPixelAccumulation); |
| 707 paintLayerContents(context, transformedPaintingInfo, rect); | 705 paintLayerContents(context, transformedPaintingInfo, rect); |
| 708 | 706 |
| 709 // Restore the clip. | 707 // Restore the clip. |
| 710 // TODO(ojan): This should ASSERT(layer()->parent()) instead of branching si
nce the | 708 layer()->parent()->restoreClip(context, paintingInfo.paintDirtyRect, clipRec
t); |
| 711 // RenderView can't be transformed in sky. | |
| 712 if (layer()->parent()) | |
| 713 layer()->parent()->restoreClip(context, paintingInfo.paintDirtyRect, cli
pRect); | |
| 714 } | 709 } |
| 715 | 710 |
| 716 void RenderBox::paintLayerContents(GraphicsContext* context, const LayerPainting
Info& paintingInfo, const IntRect& rect) | 711 void RenderBox::paintLayerContents(GraphicsContext* context, const LayerPainting
Info& paintingInfo, const IntRect& rect) |
| 717 { | 712 { |
| 718 float deviceScaleFactor = blink::deviceScaleFactor(frame()); | 713 float deviceScaleFactor = blink::deviceScaleFactor(frame()); |
| 719 context->setDeviceScaleFactor(deviceScaleFactor); | 714 context->setDeviceScaleFactor(deviceScaleFactor); |
| 720 | 715 |
| 721 GraphicsContext* transparencyLayerContext = context; | 716 GraphicsContext* transparencyLayerContext = context; |
| 722 | 717 |
| 723 LayoutPoint offsetFromRoot; | 718 LayoutPoint offsetFromRoot; |
| 724 layer()->convertToLayerCoords(paintingInfo.rootLayer, offsetFromRoot); | 719 layer()->convertToLayerCoords(paintingInfo.rootLayer, offsetFromRoot); |
| 725 | 720 |
| 721 LayerPaintingInfo localPaintingInfo(paintingInfo); |
| 722 |
| 723 LayoutRect layerBounds; |
| 724 // FIXME(sky): Remove foregroundRect. It's unused. |
| 725 ClipRect contentRect, foregroundRect; |
| 726 ClipRectsContext clipRectsContext(localPaintingInfo.rootLayer, PaintingClipR
ects, localPaintingInfo.subPixelAccumulation); |
| 727 layer()->clipper().calculateRects(clipRectsContext, localPaintingInfo.paintD
irtyRect, |
| 728 layerBounds, contentRect, foregroundRect, |
| 729 &offsetFromRoot); |
| 730 |
| 731 if (!layer()->intersectsDamageRect(layerBounds, contentRect.rect(), localPai
ntingInfo.rootLayer, &offsetFromRoot)) |
| 732 return; |
| 733 |
| 726 LayoutRect rootRelativeBounds; | 734 LayoutRect rootRelativeBounds; |
| 727 bool rootRelativeBoundsComputed = false; | 735 bool rootRelativeBoundsComputed = false; |
| 728 | 736 |
| 729 // Apply clip-path to context. | 737 // Apply clip-path to context. |
| 730 GraphicsContextStateSaver clipStateSaver(*context, false); | 738 GraphicsContextStateSaver clipStateSaver(*context, false); |
| 731 | 739 |
| 732 // Clip-path, like border radius, must not be applied to the contents of a c
omposited-scrolling container. | 740 // Clip-path, like border radius, must not be applied to the contents of a c
omposited-scrolling container. |
| 733 // It must, however, still be applied to the mask layer, so that the composi
tor can properly mask the | 741 // It must, however, still be applied to the mask layer, so that the composi
tor can properly mask the |
| 734 // scrolling contents and scrollbars. | 742 // scrolling contents and scrollbars. |
| 735 // TODO(ojan): This style null check doesn't make sense. We should always ha
ve a style. | 743 if (hasClipPath()) { |
| 736 if (hasClipPath() && style()) { | |
| 737 ASSERT(style()->clipPath()); | 744 ASSERT(style()->clipPath()); |
| 738 if (style()->clipPath()->type() == ClipPathOperation::SHAPE) { | 745 if (style()->clipPath()->type() == ClipPathOperation::SHAPE) { |
| 739 ShapeClipPathOperation* clipPath = toShapeClipPathOperation(style()-
>clipPath()); | 746 ShapeClipPathOperation* clipPath = toShapeClipPathOperation(style()-
>clipPath()); |
| 740 if (clipPath->isValid()) { | 747 if (clipPath->isValid()) { |
| 741 clipStateSaver.save(); | 748 clipStateSaver.save(); |
| 742 | 749 |
| 743 if (!rootRelativeBoundsComputed) { | 750 if (!rootRelativeBoundsComputed) { |
| 744 rootRelativeBounds = layer()->physicalBoundingBoxIncludingRe
flectionAndStackingChildren(paintingInfo.rootLayer, offsetFromRoot); | 751 rootRelativeBounds = layer()->physicalBoundingBoxIncludingRe
flectionAndStackingChildren(paintingInfo.rootLayer, offsetFromRoot); |
| 745 rootRelativeBoundsComputed = true; | 752 rootRelativeBoundsComputed = true; |
| 746 } | 753 } |
| 747 | 754 |
| 748 context->clipPath(clipPath->path(rootRelativeBounds), clipPath->
windRule()); | 755 context->clipPath(clipPath->path(rootRelativeBounds), clipPath->
windRule()); |
| 749 } | 756 } |
| 750 } | 757 } |
| 751 } | 758 } |
| 752 | 759 |
| 753 LayerPaintingInfo localPaintingInfo(paintingInfo); | 760 bool haveTransparency = layer()->isTransparent(); |
| 761 |
| 754 FilterEffectRendererHelper filterPainter(layer()->filterRenderer() && layer(
)->paintsWithFilters()); | 762 FilterEffectRendererHelper filterPainter(layer()->filterRenderer() && layer(
)->paintsWithFilters()); |
| 755 | 763 |
| 756 LayoutRect layerBounds; | |
| 757 // FIXME(sky): Remove foregroundRect. It's unused. | |
| 758 ClipRect contentRect, foregroundRect; | |
| 759 ClipRectsContext clipRectsContext(localPaintingInfo.rootLayer, PaintingClipR
ects, localPaintingInfo.subPixelAccumulation); | |
| 760 layer()->clipper().calculateRects(clipRectsContext, localPaintingInfo.paintD
irtyRect, | |
| 761 layerBounds, contentRect, foregroundRect, | |
| 762 &offsetFromRoot); | |
| 763 | |
| 764 bool shouldPaintContent = layer()->intersectsDamageRect(layerBounds, content
Rect.rect(), localPaintingInfo.rootLayer, &offsetFromRoot); | |
| 765 | |
| 766 bool haveTransparency = layer()->isTransparent(); | |
| 767 | |
| 768 if (filterPainter.haveFilterEffect()) { | 764 if (filterPainter.haveFilterEffect()) { |
| 769 ASSERT(layer()->filterInfo()); | 765 ASSERT(layer()->filterInfo()); |
| 770 | 766 |
| 771 if (!rootRelativeBoundsComputed) | 767 if (!rootRelativeBoundsComputed) |
| 772 rootRelativeBounds = layer()->physicalBoundingBoxIncludingReflection
AndStackingChildren(paintingInfo.rootLayer, offsetFromRoot); | 768 rootRelativeBounds = layer()->physicalBoundingBoxIncludingReflection
AndStackingChildren(paintingInfo.rootLayer, offsetFromRoot); |
| 773 | 769 |
| 774 if (filterPainter.prepareFilterEffect(layer(), rootRelativeBounds, paint
ingInfo.paintDirtyRect)) { | 770 if (filterPainter.prepareFilterEffect(layer(), rootRelativeBounds, paint
ingInfo.paintDirtyRect)) { |
| 775 // Rewire the old context to a memory buffer, so that we can capture
the contents of the layer. | 771 // Rewire the old context to a memory buffer, so that we can capture
the contents of the layer. |
| 776 // NOTE: We saved the old context in the "transparencyLayerContext"
local variable, to be able to start a transparency layer | 772 // NOTE: We saved the old context in the "transparencyLayerContext"
local variable, to be able to start a transparency layer |
| 777 // on the original context and avoid duplicating "beginFilterEffect"
after each transparency layer call. Also, note that | 773 // on the original context and avoid duplicating "beginFilterEffect"
after each transparency layer call. Also, note that |
| (...skipping 12 matching lines...) Expand all Loading... |
| 790 // Subsequent code should not clip to the dirty rect, since we've al
ready | 786 // Subsequent code should not clip to the dirty rect, since we've al
ready |
| 791 // done it above, and doing it later will defeat the outsets. | 787 // done it above, and doing it later will defeat the outsets. |
| 792 localPaintingInfo.clipToDirtyRect = false; | 788 localPaintingInfo.clipToDirtyRect = false; |
| 793 | 789 |
| 794 context = filterPainter.beginFilterEffect(context); | 790 context = filterPainter.beginFilterEffect(context); |
| 795 } | 791 } |
| 796 } | 792 } |
| 797 | 793 |
| 798 LayoutPoint layerLocation = toPoint(layerBounds.location() - location() + lo
calPaintingInfo.subPixelAccumulation); | 794 LayoutPoint layerLocation = toPoint(layerBounds.location() - location() + lo
calPaintingInfo.subPixelAccumulation); |
| 799 | 795 |
| 800 if (shouldPaintContent) { | 796 // Begin transparency if we have something to paint. |
| 801 bool contentRectIsEmpty = contentRect.isEmpty(); | 797 if (haveTransparency) |
| 798 layer()->beginTransparencyLayers(transparencyLayerContext, localPainting
Info.rootLayer, paintingInfo.paintDirtyRect, localPaintingInfo.subPixelAccumulat
ion); |
| 802 | 799 |
| 803 // Begin transparency if we have something to paint. | 800 if (localPaintingInfo.clipToDirtyRect) |
| 804 if (haveTransparency && !contentRectIsEmpty) | 801 layer()->clipToRect(localPaintingInfo, context, contentRect); |
| 805 layer()->beginTransparencyLayers(transparencyLayerContext, localPain
tingInfo.rootLayer, paintingInfo.paintDirtyRect, localPaintingInfo.subPixelAccum
ulation); | |
| 806 | 802 |
| 807 // Optimize clipping for the single fragment case. | 803 Vector<RenderBox*> layers; |
| 808 bool shouldClip = localPaintingInfo.clipToDirtyRect && !contentRectIsEmp
ty; | 804 PaintInfo paintInfo(context, pixelSnappedIntRect(contentRect.rect()), localP
aintingInfo.rootLayer->renderer()); |
| 809 if (shouldClip) | 805 paint(paintInfo, layerLocation, layers); |
| 810 layer()->clipToRect(localPaintingInfo, context, contentRect); | |
| 811 | 806 |
| 812 // TODO(ojan): We probably should have already set shouldPaintContent to
false if the rect is empty. | 807 std::stable_sort(layers.begin(), layers.end(), forwardCompareZIndex); |
| 813 if (!contentRectIsEmpty) { | 808 for (auto& box : layers) { |
| 814 Vector<RenderBox*> layers; | 809 box->paintLayer(context, paintingInfo.rootLayer, rect); |
| 810 } |
| 815 | 811 |
| 816 PaintInfo paintInfo(context, pixelSnappedIntRect(contentRect.rect())
, localPaintingInfo.rootLayer->renderer()); | 812 if (localPaintingInfo.clipToDirtyRect) |
| 817 paint(paintInfo, layerLocation, layers); | 813 layer()->restoreClip(context, localPaintingInfo.paintDirtyRect, contentR
ect); |
| 818 | |
| 819 std::stable_sort(layers.begin(), layers.end(), forwardCompareZIndex)
; | |
| 820 for (auto& box : layers) { | |
| 821 box->paintLayer(context, paintingInfo.rootLayer, rect); | |
| 822 } | |
| 823 } | |
| 824 | |
| 825 if (shouldClip) | |
| 826 layer()->restoreClip(context, localPaintingInfo.paintDirtyRect, cont
entRect); | |
| 827 } | |
| 828 | 814 |
| 829 if (filterPainter.hasStartedFilterEffect()) { | 815 if (filterPainter.hasStartedFilterEffect()) { |
| 830 context = filterPainter.applyFilterEffect(); | 816 context = filterPainter.applyFilterEffect(); |
| 831 layer()->restoreClip(transparencyLayerContext, localPaintingInfo.paintDi
rtyRect, contentRect); | 817 layer()->restoreClip(transparencyLayerContext, localPaintingInfo.paintDi
rtyRect, contentRect); |
| 832 } | 818 } |
| 833 | 819 |
| 834 // Make sure that we now use the original transparency context. | 820 // Make sure that we now use the original transparency context. |
| 835 ASSERT(transparencyLayerContext == context); | 821 ASSERT(transparencyLayerContext == context); |
| 836 | 822 |
| 837 // End our transparency layer | 823 // End our transparency layer |
| (...skipping 2197 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 3035 | 3021 |
| 3036 RenderBox::BoxDecorationData::BoxDecorationData(const RenderStyle& style) | 3022 RenderBox::BoxDecorationData::BoxDecorationData(const RenderStyle& style) |
| 3037 { | 3023 { |
| 3038 backgroundColor = style.colorIncludingFallback(CSSPropertyBackgroundColor); | 3024 backgroundColor = style.colorIncludingFallback(CSSPropertyBackgroundColor); |
| 3039 hasBackground = backgroundColor.alpha() || style.hasBackgroundImage(); | 3025 hasBackground = backgroundColor.alpha() || style.hasBackgroundImage(); |
| 3040 ASSERT(hasBackground == style.hasBackground()); | 3026 ASSERT(hasBackground == style.hasBackground()); |
| 3041 hasBorder = style.hasBorder(); | 3027 hasBorder = style.hasBorder(); |
| 3042 } | 3028 } |
| 3043 | 3029 |
| 3044 } // namespace blink | 3030 } // namespace blink |
| OLD | NEW |