mirror of
https://github.com/zoriya/react-native-svg.git
synced 2026-06-01 14:15:03 +00:00
Fix ViewBox, images, transforms, and, gradients; on ios.
Make getContextWidth/Height and setupGlyphContext take clip bounding box and affine transform matrix into consideration.
This commit is contained in:
+29
-28
@@ -15,41 +15,40 @@
|
||||
+ (CGAffineTransform)getTransform:(CGRect)vbRect eRect:(CGRect)eRect align:(NSString *)align meetOrSlice:(RNSVGVBMOS)meetOrSlice fromSymbol:(BOOL)fromSymbol
|
||||
{
|
||||
// based on https://svgwg.org/svg2-draft/coords.html#ComputingAViewportsTransform
|
||||
|
||||
|
||||
// Let vb-x, vb-y, vb-width, vb-height be the min-x, min-y, width and height values of the viewBox attribute respectively.
|
||||
CGFloat vbX = CGRectGetMinX(vbRect);
|
||||
CGFloat vbY = CGRectGetMinY(vbRect);
|
||||
CGFloat vbWidth = CGRectGetWidth(vbRect);
|
||||
CGFloat vbHeight = CGRectGetHeight(vbRect);
|
||||
|
||||
|
||||
// Let e-x, e-y, e-width, e-height be the position and size of the element respectively.
|
||||
CGFloat eX = CGRectGetMinX(eRect);
|
||||
CGFloat eY = CGRectGetMinY(eRect);
|
||||
CGFloat eWidth = CGRectGetWidth(eRect);
|
||||
CGFloat eHeight = CGRectGetHeight(eRect);
|
||||
|
||||
|
||||
// Let align be the align value of preserveAspectRatio, or 'xMidyMid' if preserveAspectRatio is not defined.
|
||||
|
||||
|
||||
// Let meetOrSlice be the meetOrSlice value of preserveAspectRatio, or 'meet' if preserveAspectRatio is not defined or if meetOrSlice is missing from this value.
|
||||
|
||||
|
||||
// Initialize scale-x to e-width/vb-width.
|
||||
CGFloat scaleX = eWidth / vbWidth;
|
||||
|
||||
|
||||
// Initialize scale-y to e-height/vb-height.
|
||||
CGFloat scaleY = eHeight / vbHeight;
|
||||
|
||||
|
||||
// Initialize translate-x to vb-x - e-x.
|
||||
// Initialize translate-y to vb-y - e-y.
|
||||
CGFloat translateX = vbX - eX;
|
||||
CGFloat translateY = vbY - eY;
|
||||
|
||||
|
||||
// Initialize translate-x to e-x - (vb-x * scale-x).
|
||||
// Initialize translate-y to e-y - (vb-y * scale-y).
|
||||
CGFloat translateX = eX - (vbX * scaleX);
|
||||
CGFloat translateY = eY - (vbY * scaleY);
|
||||
|
||||
// If align is 'none'
|
||||
if (meetOrSlice == kRNSVGVBMOSNone) {
|
||||
// Let scale be set the smaller value of scale-x and scale-y.
|
||||
// Assign scale-x and scale-y to scale.
|
||||
CGFloat scale = scaleX = scaleY = fmin(scaleX, scaleY);
|
||||
|
||||
|
||||
// If scale is greater than 1
|
||||
if (scale > 1) {
|
||||
// Minus translateX by (eWidth / scale - vbWidth) / 2
|
||||
@@ -68,30 +67,32 @@
|
||||
} else if (![align isEqualToString: @"none"] && meetOrSlice == kRNSVGVBMOSSlice) {
|
||||
scaleX = scaleY = fmax(scaleX, scaleY);
|
||||
}
|
||||
|
||||
// If align contains 'xMid', minus (e-width / scale-x - vb-width) / 2 from transform-x.
|
||||
|
||||
// If align contains 'xMid', add (e-width - vb-width * scale-x) / 2 to translate-x.
|
||||
if ([align containsString:@"xMid"]) {
|
||||
translateX -= (eWidth / scaleX - vbWidth) / 2;
|
||||
translateX += (eWidth - vbWidth * scaleX) / 2.0;
|
||||
}
|
||||
|
||||
// If align contains 'xMax', minus (e-width / scale-x - vb-width) from transform-x.
|
||||
|
||||
// If align contains 'xMax', add (e-width - vb-width * scale-x) to translate-x.
|
||||
if ([align containsString:@"xMax"]) {
|
||||
translateX -= eWidth / scaleX - vbWidth;
|
||||
translateX += (eWidth - vbWidth * scaleX);
|
||||
}
|
||||
|
||||
// If align contains 'yMid', minus (e-height / scale-y - vb-height) / 2 from transform-y.
|
||||
|
||||
// If align contains 'yMid', add (e-height - vb-height * scale-y) / 2 to translate-y.
|
||||
if ([align containsString:@"YMid"]) {
|
||||
translateY -= (eHeight / scaleY - vbHeight) / 2;
|
||||
translateY += (eHeight - vbHeight * scaleY) / 2.0;
|
||||
}
|
||||
|
||||
// If align contains 'yMax', minus (e-height / scale-y - vb-height) from transform-y.
|
||||
|
||||
// If align contains 'yMax', add (e-height - vb-height * scale-y) to translate-y.
|
||||
if ([align containsString:@"YMax"]) {
|
||||
translateY -= eHeight / scaleY - vbHeight;
|
||||
translateY += (eHeight - vbHeight * scaleY);
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
// The transform applied to content contained by the element is given by
|
||||
// translate(translate-x, translate-y) scale(scale-x, scale-y).
|
||||
CGAffineTransform transform = CGAffineTransformMakeScale(scaleX, scaleY);
|
||||
return CGAffineTransformTranslate(transform, -translateX * (fromSymbol ? scaleX : 1), -translateY * (fromSymbol ? scaleY : 1));
|
||||
return CGAffineTransformTranslate(transform, translateX, translateY);
|
||||
}
|
||||
|
||||
@end
|
||||
|
||||
Reference in New Issue
Block a user