1092 {
1093 static const Clip kClippedOut = {
1095
1096 const SaveRecord& cs = this->currentSaveRecord();
1098
1099 return kClippedOut;
1100 }
1101
1102
1103 const Rect deviceBounds = this->deviceBounds();
1104
1105
1106
1108 if (geometry.isShape()) {
1109 styledShape.
init(geometry.shape());
1110 } else {
1111
1112
1114 }
1115
1116 auto origSize = geometry.bounds().size();
1117 if (!
SkIsFinite(origSize.x(), origSize.y())) {
1118
1119 return kClippedOut;
1120 }
1121
1122
1123
1124
1125 bool infiniteBounds = styledShape->inverted();
1126
1127
1128
1129
1130
1131
1132 if (!infiniteBounds && (styledShape->isLine() ||
any(origSize == 0.f))) {
1134 return kClippedOut;
1135 }
1136 }
1137
1138 Rect transformedShapeBounds;
1139 bool shapeInDeviceSpace = false;
1140
1141
1142 float rendererOutset = outsetBoundsForAA ? localToDevice.localAARadius(styledShape->bounds())
1143 : 0.f;
1145 transformedShapeBounds = deviceBounds;
1146 infiniteBounds = true;
1147 } else {
1148
1149
1150 transformedShapeBounds = styledShape->bounds();
1151
1152
1155 transformedShapeBounds.outset(localStyleOutset);
1156
1157 if (!style.
isFillStyle() || rendererOutset != 0.0f) {
1158
1159
1160 styledShape.
writable()->setRect(transformedShapeBounds);
1161 }
1162 }
1163
1164 transformedShapeBounds = localToDevice.mapRect(transformedShapeBounds);
1165
1166
1167
1169 transformedShapeBounds.outset(0.5f);
1170
1171
1172 styledShape.
writable()->setRect(transformedShapeBounds);
1173 shapeInDeviceSpace = true;
1174 }
1175
1176
1177 transformedShapeBounds.intersect(deviceBounds);
1178 }
1179
1181 if (infiniteBounds) {
1182 drawBounds = deviceBounds;
1183 styledShape.
writable()->setRect(drawBounds);
1184 shapeInDeviceSpace = true;
1185 } else {
1186 drawBounds = transformedShapeBounds;
1187 }
1188
1190
1191
1192
1193 return Clip(drawBounds, transformedShapeBounds, deviceBounds.asSkIRect(), cs.shader());
1194 }
1195
1196
1197
1198
1199
1200
1201
1202
1203
1204
1205 Rect scissor = cs.scissor(deviceBounds, drawBounds).makeRoundOut();
1206 drawBounds.intersect(scissor);
1207 transformedShapeBounds.intersect(scissor);
1208 if (drawBounds.isEmptyNegativeOrNaN() || cs.innerBounds().contains(drawBounds)) {
1209
1210 return Clip(drawBounds, transformedShapeBounds, scissor.asSkIRect(), cs.shader());
1211 }
1212
1213
1214
1215
1216
1217
1218 TransformedShape
draw{shapeInDeviceSpace ?
kIdentity : localToDevice,
1219 *styledShape,
1220 drawBounds,
1223 true};
1224
1226 SkASSERT(outEffectiveElements->empty());
1227 int i = fElements.
count();
1228 for (
const RawElement&
e : fElements.
ritems()) {
1230 if (
i < cs.oldestElementIndex()) {
1231
1232
1233 break;
1234 }
1235
1236 auto influence =
e.testForDraw(
draw);
1237 if (influence == RawElement::DrawInfluence::kClipOut) {
1238 outEffectiveElements->clear();
1239 return kClippedOut;
1240 }
1241 if (influence == RawElement::DrawInfluence::kIntersect) {
1242 outEffectiveElements->push_back(&
e);
1243 }
1244 }
1245
1246 return Clip(drawBounds, transformedShapeBounds, scissor.asSkIRect(), cs.shader());
1247}
static bool SkIsFinite(T x, Pack... values)
static void draw(SkCanvas *canvas, SkRect &target, int x, int y)
@ kButt_Cap
no stroke extension
SkScalar getInflationRadius() const
bool isHairlineStyle() const
SkPaint::Cap getCap() const
void initIfNeeded(Args &&... args)
void init(const T &initial)
constexpr std::array< float, 9 > kIdentity
SIT bool all(const Vec< 1, T > &x)
SIT bool any(const Vec< 1, T > &x)
static constexpr SkIRect MakeEmpty()