@@ -5194,25 +5194,243 @@ void com_codename1_impl_ios_IOSNative_updatePersonWithRecordID___int_com_codenam
51945194#endif
51955195}
51965196
5197- static UIImage* cn1_captureView (UIView *view) {
5197+ static BOOL cn1_renderViewIntoContext (UIView *renderView, UIView *rootView, CGContextRef ctx) {
5198+ if (renderView == nil || rootView == nil || ctx == NULL ) {
5199+ return NO ;
5200+ }
5201+ if (renderView.hidden || renderView.alpha <= 0 .0f ) {
5202+ return NO ;
5203+ }
5204+
5205+ CGRect localBounds = renderView.bounds ;
5206+ if (CGRectIsEmpty (localBounds) || localBounds.size .width <= 0 .0f || localBounds.size .height <= 0 .0f ) {
5207+ return NO ;
5208+ }
5209+
5210+ CGRect translatedRect = [rootView convertRect: localBounds fromView: renderView];
5211+ if (CGRectIsNull (translatedRect) || CGRectIsEmpty (translatedRect)) {
5212+ return NO ;
5213+ }
5214+
5215+ CGContextSaveGState (ctx);
5216+ CGContextTranslateCTM (ctx, translatedRect.origin .x , translatedRect.origin .y );
5217+ BOOL drawn = NO ;
5218+ #if defined(ENABLE_WKWEBVIEW) && defined(supportsWKWebKit)
5219+ if ([renderView isKindOfClass: [WKWebView class ]]) {
5220+ WKWebView *webView = (WKWebView *)renderView;
5221+ #if __IPHONE_OS_VERSION_MAX_ALLOWED >= 110000
5222+ if (!drawn && @available (iOS 11.0 , *)) {
5223+ CGRect snapshotRect = CGRectIntersection (webView.bounds , localBounds);
5224+ if (!CGRectIsNull (snapshotRect) && !CGRectIsEmpty (snapshotRect)) {
5225+ WKSnapshotConfiguration *config = [[WKSnapshotConfiguration alloc ] init ];
5226+ config.rect = snapshotRect;
5227+ if (snapshotRect.size .width > 0 .0f ) {
5228+ config.snapshotWidth = @(snapshotRect.size .width );
5229+ }
5230+ #ifdef __IPHONE_13_0
5231+ if (@available (iOS 13.0 , *)) {
5232+ config.afterScreenUpdates = YES ;
5233+ }
5234+ #endif
5235+ __block UIImage *snapshotImage = nil ;
5236+ __block BOOL snapshotComplete = NO ;
5237+ [webView takeSnapshotWithConfiguration: config completionHandler: ^(UIImage * _Nullable image, NSError * _Nullable error) {
5238+ if (image != nil ) {
5239+ snapshotImage = image;
5240+ } else if (error != nil ) {
5241+ NSLog (@" WKWebView snapshot failed: %@ " , error);
5242+ }
5243+ snapshotComplete = YES ;
5244+ }];
5245+ [config release ];
5246+
5247+ if (!snapshotComplete) {
5248+ NSTimeInterval timeout = 1.0 ;
5249+ while (!snapshotComplete && timeout > 0 ) {
5250+ NSTimeInterval step = 0.01 ;
5251+ NSDate *stepDate = [NSDate dateWithTimeIntervalSinceNow: step];
5252+ [[NSRunLoop currentRunLoop ] runMode: NSDefaultRunLoopMode beforeDate: stepDate];
5253+ timeout -= step;
5254+ }
5255+ }
5256+
5257+ if (snapshotImage != nil ) {
5258+ [snapshotImage drawInRect: CGRectMake (0 , 0 , localBounds.size.width, localBounds.size.height)];
5259+ drawn = YES ;
5260+ }
5261+ }
5262+ }
5263+ #endif
5264+ if (!drawn) {
5265+ UIView *snapshotView = [renderView snapshotViewAfterScreenUpdates: YES ];
5266+ if (snapshotView != nil ) {
5267+ BOOL snapshotDrawn = NO ;
5268+ if ([snapshotView respondsToSelector: @selector (drawViewHierarchyInRect:afterScreenUpdates: )]) {
5269+ snapshotDrawn = [snapshotView drawViewHierarchyInRect: snapshotView.bounds afterScreenUpdates: YES ];
5270+ }
5271+ if (!snapshotDrawn) {
5272+ [snapshotView.layer renderInContext: ctx];
5273+ }
5274+ drawn = YES ;
5275+ }
5276+ }
5277+ }
5278+ #endif
5279+ if (!drawn && [renderView respondsToSelector: @selector (drawViewHierarchyInRect:afterScreenUpdates: )]) {
5280+ drawn = [renderView drawViewHierarchyInRect: localBounds afterScreenUpdates: YES ];
5281+ }
5282+ if (!drawn) {
5283+ [renderView.layer renderInContext: ctx];
5284+ drawn = YES ;
5285+ }
5286+ CGContextRestoreGState (ctx);
5287+ return drawn;
5288+ }
5289+
5290+ static void cn1_renderPeerComponents (UIView *rootView, CGContextRef ctx) {
5291+ CodenameOne_GLViewController *controller = [CodenameOne_GLViewController instance ];
5292+ EAGLView *glView = [controller eaglView ];
5293+ if (glView == nil || rootView == nil || ctx == NULL ) {
5294+ return ;
5295+ }
5296+
5297+ UIView *peerLayer = glView.peerComponentsLayer ;
5298+ NSArray <UIView *> *peerCandidates = nil ;
5299+ if (peerLayer != nil ) {
5300+ [peerLayer layoutIfNeeded ];
5301+ peerCandidates = peerLayer.subviews ;
5302+ } else {
5303+ [glView layoutIfNeeded ];
5304+ peerCandidates = glView.subviews ;
5305+ }
5306+
5307+ if (peerCandidates.count == 0 ) {
5308+ return ;
5309+ }
5310+
5311+ for (UIView *peerView in peerCandidates) {
5312+ if (![peerView isKindOfClass: [UIView class ]]) {
5313+ continue ;
5314+ }
5315+ cn1_renderViewIntoContext (peerView, rootView, ctx);
5316+ }
5317+ }
5318+
5319+ static UIView* cn1_rootViewForCapture (UIView *view) {
51985320 if (view == nil ) {
51995321 return nil ;
52005322 }
5201- CGSize size = view.bounds .size ;
5323+
5324+ UIView *rootView = view;
5325+ UIWindow *window = view.window ;
5326+
5327+ if (window == nil ) {
5328+ NSArray <UIWindow*> *windows = [UIApplication sharedApplication ].windows ;
5329+ for (UIWindow *candidate in windows) {
5330+ if ([view isDescendantOfView: candidate]) {
5331+ window = candidate;
5332+ break ;
5333+ }
5334+ }
5335+ }
5336+
5337+ if (window == nil ) {
5338+ #if __IPHONE_OS_VERSION_MAX_ALLOWED >= 130000
5339+ if (@available (iOS 13.0 , *)) {
5340+ NSSet <UIScene *> *connectedScenes = [UIApplication sharedApplication ].connectedScenes ;
5341+ for (UIScene *scene in connectedScenes) {
5342+ if (![scene isKindOfClass: [UIWindowScene class ]]) {
5343+ continue ;
5344+ }
5345+ if (scene.activationState != UISceneActivationStateForegroundActive) {
5346+ continue ;
5347+ }
5348+ UIWindowScene *windowScene = (UIWindowScene *)scene;
5349+ for (UIWindow *candidate in windowScene.windows ) {
5350+ if ([view isDescendantOfView: candidate]) {
5351+ window = candidate;
5352+ break ;
5353+ }
5354+ }
5355+ if (window != nil ) {
5356+ break ;
5357+ }
5358+ if (windowScene.windows .count > 0 && window == nil ) {
5359+ window = windowScene.windows .firstObject ;
5360+ }
5361+ }
5362+ }
5363+ #endif
5364+ }
5365+
5366+ if (window == nil ) {
5367+ window = [UIApplication sharedApplication ].keyWindow ;
5368+ }
5369+
5370+ if (window != nil ) {
5371+ rootView = window;
5372+ } else {
5373+ UIView *candidate = view;
5374+ while (candidate.superview != nil ) {
5375+ candidate = candidate.superview ;
5376+ }
5377+ rootView = candidate;
5378+ }
5379+
5380+ return rootView;
5381+ }
5382+
5383+ static UIImage* cn1_captureView (UIView *view) {
5384+ UIView *rootView = cn1_rootViewForCapture (view);
5385+ if (rootView == nil ) {
5386+ return nil ;
5387+ }
5388+
5389+ CGSize size = rootView.bounds .size ;
52025390 if (size.width <= 0 || size.height <= 0 ) {
52035391 return nil ;
52045392 }
52055393
5206- UIGraphicsBeginImageContextWithOptions (size, view.opaque , 0.0 );
5207- BOOL ok = NO ;
5208- if ([view respondsToSelector: @selector (drawViewHierarchyInRect:afterScreenUpdates: )]) {
5209- ok = [view drawViewHierarchyInRect: view.bounds afterScreenUpdates: YES ];
5394+ UIGraphicsBeginImageContextWithOptions (size, rootView.opaque , 0.0 );
5395+ CGContextRef ctx = UIGraphicsGetCurrentContext ();
5396+ if (ctx == NULL ) {
5397+ UIGraphicsEndImageContext ();
5398+ return nil ;
52105399 }
5211- if (!ok) {
5212- [view.layer renderInContext: UIGraphicsGetCurrentContext ()];
5400+
5401+ [rootView layoutIfNeeded ];
5402+
5403+ cn1_renderViewIntoContext (view, rootView, ctx);
5404+
5405+ CodenameOne_GLViewController *controller = [CodenameOne_GLViewController instance ];
5406+ EAGLView *glView = [controller eaglView ];
5407+ if (glView != nil && glView != view) {
5408+ cn1_renderViewIntoContext (glView, rootView, ctx);
52135409 }
5410+
5411+ cn1_renderPeerComponents (rootView, ctx);
5412+
52145413 UIImage *image = UIGraphicsGetImageFromCurrentImageContext ();
52155414 UIGraphicsEndImageContext ();
5415+
5416+ if (rootView != view) {
5417+ CGRect targetFrame = [rootView convertRect: view.bounds fromView: view];
5418+ targetFrame = CGRectIntersection (targetFrame, CGRectMake (0 , 0 , size.width , size.height ));
5419+ if (!CGRectIsNull (targetFrame) && targetFrame.size .width > 0 && targetFrame.size .height > 0 ) {
5420+ CGRect integralTarget = CGRectIntegral (targetFrame);
5421+ CGRect pixelRect = CGRectMake (integralTarget.origin .x * image.scale ,
5422+ integralTarget.origin .y * image.scale ,
5423+ integralTarget.size .width * image.scale ,
5424+ integralTarget.size .height * image.scale );
5425+ CGImageRef cropped = CGImageCreateWithImageInRect (image.CGImage , pixelRect);
5426+ if (cropped != nil ) {
5427+ UIImage *croppedImage = [UIImage imageWithCGImage: cropped scale: image.scale orientation: image.imageOrientation];
5428+ CGImageRelease (cropped);
5429+ image = croppedImage;
5430+ }
5431+ }
5432+ }
5433+
52165434 return image;
52175435}
52185436
0 commit comments