From 4d00aab469f572ea8e74d9717d6c0aea162c8a4c Mon Sep 17 00:00:00 2001 From: Curtis Hard Date: Tue, 7 Jun 2022 19:46:31 +0100 Subject: [PATCH] =?UTF-8?q?Nice=20refactor=20of=20viewBox=E2=80=99s?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- .../IJSVG/Source/Layers/IJSVGImageLayer.h | 3 - .../IJSVG/Source/Layers/IJSVGImageLayer.m | 2 +- .../IJSVG/Source/Layers/IJSVGPatternLayer.m | 2 +- .../IJSVG/Source/Layers/IJSVGRootLayer.m | 5 +- .../IJSVG/Source/Rendering/IJSVGLayerTree.m | 3 - .../IJSVG/IJSVG/Source/Utils/IJSVGViewBox.h | 9 +- .../IJSVG/IJSVG/Source/Utils/IJSVGViewBox.m | 265 +++++++++++++----- IJSVGExample/IJSVGExample/gump-bench.svg | 71 +++++ .../IJSVGExample/pattern-alignment.svg | 18 ++ IJSVGExample/IJSVGExample/sh.svg | 10 + 10 files changed, 313 insertions(+), 75 deletions(-) create mode 100644 IJSVGExample/IJSVGExample/gump-bench.svg create mode 100644 IJSVGExample/IJSVGExample/pattern-alignment.svg create mode 100644 IJSVGExample/IJSVGExample/sh.svg diff --git a/Framework/IJSVG/IJSVG/Source/Layers/IJSVGImageLayer.h b/Framework/IJSVG/IJSVG/Source/Layers/IJSVGImageLayer.h index b311d69..12b9f70 100644 --- a/Framework/IJSVG/IJSVG/Source/Layers/IJSVGImageLayer.h +++ b/Framework/IJSVG/IJSVG/Source/Layers/IJSVGImageLayer.h @@ -14,9 +14,6 @@ #import @interface IJSVGImageLayer : IJSVGLayer { - -@private - CALayer* _imageLayer; } @property (nonatomic, strong) IJSVGImage* image; diff --git a/Framework/IJSVG/IJSVG/Source/Layers/IJSVGImageLayer.m b/Framework/IJSVG/IJSVG/Source/Layers/IJSVGImageLayer.m index 46c1773..d479fc1 100644 --- a/Framework/IJSVG/IJSVG/Source/Layers/IJSVGImageLayer.m +++ b/Framework/IJSVG/IJSVG/Source/Layers/IJSVGImageLayer.m @@ -29,7 +29,7 @@ CGImageRef image = _image.CGImage; CGRect imageDrawRect = _image.intrinsicBounds; CGRect currentBounds = self.bounds; - IJSVGViewBoxDrawingBlock drawBlock = ^(CGSize scale) { + IJSVGViewBoxDrawingBlock drawBlock = ^(CGRect computedRect, CGFloat scale[]) { // image will be upside down, so just translate it back on itself CGContextConcatCTM(ctx, CGAffineTransformMakeScale(1.f, -1.f)); CGContextTranslateCTM(ctx, 0.f, -CGRectGetHeight(imageDrawRect)); diff --git a/Framework/IJSVG/IJSVG/Source/Layers/IJSVGPatternLayer.m b/Framework/IJSVG/IJSVG/Source/Layers/IJSVGPatternLayer.m index 593445c..5893938 100644 --- a/Framework/IJSVG/IJSVG/Source/Layers/IJSVGPatternLayer.m +++ b/Framework/IJSVG/IJSVG/Source/Layers/IJSVGPatternLayer.m @@ -37,7 +37,7 @@ void IJSVGPatternDrawingCallBack(void* info, CGContextRef ctx) IJSVGViewBoxAlignment alignment = layer.patternNode.viewBoxAlignment; IJSVGViewBoxMeetOrSlice meetOrSlice = layer.patternNode.viewBoxMeetOrSlice; CGRect viewBox = layer.viewBox; - IJSVGViewBoxDrawingBlock drawBlock = ^(CGSize scale) { + IJSVGViewBoxDrawingBlock drawBlock = ^(CGRect computedRect, CGFloat scale[]) { [layer.pattern renderInContext:ctx]; }; IJSVGContextDrawViewBox(ctx, viewBox, rect, alignment, meetOrSlice, drawBlock); diff --git a/Framework/IJSVG/IJSVG/Source/Layers/IJSVGRootLayer.m b/Framework/IJSVG/IJSVG/Source/Layers/IJSVGRootLayer.m index 072cdc3..4ba1a2c 100644 --- a/Framework/IJSVG/IJSVG/Source/Layers/IJSVGRootLayer.m +++ b/Framework/IJSVG/IJSVG/Source/Layers/IJSVGRootLayer.m @@ -15,12 +15,11 @@ if(self.viewBox != nil) { CGRect viewBox = [self.viewBox computeValue:CGSizeZero]; __weak IJSVGRootLayer* weakSelf = self; - IJSVGViewBoxDrawingBlock drawingBlock = ^(CGSize size) { + IJSVGViewBoxDrawingBlock drawingBlock = ^(CGRect computedRect, CGFloat scale[]) { CGContextSaveGState(ctx); - CGContextClipToRect(ctx,viewBox); // we have to make sure we set the backing scale factor once // we know how scale this will be drawn at - CGFloat nScale = MIN(size.width, size.height); + CGFloat nScale = MIN(scale[0], scale[1]); nScale += weakSelf.backingScaleFactor; weakSelf.backingScaleFactor = nScale; diff --git a/Framework/IJSVG/IJSVG/Source/Rendering/IJSVGLayerTree.m b/Framework/IJSVG/IJSVG/Source/Rendering/IJSVGLayerTree.m index 86b2d2c..6b43bee 100644 --- a/Framework/IJSVG/IJSVG/Source/Rendering/IJSVGLayerTree.m +++ b/Framework/IJSVG/IJSVG/Source/Rendering/IJSVGLayerTree.m @@ -364,9 +364,6 @@ frame = CGRectMake(0.f, 0.f, node.intrinsicSize.width.value, node.intrinsicSize.height.value); - - - layer.frame = frame; [self pushViewPort:layer.frame]; layer.sublayers = [self drawableLayersForNodes:node.children]; diff --git a/Framework/IJSVG/IJSVG/Source/Utils/IJSVGViewBox.h b/Framework/IJSVG/IJSVG/Source/Utils/IJSVGViewBox.h index 92e0720..8901a4c 100644 --- a/Framework/IJSVG/IJSVG/Source/Utils/IJSVGViewBox.h +++ b/Framework/IJSVG/IJSVG/Source/Utils/IJSVGViewBox.h @@ -29,15 +29,22 @@ typedef NS_ENUM(NSInteger, IJSVGViewBoxMeetOrSlice) { IJSVGViewBoxMeetOrSliceSlice, }; +typedef CGRect (*IJSVGViewBoxComputeRectFunction)(CGRect viewBox, CGRect drawingRect, + IJSVGViewBoxMeetOrSlice meetOrSlice, + CGFloat* scale); + @interface IJSVGViewBox : NSObject -typedef void (^IJSVGViewBoxDrawingBlock)(CGSize scale); +typedef void (^IJSVGViewBoxDrawingBlock)(CGRect computedRect, CGFloat scale[]); + (IJSVGViewBoxAlignment)alignmentForString:(NSString*)string meetOrSlice:(IJSVGViewBoxMeetOrSlice*)meetOrSlice; + (IJSVGViewBoxAlignment)alignmentForString:(NSString*)string; + (IJSVGViewBoxMeetOrSlice)meetOrSliceForString:(NSString*)string; +CGRect IJSVGViewBoxComputeRect(CGRect viewBox, CGRect drawingRect, IJSVGViewBoxAlignment alignment, + IJSVGViewBoxMeetOrSlice meetOrSlice, CGFloat* scale); + void IJSVGContextDrawViewBox(CGContextRef ctx, CGRect viewBox, CGRect boundingBox, IJSVGViewBoxAlignment alignment, IJSVGViewBoxMeetOrSlice meetOrSlice, IJSVGViewBoxDrawingBlock block); diff --git a/Framework/IJSVG/IJSVG/Source/Utils/IJSVGViewBox.m b/Framework/IJSVG/IJSVG/Source/Utils/IJSVGViewBox.m index 839e04b..e574b12 100644 --- a/Framework/IJSVG/IJSVG/Source/Utils/IJSVGViewBox.m +++ b/Framework/IJSVG/IJSVG/Source/Utils/IJSVGViewBox.m @@ -85,13 +85,19 @@ return IJSVGViewBoxAlignmentUnknown; } -CGSize IJSVGViewBoxComputeXMidYMid(CGContextRef ctx, CGRect viewBox, - CGRect drawingRect, IJSVGViewBoxMeetOrSlice meetOrSlice) +CGRect IJSVGViewBoxComputeRectXMidYMid(CGRect viewBox, CGRect drawingRect, + IJSVGViewBoxMeetOrSlice meetOrSlice, + CGFloat* scale) { CGFloat width = drawingRect.size.width / viewBox.size.width; CGFloat height = drawingRect.size.height / viewBox.size.height; CGFloat ratio = meetOrSlice == IJSVGViewBoxMeetOrSliceMeet ? MIN(width, height) : MAX(width, height); + if(scale != NULL) { + scale[0] = ratio; + scale[1] = ratio; + } + // scale the viewBox into the drawingRect CGAffineTransform transform = CGAffineTransformIdentity; transform = CGAffineTransformConcat(transform, CGAffineTransformMakeScale(ratio, ratio)); @@ -103,18 +109,22 @@ CGSize IJSVGViewBoxComputeXMidYMid(CGContextRef ctx, CGRect viewBox, translate = CGAffineTransformMakeTranslation(-(viewBox.origin.x * ratio), -(viewBox.origin.y * ratio)); transform = CGAffineTransformConcat(transform, translate); - CGContextConcatCTM(ctx, transform); - - return CGSizeMake(ratio, ratio); + return CGRectApplyAffineTransform(drawingRect, transform); } -CGSize IJSVGViewBoxComputeXMinYMid(CGContextRef ctx, CGRect viewBox, - CGRect drawingRect, IJSVGViewBoxMeetOrSlice meetOrSlice) +CGRect IJSVGViewBoxComputeRectXMinYMid(CGRect viewBox, CGRect drawingRect, + IJSVGViewBoxMeetOrSlice meetOrSlice, + CGFloat* scale) { CGFloat width = drawingRect.size.width / viewBox.size.width; CGFloat height = drawingRect.size.height / viewBox.size.height; CGFloat ratio = meetOrSlice == IJSVGViewBoxMeetOrSliceMeet ? MIN(width, height) : MAX(width, height); + if(scale != NULL) { + scale[0] = ratio; + scale[1] = ratio; + } + // scale the viewBox into the drawingRect CGAffineTransform transform = CGAffineTransformIdentity; transform = CGAffineTransformConcat(transform, CGAffineTransformMakeScale(ratio, ratio)); @@ -126,18 +136,22 @@ CGSize IJSVGViewBoxComputeXMinYMid(CGContextRef ctx, CGRect viewBox, translate = CGAffineTransformMakeTranslation(-(viewBox.origin.x * ratio), -(viewBox.origin.y * ratio)); transform = CGAffineTransformConcat(transform, translate); - CGContextConcatCTM(ctx, transform); - - return CGSizeMake(ratio, ratio); + return CGRectApplyAffineTransform(drawingRect, transform); } -CGSize IJSVGViewBoxComputeXMaxYMid(CGContextRef ctx, CGRect viewBox, - CGRect drawingRect, IJSVGViewBoxMeetOrSlice meetOrSlice) +CGRect IJSVGViewBoxComputeRectXMaxYMid(CGRect viewBox, CGRect drawingRect, + IJSVGViewBoxMeetOrSlice meetOrSlice, + CGFloat* scale) { CGFloat width = drawingRect.size.width / viewBox.size.width; CGFloat height = drawingRect.size.height / viewBox.size.height; CGFloat ratio = meetOrSlice == IJSVGViewBoxMeetOrSliceMeet ? MIN(width, height) : MAX(width, height); + if(scale != NULL) { + scale[0] = ratio; + scale[1] = ratio; + } + // scale the viewBox into the drawingRect CGAffineTransform transform = CGAffineTransformIdentity; transform = CGAffineTransformConcat(transform, CGAffineTransformMakeScale(ratio, ratio)); @@ -149,18 +163,22 @@ CGSize IJSVGViewBoxComputeXMaxYMid(CGContextRef ctx, CGRect viewBox, translate = CGAffineTransformMakeTranslation(-(viewBox.origin.x * ratio), -(viewBox.origin.y * ratio)); transform = CGAffineTransformConcat(transform, translate); - CGContextConcatCTM(ctx, transform); - - return CGSizeMake(ratio, ratio); + return CGRectApplyAffineTransform(drawingRect, transform); } -CGSize IJSVGViewBoxComputeXMidYMin(CGContextRef ctx, CGRect viewBox, - CGRect drawingRect, IJSVGViewBoxMeetOrSlice meetOrSlice) +CGRect IJSVGViewBoxComputeRectXMidYMin(CGRect viewBox, CGRect drawingRect, + IJSVGViewBoxMeetOrSlice meetOrSlice, + CGFloat* scale) { CGFloat width = drawingRect.size.width / viewBox.size.width; CGFloat height = drawingRect.size.height / viewBox.size.height; CGFloat ratio = meetOrSlice == IJSVGViewBoxMeetOrSliceMeet ? MIN(width, height) : MAX(width, height); + if(scale != NULL) { + scale[0] = ratio; + scale[1] = ratio; + } + // scale the viewBox into the drawingRect CGAffineTransform transform = CGAffineTransformIdentity; transform = CGAffineTransformConcat(transform, CGAffineTransformMakeScale(ratio, ratio)); @@ -172,18 +190,22 @@ CGSize IJSVGViewBoxComputeXMidYMin(CGContextRef ctx, CGRect viewBox, translate = CGAffineTransformMakeTranslation(-(viewBox.origin.x * ratio), -(viewBox.origin.y * ratio)); transform = CGAffineTransformConcat(transform, translate); - CGContextConcatCTM(ctx, transform); - - return CGSizeMake(ratio, ratio); + return CGRectApplyAffineTransform(drawingRect, transform); } -CGSize IJSVGViewBoxComputeXMinYMin(CGContextRef ctx, CGRect viewBox, - CGRect drawingRect, IJSVGViewBoxMeetOrSlice meetOrSlice) +CGRect IJSVGViewBoxComputeRectXMinYMin(CGRect viewBox, CGRect drawingRect, + IJSVGViewBoxMeetOrSlice meetOrSlice, + CGFloat* scale) { CGFloat width = drawingRect.size.width / viewBox.size.width; CGFloat height = drawingRect.size.height / viewBox.size.height; CGFloat ratio = meetOrSlice == IJSVGViewBoxMeetOrSliceMeet ? MIN(width, height) : MAX(width, height); + if(scale != NULL) { + scale[0] = ratio; + scale[1] = ratio; + } + // scale the viewBox into the drawingRect CGAffineTransform transform = CGAffineTransformIdentity; transform = CGAffineTransformConcat(transform, CGAffineTransformMakeScale(ratio, ratio)); @@ -194,18 +216,22 @@ CGSize IJSVGViewBoxComputeXMinYMin(CGContextRef ctx, CGRect viewBox, translate = CGAffineTransformMakeTranslation(-(viewBox.origin.x * ratio), -(viewBox.origin.y * ratio)); transform = CGAffineTransformConcat(transform, translate); - CGContextConcatCTM(ctx, transform); - - return CGSizeMake(ratio, ratio); + return CGRectApplyAffineTransform(drawingRect, transform); } -CGSize IJSVGViewBoxComputeXMidYMax(CGContextRef ctx, CGRect viewBox, - CGRect drawingRect, IJSVGViewBoxMeetOrSlice meetOrSlice) +CGRect IJSVGViewBoxComputeRectXMidYMax(CGRect viewBox, CGRect drawingRect, + IJSVGViewBoxMeetOrSlice meetOrSlice, + CGFloat* scale) { CGFloat width = drawingRect.size.width / viewBox.size.width; CGFloat height = drawingRect.size.height / viewBox.size.height; CGFloat ratio = meetOrSlice == IJSVGViewBoxMeetOrSliceMeet ? MIN(width, height) : MAX(width, height); + if(scale != NULL) { + scale[0] = ratio; + scale[1] = ratio; + } + // scale the viewBox into the drawingRect CGAffineTransform transform = CGAffineTransformIdentity; transform = CGAffineTransformConcat(transform, CGAffineTransformMakeScale(ratio, ratio)); @@ -217,18 +243,22 @@ CGSize IJSVGViewBoxComputeXMidYMax(CGContextRef ctx, CGRect viewBox, translate = CGAffineTransformMakeTranslation(-(viewBox.origin.x * ratio), -(viewBox.origin.y * ratio)); transform = CGAffineTransformConcat(transform, translate); - CGContextConcatCTM(ctx, transform); - - return CGSizeMake(ratio, ratio); + return CGRectApplyAffineTransform(drawingRect, transform); } -CGSize IJSVGViewBoxComputeXMaxYMin(CGContextRef ctx, CGRect viewBox, - CGRect drawingRect, IJSVGViewBoxMeetOrSlice meetOrSlice) +CGRect IJSVGViewBoxComputeRectXMaxYMin(CGRect viewBox, CGRect drawingRect, + IJSVGViewBoxMeetOrSlice meetOrSlice, + CGFloat* scale) { CGFloat width = drawingRect.size.width / viewBox.size.width; CGFloat height = drawingRect.size.height / viewBox.size.height; CGFloat ratio = meetOrSlice == IJSVGViewBoxMeetOrSliceMeet ? MIN(width, height) : MAX(width, height); + if(scale != NULL) { + scale[0] = ratio; + scale[1] = ratio; + } + // scale the viewBox into the drawingRect CGAffineTransform transform = CGAffineTransformIdentity; transform = CGAffineTransformConcat(transform, CGAffineTransformMakeScale(ratio, ratio)); @@ -240,18 +270,22 @@ CGSize IJSVGViewBoxComputeXMaxYMin(CGContextRef ctx, CGRect viewBox, translate = CGAffineTransformMakeTranslation(-(viewBox.origin.x * ratio), -(viewBox.origin.y * ratio)); transform = CGAffineTransformConcat(transform, translate); - CGContextConcatCTM(ctx, transform); - - return CGSizeMake(ratio, ratio); + return CGRectApplyAffineTransform(drawingRect, transform); } -CGSize IJSVGViewBoxComputeXMinYMax(CGContextRef ctx, CGRect viewBox, - CGRect drawingRect, IJSVGViewBoxMeetOrSlice meetOrSlice) +CGRect IJSVGViewBoxComputeRectXMinYMax(CGRect viewBox, CGRect drawingRect, + IJSVGViewBoxMeetOrSlice meetOrSlice, + CGFloat* scale) { CGFloat width = drawingRect.size.width / viewBox.size.width; CGFloat height = drawingRect.size.height / viewBox.size.height; CGFloat ratio = meetOrSlice == IJSVGViewBoxMeetOrSliceMeet ? MIN(width, height) : MAX(width, height); + if(scale != NULL) { + scale[0] = ratio; + scale[1] = ratio; + } + // scale the viewBox into the drawingRect CGAffineTransform transform = CGAffineTransformIdentity; transform = CGAffineTransformConcat(transform, CGAffineTransformMakeScale(ratio, ratio)); @@ -263,18 +297,22 @@ CGSize IJSVGViewBoxComputeXMinYMax(CGContextRef ctx, CGRect viewBox, translate = CGAffineTransformMakeTranslation(-(viewBox.origin.x * ratio), -(viewBox.origin.y * ratio)); transform = CGAffineTransformConcat(transform, translate); - CGContextConcatCTM(ctx, transform); - - return CGSizeMake(ratio, ratio); + return CGRectApplyAffineTransform(drawingRect, transform); } -CGSize IJSVGViewBoxComputeXMaxYMax(CGContextRef ctx, CGRect viewBox, - CGRect drawingRect, IJSVGViewBoxMeetOrSlice meetOrSlice) +CGRect IJSVGViewBoxComputeRectXMaxYMax(CGRect viewBox, CGRect drawingRect, + IJSVGViewBoxMeetOrSlice meetOrSlice, + CGFloat* scale) { CGFloat width = drawingRect.size.width / viewBox.size.width; CGFloat height = drawingRect.size.height / viewBox.size.height; CGFloat ratio = meetOrSlice == IJSVGViewBoxMeetOrSliceMeet ? MIN(width, height) : MAX(width, height); + if(scale != NULL) { + scale[0] = ratio; + scale[1] = ratio; + } + // scale the viewBox into the drawingRect CGAffineTransform transform = CGAffineTransformIdentity; transform = CGAffineTransformConcat(transform, CGAffineTransformMakeScale(ratio, ratio)); @@ -286,17 +324,21 @@ CGSize IJSVGViewBoxComputeXMaxYMax(CGContextRef ctx, CGRect viewBox, translate = CGAffineTransformMakeTranslation(-(viewBox.origin.x * ratio), -(viewBox.origin.y * ratio)); transform = CGAffineTransformConcat(transform, translate); - CGContextConcatCTM(ctx, transform); - - return CGSizeMake(ratio, ratio); + return CGRectApplyAffineTransform(drawingRect, transform); } -CGSize IJSVGViewBoxComputeNone(CGContextRef ctx, CGRect viewBox, - CGRect drawingRect, IJSVGViewBoxMeetOrSlice meetOrSlice) +CGRect IJSVGViewBoxComputeRectNone(CGRect viewBox, CGRect drawingRect, + IJSVGViewBoxMeetOrSlice meetOrSlice, + CGFloat* scale) { CGFloat width = drawingRect.size.width / viewBox.size.width; CGFloat height = drawingRect.size.height / viewBox.size.height; + if(scale != NULL) { + scale[0] = width; + scale[1] = height; + } + // scale the viewBox into the drawingRect CGAffineTransform transform = CGAffineTransformIdentity; transform = CGAffineTransformConcat(transform, CGAffineTransformMakeScale(width, height)); @@ -308,9 +350,30 @@ CGSize IJSVGViewBoxComputeNone(CGContextRef ctx, CGRect viewBox, translate = CGAffineTransformMakeTranslation(-(viewBox.origin.x * width), -(viewBox.origin.y * height)); transform = CGAffineTransformConcat(transform, translate); - CGContextConcatCTM(ctx, transform); - - return CGSizeMake(width, height); + return CGRectApplyAffineTransform(drawingRect, transform); +} + +CGRect IJSVGContextViewBoxConcatNone(CGContextRef ctx, CGRect viewBox, + CGRect drawingRect, IJSVGViewBoxMeetOrSlice meetOrSlice, + CGFloat* scale) +{ + CGFloat ratioX = 1.f; + CGFloat ratioY = 1.f; + CGRect rect = IJSVGViewBoxComputeRectNone(viewBox, drawingRect, meetOrSlice, scale); + CGContextTranslateCTM(ctx, rect.origin.x, rect.origin.y); + CGContextScaleCTM(ctx, ratioX, ratioY); + return rect; +} + +CGRect IJSVGContextViewBoxConcat(CGContextRef ctx, IJSVGViewBoxComputeRectFunction function, + CGRect viewBox, CGRect drawingRect, + IJSVGViewBoxMeetOrSlice meetOrSlice, + CGFloat* scale) +{ + CGRect rect = function(viewBox, drawingRect, meetOrSlice, scale); + CGContextTranslateCTM(ctx, rect.origin.x, rect.origin.y); + CGContextScaleCTM(ctx, scale[0], scale[1]); + return rect; } void IJSVGContextDrawViewBox(CGContextRef ctx, CGRect viewBox, CGRect boundingBox, @@ -324,6 +387,56 @@ void IJSVGContextDrawViewBox(CGContextRef ctx, CGRect viewBox, CGRect boundingBo drawingBlock:block]; } +CGRect IJSVGViewBoxComputeRect(CGRect viewBox, CGRect drawingRect, IJSVGViewBoxAlignment alignment, + IJSVGViewBoxMeetOrSlice meetOrSlice, CGFloat* scale) +{ + switch(alignment) { + default: + case IJSVGViewBoxAlignmentUnknown: + case IJSVGViewBoxAlignmentXMidYMid: { + return IJSVGViewBoxComputeRectXMidYMid(viewBox, drawingRect, + meetOrSlice, scale); + } + case IJSVGViewBoxAlignmentNone: { + return IJSVGViewBoxComputeRectNone(viewBox, drawingRect, + meetOrSlice, scale); + } + case IJSVGViewBoxAlignmentXMaxYMax: { + return IJSVGViewBoxComputeRectXMaxYMax(viewBox, drawingRect, + meetOrSlice, scale); + } + case IJSVGViewBoxAlignmentXMaxYMid: { + return IJSVGViewBoxComputeRectXMaxYMid(viewBox, drawingRect, + meetOrSlice, scale); + } + case IJSVGViewBoxAlignmentXMaxYMin: { + return IJSVGViewBoxComputeRectXMaxYMin(viewBox, drawingRect, + meetOrSlice, scale); + } + case IJSVGViewBoxAlignmentXMidYMax: { + return IJSVGViewBoxComputeRectXMidYMax(viewBox, drawingRect, + meetOrSlice, scale); + } + case IJSVGViewBoxAlignmentXMidYMin: { + return IJSVGViewBoxComputeRectXMidYMin(viewBox, drawingRect, + meetOrSlice, scale); + } + case IJSVGViewBoxAlignmentXMinYMax: { + return IJSVGViewBoxComputeRectXMinYMin(viewBox, drawingRect, + meetOrSlice, scale); + } + case IJSVGViewBoxAlignmentXMinYMid: { + return IJSVGViewBoxComputeRectXMinYMid(viewBox, drawingRect, + meetOrSlice, scale); + } + case IJSVGViewBoxAlignmentXMinYMin: { + return IJSVGViewBoxComputeRectXMinYMin(viewBox, drawingRect, + meetOrSlice, scale); + } + } + return CGRectNull; +} + + (void)drawViewBox:(CGRect)viewBox inRect:(CGRect)drawingRect alignment:(IJSVGViewBoxAlignment)alignment @@ -334,7 +447,6 @@ void IJSVGContextDrawViewBox(CGContextRef ctx, CGRect viewBox, CGRect boundingBo // this is equal to none, dont do anything fancy if(CGRectIsNull(viewBox) == YES || CGRectEqualToRect(viewBox, CGRectZero) == YES) { - block(CGSizeMake(1.f, 1.f)); return; } @@ -342,51 +454,78 @@ void IJSVGContextDrawViewBox(CGContextRef ctx, CGRect viewBox, CGRect boundingBo if(meetOrSlice == IJSVGViewBoxMeetOrSliceSlice) { CGContextClipToRect(ctx, drawingRect); } - CGSize scale = CGSizeZero; + + // init the scaler + CGFloat* scale = (CGFloat*)malloc(sizeof(CGFloat)*2); + scale[0] = 1.f; + scale[1] = 1.f; + + CGRect computedRect = CGRectNull; switch(alignment) { case IJSVGViewBoxAlignmentNone: { - scale = IJSVGViewBoxComputeNone(ctx, viewBox, drawingRect, meetOrSlice); + computedRect = IJSVGContextViewBoxConcat(ctx, &IJSVGViewBoxComputeRectNone, + viewBox, drawingRect, meetOrSlice, + scale); break; } case IJSVGViewBoxAlignmentUnknown: case IJSVGViewBoxAlignmentXMidYMid: { - scale = IJSVGViewBoxComputeXMidYMid(ctx, viewBox, drawingRect, meetOrSlice); + computedRect = IJSVGContextViewBoxConcat(ctx, &IJSVGViewBoxComputeRectXMidYMid, + viewBox, drawingRect, meetOrSlice, + scale); break; } case IJSVGViewBoxAlignmentXMinYMid: { - scale = IJSVGViewBoxComputeXMinYMid(ctx, viewBox, drawingRect, meetOrSlice); + computedRect = IJSVGContextViewBoxConcat(ctx, &IJSVGViewBoxComputeRectXMinYMid, + viewBox, drawingRect, meetOrSlice, + scale); break; } case IJSVGViewBoxAlignmentXMaxYMid: { - scale = IJSVGViewBoxComputeXMaxYMid(ctx, viewBox, drawingRect, meetOrSlice); + computedRect = IJSVGContextViewBoxConcat(ctx, &IJSVGViewBoxComputeRectXMaxYMid, + viewBox, drawingRect, meetOrSlice, + scale); break; } case IJSVGViewBoxAlignmentXMidYMin: { - scale = IJSVGViewBoxComputeXMidYMin(ctx, viewBox, drawingRect, meetOrSlice); + computedRect = IJSVGContextViewBoxConcat(ctx, &IJSVGViewBoxComputeRectXMidYMin, + viewBox, drawingRect, meetOrSlice, + scale); break; } case IJSVGViewBoxAlignmentXMidYMax: { - scale = IJSVGViewBoxComputeXMidYMax(ctx, viewBox, drawingRect, meetOrSlice); + computedRect = IJSVGContextViewBoxConcat(ctx, &IJSVGViewBoxComputeRectXMidYMax, + viewBox, drawingRect, meetOrSlice, + scale); break; } case IJSVGViewBoxAlignmentXMinYMin: { - scale = IJSVGViewBoxComputeXMinYMin(ctx, viewBox, drawingRect, meetOrSlice); + computedRect = IJSVGContextViewBoxConcat(ctx, &IJSVGViewBoxComputeRectXMinYMin, + viewBox, drawingRect, meetOrSlice, + scale); break; } case IJSVGViewBoxAlignmentXMaxYMin: { - scale = IJSVGViewBoxComputeXMaxYMin(ctx, viewBox, drawingRect, meetOrSlice); + computedRect = IJSVGContextViewBoxConcat(ctx, &IJSVGViewBoxComputeRectXMaxYMin, + viewBox, drawingRect, meetOrSlice, + scale); break; } case IJSVGViewBoxAlignmentXMinYMax: { - scale = IJSVGViewBoxComputeXMinYMax(ctx, viewBox, drawingRect, meetOrSlice); + computedRect = IJSVGContextViewBoxConcat(ctx, &IJSVGViewBoxComputeRectXMinYMax, + viewBox, drawingRect, meetOrSlice, + scale); break; } case IJSVGViewBoxAlignmentXMaxYMax: { - scale = IJSVGViewBoxComputeXMaxYMax(ctx, viewBox, drawingRect, meetOrSlice); + computedRect = IJSVGContextViewBoxConcat(ctx, &IJSVGViewBoxComputeRectXMaxYMax, + viewBox, drawingRect, meetOrSlice, + scale); break; } } - block(scale); + block(computedRect, scale); + free(scale); CGContextRestoreGState(ctx); } diff --git a/IJSVGExample/IJSVGExample/gump-bench.svg b/IJSVGExample/IJSVGExample/gump-bench.svg new file mode 100644 index 0000000..271eac9 --- /dev/null +++ b/IJSVGExample/IJSVGExample/gump-bench.svg @@ -0,0 +1,71 @@ + + + Bench, Forest Gump + + + + + + + + + + + + + + + + + + + + + + + + + + + + Box of Chocolates + + + + + + + + + + + + + + + + + Bench + + + + + + + + + + + + + + + + + + + + + + diff --git a/IJSVGExample/IJSVGExample/pattern-alignment.svg b/IJSVGExample/IJSVGExample/pattern-alignment.svg new file mode 100644 index 0000000..0da3415 --- /dev/null +++ b/IJSVGExample/IJSVGExample/pattern-alignment.svg @@ -0,0 +1,18 @@ + + + + + + + + + + + + + + + + + + diff --git a/IJSVGExample/IJSVGExample/sh.svg b/IJSVGExample/IJSVGExample/sh.svg new file mode 100644 index 0000000..36c9889 --- /dev/null +++ b/IJSVGExample/IJSVGExample/sh.svg @@ -0,0 +1,10 @@ + + + + + + + + + +