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

Side by Side Diff: Source/core/paint/BoxPainter.cpp

Issue 1164573003: Move NinePieceImage painting to a separate class (Closed) Base URL: https://chromium.googlesource.com/chromium/blink.git@master
Patch Set: Address review comments Created 5 years, 6 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
« no previous file with comments | « Source/core/core.gypi ('k') | Source/core/paint/NinePieceImagePainter.h » ('j') | no next file with comments »
Toggle Intra-line Diffs ('i') | Expand Comments ('e') | Collapse Comments ('c') | Show Comments Hide Comments ('s')
OLDNEW
1 // Copyright 2014 The Chromium Authors. All rights reserved. 1 // Copyright 2014 The Chromium Authors. All rights reserved.
2 // Use of this source code is governed by a BSD-style license that can be 2 // Use of this source code is governed by a BSD-style license that can be
3 // found in the LICENSE file. 3 // found in the LICENSE file.
4 4
5 #include "config.h" 5 #include "config.h"
6 #include "core/paint/BoxPainter.h" 6 #include "core/paint/BoxPainter.h"
7 7
8 #include "core/HTMLNames.h" 8 #include "core/HTMLNames.h"
9 #include "core/frame/Settings.h" 9 #include "core/frame/Settings.h"
10 #include "core/html/HTMLFrameOwnerElement.h" 10 #include "core/html/HTMLFrameOwnerElement.h"
11 #include "core/layout/ImageQualityController.h" 11 #include "core/layout/ImageQualityController.h"
12 #include "core/layout/LayoutBox.h" 12 #include "core/layout/LayoutBox.h"
13 #include "core/layout/LayoutBoxModelObject.h" 13 #include "core/layout/LayoutBoxModelObject.h"
14 #include "core/layout/LayoutObject.h" 14 #include "core/layout/LayoutObject.h"
15 #include "core/layout/LayoutTable.h" 15 #include "core/layout/LayoutTable.h"
16 #include "core/layout/LayoutTheme.h" 16 #include "core/layout/LayoutTheme.h"
17 #include "core/layout/LayoutView.h" 17 #include "core/layout/LayoutView.h"
18 #include "core/layout/compositing/CompositedDeprecatedPaintLayerMapping.h" 18 #include "core/layout/compositing/CompositedDeprecatedPaintLayerMapping.h"
19 #include "core/style/BorderEdge.h" 19 #include "core/style/BorderEdge.h"
20 #include "core/style/ShadowList.h" 20 #include "core/style/ShadowList.h"
21 #include "core/paint/BackgroundImageGeometry.h" 21 #include "core/paint/BackgroundImageGeometry.h"
22 #include "core/paint/BoxBorderPainter.h" 22 #include "core/paint/BoxBorderPainter.h"
23 #include "core/paint/BoxDecorationData.h" 23 #include "core/paint/BoxDecorationData.h"
24 #include "core/paint/DeprecatedPaintLayer.h" 24 #include "core/paint/DeprecatedPaintLayer.h"
25 #include "core/paint/LayoutObjectDrawingRecorder.h" 25 #include "core/paint/LayoutObjectDrawingRecorder.h"
26 #include "core/paint/NinePieceImagePainter.h"
26 #include "core/paint/PaintInfo.h" 27 #include "core/paint/PaintInfo.h"
27 #include "core/paint/RoundedInnerRectClipper.h" 28 #include "core/paint/RoundedInnerRectClipper.h"
28 #include "core/paint/ThemePainter.h" 29 #include "core/paint/ThemePainter.h"
29 #include "platform/LengthFunctions.h" 30 #include "platform/LengthFunctions.h"
30 #include "platform/geometry/LayoutPoint.h" 31 #include "platform/geometry/LayoutPoint.h"
31 #include "platform/geometry/LayoutRectOutsets.h" 32 #include "platform/geometry/LayoutRectOutsets.h"
32 #include "platform/graphics/GraphicsContextStateSaver.h" 33 #include "platform/graphics/GraphicsContextStateSaver.h"
33 #include "platform/graphics/paint/CompositingDisplayItem.h" 34 #include "platform/graphics/paint/CompositingDisplayItem.h"
34 #include "wtf/Optional.h" 35 #include "wtf/Optional.h"
35 36
(...skipping 902 matching lines...) Expand 10 before | Expand all | Expand 10 after
938 ? static_cast<float>(positioningAreaSize.height()) / imageIntrinsicS ize.height() : 1; 939 ? static_cast<float>(positioningAreaSize.height()) / imageIntrinsicS ize.height() : 1;
939 float scaleFactor = type == Contain ? std::min(horizontalScaleFactor, ve rticalScaleFactor) : std::max(horizontalScaleFactor, verticalScaleFactor); 940 float scaleFactor = type == Contain ? std::min(horizontalScaleFactor, ve rticalScaleFactor) : std::max(horizontalScaleFactor, verticalScaleFactor);
940 return IntSize(std::max(1l, lround(imageIntrinsicSize.width() * scaleFac tor)), std::max(1l, lround(imageIntrinsicSize.height() * scaleFactor))); 941 return IntSize(std::max(1l, lround(imageIntrinsicSize.width() * scaleFac tor)), std::max(1l, lround(imageIntrinsicSize.height() * scaleFactor)));
941 } 942 }
942 } 943 }
943 944
944 ASSERT_NOT_REACHED(); 945 ASSERT_NOT_REACHED();
945 return IntSize(); 946 return IntSize();
946 } 947 }
947 948
948 static LayoutUnit computeBorderImageSide(const BorderImageLength& borderSlice, L ayoutUnit borderSide, LayoutUnit imageSide, LayoutUnit boxExtent)
949 {
950 if (borderSlice.isNumber())
951 return borderSlice.number() * borderSide;
952 if (borderSlice.length().isAuto())
953 return imageSide;
954 return valueForLength(borderSlice.length(), boxExtent);
955 }
956
957 bool BoxPainter::paintNinePieceImage(LayoutBoxModelObject& obj, GraphicsContext* graphicsContext, const LayoutRect& rect, const ComputedStyle& style, const Nine PieceImage& ninePieceImage, SkXfermode::Mode op) 949 bool BoxPainter::paintNinePieceImage(LayoutBoxModelObject& obj, GraphicsContext* graphicsContext, const LayoutRect& rect, const ComputedStyle& style, const Nine PieceImage& ninePieceImage, SkXfermode::Mode op)
958 { 950 {
959 StyleImage* styleImage = ninePieceImage.image(); 951 NinePieceImagePainter ninePieceImagePainter(obj);
960 if (!styleImage) 952 return ninePieceImagePainter.paint(graphicsContext, rect, style, ninePieceIm age, op);
961 return false;
962
963 if (!styleImage->isLoaded())
964 return true; // Never paint a nine-piece image incrementally, but don't paint the fallback borders either.
965
966 if (!styleImage->canRender(obj, style.effectiveZoom()))
967 return false;
968
969 // FIXME: border-image is broken with full page zooming when tiling has to h appen, since the tiling function
970 // doesn't have any understanding of the zoom that is in effect on the tile.
971 LayoutRect rectWithOutsets = rect;
972 rectWithOutsets.expand(style.imageOutsets(ninePieceImage));
973 IntRect borderImageRect = pixelSnappedIntRect(rectWithOutsets);
974
975 IntSize imageSize = obj.calculateImageIntrinsicDimensions(styleImage, border ImageRect.size(), LayoutBoxModelObject::DoNotScaleByEffectiveZoom);
976
977 // If both values are 'auto' then the intrinsic width and/or height of the i mage should be used, if any.
978 styleImage->setContainerSizeForLayoutObject(&obj, imageSize, style.effective Zoom());
979
980 int imageWidth = imageSize.width();
981 int imageHeight = imageSize.height();
982
983 float imageScaleFactor = styleImage->imageScaleFactor();
984 int topSlice = std::min<int>(imageHeight, valueForLength(ninePieceImage.imag eSlices().top(), imageHeight)) * imageScaleFactor;
985 int rightSlice = std::min<int>(imageWidth, valueForLength(ninePieceImage.ima geSlices().right(), imageWidth)) * imageScaleFactor;
986 int bottomSlice = std::min<int>(imageHeight, valueForLength(ninePieceImage.i mageSlices().bottom(), imageHeight)) * imageScaleFactor;
987 int leftSlice = std::min<int>(imageWidth, valueForLength(ninePieceImage.imag eSlices().left(), imageWidth)) * imageScaleFactor;
988
989 ENinePieceImageRule hRule = ninePieceImage.horizontalRule();
990 ENinePieceImageRule vRule = ninePieceImage.verticalRule();
991
992 int topWidth = computeBorderImageSide(ninePieceImage.borderSlices().top(), s tyle.borderTopWidth(), topSlice, borderImageRect.height());
993 int rightWidth = computeBorderImageSide(ninePieceImage.borderSlices().right( ), style.borderRightWidth(), rightSlice, borderImageRect.width());
994 int bottomWidth = computeBorderImageSide(ninePieceImage.borderSlices().botto m(), style.borderBottomWidth(), bottomSlice, borderImageRect.height());
995 int leftWidth = computeBorderImageSide(ninePieceImage.borderSlices().left(), style.borderLeftWidth(), leftSlice, borderImageRect.width());
996
997 // Reduce the widths if they're too large.
998 // The spec says: Given Lwidth as the width of the border image area, Lheigh t as its height, and Wside as the border image width
999 // offset for the side, let f = min(Lwidth/(Wleft+Wright), Lheight/(Wtop+Wbo ttom)). If f < 1, then all W are reduced by
1000 // multiplying them by f.
1001 int borderSideWidth = std::max(1, leftWidth + rightWidth);
1002 int borderSideHeight = std::max(1, topWidth + bottomWidth);
1003 float borderSideScaleFactor = std::min((float)borderImageRect.width() / bord erSideWidth, (float)borderImageRect.height() / borderSideHeight);
1004 if (borderSideScaleFactor < 1) {
1005 topWidth *= borderSideScaleFactor;
1006 rightWidth *= borderSideScaleFactor;
1007 bottomWidth *= borderSideScaleFactor;
1008 leftWidth *= borderSideScaleFactor;
1009 }
1010
1011 bool drawLeft = leftSlice > 0 && leftWidth > 0;
1012 bool drawTop = topSlice > 0 && topWidth > 0;
1013 bool drawRight = rightSlice > 0 && rightWidth > 0;
1014 bool drawBottom = bottomSlice > 0 && bottomWidth > 0;
1015 bool drawMiddle = ninePieceImage.fill() && (imageWidth - leftSlice - rightSl ice) > 0 && (borderImageRect.width() - leftWidth - rightWidth) > 0
1016 && (imageHeight - topSlice - bottomSlice) > 0 && (borderImageRect.height () - topWidth - bottomWidth) > 0;
1017
1018 RefPtr<Image> image = styleImage->image(&obj, imageSize);
1019
1020 float destinationWidth = borderImageRect.width() - leftWidth - rightWidth;
1021 float destinationHeight = borderImageRect.height() - topWidth - bottomWidth;
1022
1023 float sourceWidth = imageWidth - leftSlice - rightSlice;
1024 float sourceHeight = imageHeight - topSlice - bottomSlice;
1025
1026 float leftSideScale = drawLeft ? (float)leftWidth / leftSlice : 1;
1027 float rightSideScale = drawRight ? (float)rightWidth / rightSlice : 1;
1028 float topSideScale = drawTop ? (float)topWidth / topSlice : 1;
1029 float bottomSideScale = drawBottom ? (float)bottomWidth / bottomSlice : 1;
1030
1031 InterpolationQuality interpolationQuality = chooseInterpolationQuality(obj, graphicsContext, image.get(), 0, rectWithOutsets.size());
1032 InterpolationQuality previousInterpolationQuality = graphicsContext->imageIn terpolationQuality();
1033 graphicsContext->setImageInterpolationQuality(interpolationQuality);
1034
1035 TRACE_EVENT1(TRACE_DISABLED_BY_DEFAULT("devtools.timeline"), "PaintImage", " data", InspectorPaintImageEvent::data(obj, *styleImage));
1036 if (drawLeft) {
1037 // Paint the top and bottom left corners.
1038
1039 // The top left corner rect is (tx, ty, leftWidth, topWidth)
1040 // The rect to use from within the image is obtained from our slice, and is (0, 0, leftSlice, topSlice)
1041 if (drawTop) {
1042 graphicsContext->drawImage(image.get(), IntRect(borderImageRect.loca tion(), IntSize(leftWidth, topWidth)),
1043 LayoutRect(0, 0, leftSlice, topSlice), op);
1044 }
1045
1046 // The bottom left corner rect is (tx, ty + h - bottomWidth, leftWidth, bottomWidth)
1047 // The rect to use from within the image is (0, imageHeight - bottomSlic e, leftSlice, botomSlice)
1048 if (drawBottom) {
1049 graphicsContext->drawImage(image.get(), IntRect(borderImageRect.x(), borderImageRect.maxY() - bottomWidth, leftWidth, bottomWidth),
1050 LayoutRect(0, imageHeight - bottomSlice, leftSlice, bottomSlice) , op);
1051 }
1052
1053 // Paint the left edge.
1054 // Have to scale and tile into the border rect.
1055 if (sourceHeight > 0) {
1056 graphicsContext->drawTiledImage(image.get(), IntRect(borderImageRect .x(), borderImageRect.y() + topWidth, leftWidth, destinationHeight),
1057 IntRect(0, topSlice, leftSlice, sourceHeight), FloatSize(leftSid eScale, leftSideScale), Image::StretchTile, (Image::TileRule)vRule, op);
1058 }
1059 }
1060
1061 if (drawRight) {
1062 // Paint the top and bottom right corners
1063 // The top right corner rect is (tx + w - rightWidth, ty, rightWidth, to pWidth)
1064 // The rect to use from within the image is obtained from our slice, and is (imageWidth - rightSlice, 0, rightSlice, topSlice)
1065 if (drawTop) {
1066 graphicsContext->drawImage(image.get(), IntRect(borderImageRect.maxX () - rightWidth, borderImageRect.y(), rightWidth, topWidth),
1067 LayoutRect(imageWidth - rightSlice, 0, rightSlice, topSlice), op );
1068 }
1069
1070 // The bottom right corner rect is (tx + w - rightWidth, ty + h - bottom Width, rightWidth, bottomWidth)
1071 // The rect to use from within the image is (imageWidth - rightSlice, im ageHeight - bottomSlice, rightSlice, bottomSlice)
1072 if (drawBottom) {
1073 graphicsContext->drawImage(image.get(), IntRect(borderImageRect.maxX () - rightWidth, borderImageRect.maxY() - bottomWidth, rightWidth, bottomWidth),
1074 LayoutRect(imageWidth - rightSlice, imageHeight - bottomSlice, r ightSlice, bottomSlice), op);
1075 }
1076
1077 // Paint the right edge.
1078 if (sourceHeight > 0) {
1079 graphicsContext->drawTiledImage(image.get(), IntRect(borderImageRect .maxX() - rightWidth, borderImageRect.y() + topWidth, rightWidth,
1080 destinationHeight),
1081 IntRect(imageWidth - rightSlice, topSlice, rightSlice, sourceHei ght),
1082 FloatSize(rightSideScale, rightSideScale),
1083 Image::StretchTile, (Image::TileRule)vRule, op);
1084 }
1085 }
1086
1087 // Paint the top edge.
1088 if (drawTop && sourceWidth > 0) {
1089 graphicsContext->drawTiledImage(image.get(), IntRect(borderImageRect.x() + leftWidth, borderImageRect.y(), destinationWidth, topWidth),
1090 IntRect(leftSlice, 0, sourceWidth, topSlice),
1091 FloatSize(topSideScale, topSideScale), (Image::TileRule)hRule, Image ::StretchTile, op);
1092 }
1093
1094 // Paint the bottom edge.
1095 if (drawBottom && sourceWidth > 0) {
1096 graphicsContext->drawTiledImage(image.get(), IntRect(borderImageRect.x() + leftWidth, borderImageRect.maxY() - bottomWidth,
1097 destinationWidth, bottomWidth),
1098 IntRect(leftSlice, imageHeight - bottomSlice, sourceWidth, bottomSli ce),
1099 FloatSize(bottomSideScale, bottomSideScale),
1100 (Image::TileRule)hRule, Image::StretchTile, op);
1101 }
1102
1103 // Paint the middle.
1104 if (drawMiddle) {
1105 FloatSize middleScaleFactor(1, 1);
1106 if (drawTop)
1107 middleScaleFactor.setWidth(topSideScale);
1108 else if (drawBottom)
1109 middleScaleFactor.setWidth(bottomSideScale);
1110 if (drawLeft)
1111 middleScaleFactor.setHeight(leftSideScale);
1112 else if (drawRight)
1113 middleScaleFactor.setHeight(rightSideScale);
1114
1115 // For "stretch" rules, just override the scale factor and replace. We o nly had to do this for the
1116 // center tile, since sides don't even use the scale factor unless they have a rule other than "stretch".
1117 // The middle however can have "stretch" specified in one axis but not t he other, so we have to
1118 // correct the scale here.
1119 if (hRule == StretchImageRule)
1120 middleScaleFactor.setWidth(destinationWidth / sourceWidth);
1121
1122 if (vRule == StretchImageRule)
1123 middleScaleFactor.setHeight(destinationHeight / sourceHeight);
1124
1125 graphicsContext->drawTiledImage(image.get(),
1126 IntRect(borderImageRect.x() + leftWidth, borderImageRect.y() + topWi dth, destinationWidth, destinationHeight),
1127 IntRect(leftSlice, topSlice, sourceWidth, sourceHeight),
1128 middleScaleFactor, (Image::TileRule)hRule, (Image::TileRule)vRule, o p);
1129 }
1130 graphicsContext->setImageInterpolationQuality(previousInterpolationQuality);
1131 return true;
1132 } 953 }
1133 954
1134 bool BoxPainter::shouldAntialiasLines(GraphicsContext* context) 955 bool BoxPainter::shouldAntialiasLines(GraphicsContext* context)
1135 { 956 {
1136 // FIXME: We may want to not antialias when scaled by an integral value, 957 // FIXME: We may want to not antialias when scaled by an integral value,
1137 // and we may want to antialias when translated by a non-integral value. 958 // and we may want to antialias when translated by a non-integral value.
1138 // FIXME: See crbug.com/382491. getCTM does not include scale factors applie d at raster time, such 959 // FIXME: See crbug.com/382491. getCTM does not include scale factors applie d at raster time, such
1139 // as device zoom. 960 // as device zoom.
1140 return !context->getCTM().isIdentityOrTranslationOrFlipped(); 961 return !context->getCTM().isIdentityOrTranslationOrFlipped();
1141 } 962 }
(...skipping 152 matching lines...) Expand 10 before | Expand all | Expand 10 after
1294 else 1115 else
1295 clippedEdges |= GraphicsContext::BottomEdge; 1116 clippedEdges |= GraphicsContext::BottomEdge;
1296 } 1117 }
1297 // TODO: support non-integer shadows - crbug.com/334828 1118 // TODO: support non-integer shadows - crbug.com/334828
1298 context->drawInnerShadow(border, shadowColor, flooredIntSize(shadowO ffset), shadowBlur, shadowSpread, clippedEdges); 1119 context->drawInnerShadow(border, shadowColor, flooredIntSize(shadowO ffset), shadowBlur, shadowSpread, clippedEdges);
1299 } 1120 }
1300 } 1121 }
1301 } 1122 }
1302 1123
1303 } // namespace blink 1124 } // namespace blink
OLDNEW
« no previous file with comments | « Source/core/core.gypi ('k') | Source/core/paint/NinePieceImagePainter.h » ('j') | no next file with comments »

Powered by Google App Engine
This is Rietveld 408576698