Skip to content

Commit

Permalink
[Shapes] Use the path's boundingBox to determine the scale used when …
Browse files Browse the repository at this point in the history
…borderWidth is deducted from the path.

PiperOrigin-RevId: 324334338
  • Loading branch information
attributeshift authored and material-automation committed Aug 1, 2020
1 parent d8463cb commit bb04d0a
Show file tree
Hide file tree
Showing 2 changed files with 31 additions and 9 deletions.
38 changes: 30 additions & 8 deletions components/Shapes/src/MDCShapedShadowLayer.m
Original file line number Diff line number Diff line change
Expand Up @@ -129,15 +129,37 @@ - (void)generateColorPathGivenLineWidth {
}

- (CGAffineTransform)generateTransformInsetByValue:(CGFloat)value {
CGRect standardizedBounds = CGRectStandardize(self.bounds);
CGRect insetBounds = CGRectInset(standardizedBounds, value, value);
CGAffineTransform transform = CGAffineTransformMakeTranslation(value, value);
CGFloat width = CGRectGetWidth(standardizedBounds);
CGFloat height = CGRectGetHeight(standardizedBounds);
if (width > kDimensionalEpsilon && height > kDimensionalEpsilon) {
transform = CGAffineTransformScale(transform, CGRectGetWidth(insetBounds) / width,
CGRectGetHeight(insetBounds) / height);
// Use the identitfy transfrom when inset is less than Epsilon.
if (value < kDimensionalEpsilon) {
return CGAffineTransformIdentity;
}

// Use the path's boundingBox to get the proportion of inset value,
// because this tranform is expected to be applied on a CGPath.
CGRect pathBoundingBox = CGPathGetPathBoundingBox(self.shadowPath);
CGRect pathStandardizedBounds = CGRectStandardize(pathBoundingBox);

if (CGRectGetWidth(pathStandardizedBounds) < kDimensionalEpsilon ||
CGRectGetHeight(pathStandardizedBounds) < kDimensionalEpsilon) {
return CGAffineTransformIdentity;
}

CGRect insetBounds = CGRectInset(pathStandardizedBounds, value, value);
CGFloat width = CGRectGetWidth(pathStandardizedBounds);
CGFloat height = CGRectGetHeight(pathStandardizedBounds);
CGFloat pathCenterX = CGRectGetMidX(pathStandardizedBounds);
CGFloat pathCenterY = CGRectGetMidY(pathStandardizedBounds);
// Calculate the shifted center and re-center it by applying a translation transform.
// value * 2 represents the accumulated borderWidth on each side, value * 2 / width
// represents the proportion of accumulated borderWidth in path bounds, which is also
// the value used for scale transform.
// The shiftWidth represents the shifted length horizontally on the center.
CGFloat shiftWidth = value * 2 / width * pathCenterX;
// Same calculation for height.
CGFloat shiftHeight = value * 2 / height * pathCenterY;
CGAffineTransform transform = CGAffineTransformMakeTranslation(shiftWidth, shiftHeight);
transform = CGAffineTransformScale(transform, CGRectGetWidth(insetBounds) / width,
CGRectGetHeight(insetBounds) / height);
return transform;
}

Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -39,7 +39,7 @@ - (void)testEmptyFrameWithNonEmptyPathGeneratesColorLayerPathMatchingPath {

// Then
// Note that the X and Y values here are shifted by half of the shaped border width.
UIBezierPath *insetPath = [UIBezierPath bezierPathWithRect:CGRectMake(1, 1, 100, 100)];
UIBezierPath *insetPath = [UIBezierPath bezierPathWithRect:CGRectMake(1, 1, 98, 98)];
XCTAssertTrue(CGPathEqualToPath(shadowLayer.colorLayer.path, insetPath.CGPath));
}

Expand Down

0 comments on commit bb04d0a

Please sign in to comment.