| 
				
			 | 
			
			
				@@ -5,18 +5,17 @@ import android.graphics.Bitmap; 
			 | 
		
	
		
			
			| 
				5
			 | 
			
				5
			 | 
			
			
				 import android.graphics.Canvas; 
			 | 
		
	
		
			
			| 
				6
			 | 
			
				6
			 | 
			
			
				 import android.graphics.Color; 
			 | 
		
	
		
			
			| 
				7
			 | 
			
				7
			 | 
			
			
				 import android.graphics.Matrix; 
			 | 
		
	
		
			
			| 
				
			 | 
			
				8
			 | 
			
			
				+import android.graphics.Paint; 
			 | 
		
	
		
			
			| 
				8
			 | 
			
				9
			 | 
			
			
				 import android.graphics.Point; 
			 | 
		
	
		
			
			| 
				9
			 | 
			
				
			 | 
			
			
				-import android.graphics.Rect; 
			 | 
		
	
		
			
			| 
				10
			 | 
			
				
			 | 
			
			
				-import android.graphics.RectF; 
			 | 
		
	
		
			
			| 
				11
			 | 
			
				10
			 | 
			
			
				 import android.net.Uri; 
			 | 
		
	
		
			
			| 
				12
			 | 
			
				11
			 | 
			
			
				 import android.support.annotation.IntDef; 
			 | 
		
	
		
			
			| 
				13
			 | 
			
				12
			 | 
			
			
				 import android.support.annotation.NonNull; 
			 | 
		
	
		
			
			| 
				14
			 | 
			
				13
			 | 
			
			
				 import android.support.annotation.StringDef; 
			 | 
		
	
		
			
			| 
				15
			 | 
			
				14
			 | 
			
			
				 import android.util.Base64; 
			 | 
		
	
		
			
			| 
				
			 | 
			
				15
			 | 
			
			
				+import android.util.Log; 
			 | 
		
	
		
			
			| 
				16
			 | 
			
				16
			 | 
			
			
				 import android.view.TextureView; 
			 | 
		
	
		
			
			| 
				17
			 | 
			
				17
			 | 
			
			
				 import android.view.View; 
			 | 
		
	
		
			
			| 
				18
			 | 
			
				18
			 | 
			
			
				 import android.view.ViewGroup; 
			 | 
		
	
		
			
			| 
				19
			 | 
			
				
			 | 
			
			
				-import android.view.ViewParent; 
			 | 
		
	
		
			
			| 
				20
			 | 
			
				19
			 | 
			
			
				 import android.widget.ScrollView; 
			 | 
		
	
		
			
			| 
				21
			 | 
			
				20
			 | 
			
			
				  
			 | 
		
	
		
			
			| 
				22
			 | 
			
				21
			 | 
			
			
				 import com.facebook.react.bridge.Promise; 
			 | 
		
	
	
		
			
			| 
				
			 | 
			
			
				@@ -34,6 +33,7 @@ import java.nio.charset.Charset; 
			 | 
		
	
		
			
			| 
				34
			 | 
			
				33
			 | 
			
			
				 import java.util.ArrayList; 
			 | 
		
	
		
			
			| 
				35
			 | 
			
				34
			 | 
			
			
				 import java.util.Arrays; 
			 | 
		
	
		
			
			| 
				36
			 | 
			
				35
			 | 
			
			
				 import java.util.Collections; 
			 | 
		
	
		
			
			| 
				
			 | 
			
				36
			 | 
			
			
				+import java.util.LinkedList; 
			 | 
		
	
		
			
			| 
				37
			 | 
			
				37
			 | 
			
			
				 import java.util.List; 
			 | 
		
	
		
			
			| 
				38
			 | 
			
				38
			 | 
			
			
				 import java.util.Locale; 
			 | 
		
	
		
			
			| 
				39
			 | 
			
				39
			 | 
			
			
				 import java.util.Set; 
			 | 
		
	
	
		
			
			| 
				
			 | 
			
			
				@@ -42,12 +42,21 @@ import java.util.zip.Deflater; 
			 | 
		
	
		
			
			| 
				42
			 | 
			
				42
			 | 
			
			
				  
			 | 
		
	
		
			
			| 
				43
			 | 
			
				43
			 | 
			
			
				 import javax.annotation.Nullable; 
			 | 
		
	
		
			
			| 
				44
			 | 
			
				44
			 | 
			
			
				  
			 | 
		
	
		
			
			| 
				
			 | 
			
				45
			 | 
			
			
				+import static android.view.View.VISIBLE; 
			 | 
		
	
		
			
			| 
				
			 | 
			
				46
			 | 
			
			
				+ 
			 | 
		
	
		
			
			| 
				45
			 | 
			
				47
			 | 
			
			
				 /** 
			 | 
		
	
		
			
			| 
				46
			 | 
			
				48
			 | 
			
			
				  * Snapshot utility class allow to screenshot a view. 
			 | 
		
	
		
			
			| 
				47
			 | 
			
				49
			 | 
			
			
				  */ 
			 | 
		
	
		
			
			| 
				48
			 | 
			
				50
			 | 
			
			
				 public class ViewShot implements UIBlock { 
			 | 
		
	
		
			
			| 
				49
			 | 
			
				51
			 | 
			
			
				     //region Constants 
			 | 
		
	
		
			
			| 
				50
			 | 
			
				
			 | 
			
			
				-    static final String ERROR_UNABLE_TO_SNAPSHOT = "E_UNABLE_TO_SNAPSHOT"; 
			 | 
		
	
		
			
			| 
				
			 | 
			
				52
			 | 
			
			
				+    /** 
			 | 
		
	
		
			
			| 
				
			 | 
			
				53
			 | 
			
			
				+     * Tag fort Class logs. 
			 | 
		
	
		
			
			| 
				
			 | 
			
				54
			 | 
			
			
				+     */ 
			 | 
		
	
		
			
			| 
				
			 | 
			
				55
			 | 
			
			
				+    private static final String TAG = ViewShot.class.getSimpleName(); 
			 | 
		
	
		
			
			| 
				
			 | 
			
				56
			 | 
			
			
				+    /** 
			 | 
		
	
		
			
			| 
				
			 | 
			
				57
			 | 
			
			
				+     * Error code that we return to RN. 
			 | 
		
	
		
			
			| 
				
			 | 
			
				58
			 | 
			
			
				+     */ 
			 | 
		
	
		
			
			| 
				
			 | 
			
				59
			 | 
			
			
				+    public static final String ERROR_UNABLE_TO_SNAPSHOT = "E_UNABLE_TO_SNAPSHOT"; 
			 | 
		
	
		
			
			| 
				51
			 | 
			
				60
			 | 
			
			
				     /** 
			 | 
		
	
		
			
			| 
				52
			 | 
			
				61
			 | 
			
			
				      * pre-allocated output stream size for screenshot. In real life example it will eb around 7Mb. 
			 | 
		
	
		
			
			| 
				53
			 | 
			
				62
			 | 
			
			
				      */ 
			 | 
		
	
	
		
			
			| 
				
			 | 
			
			
				@@ -163,6 +172,7 @@ public class ViewShot implements UIBlock { 
			 | 
		
	
		
			
			| 
				163
			 | 
			
				172
			 | 
			
			
				         } 
			 | 
		
	
		
			
			| 
				164
			 | 
			
				173
			 | 
			
			
				  
			 | 
		
	
		
			
			| 
				165
			 | 
			
				174
			 | 
			
			
				         if (view == null) { 
			 | 
		
	
		
			
			| 
				
			 | 
			
				175
			 | 
			
			
				+            Log.e(TAG, "No view found with reactTag: " + tag, new AssertionError()); 
			 | 
		
	
		
			
			| 
				166
			 | 
			
				176
			 | 
			
			
				             promise.reject(ERROR_UNABLE_TO_SNAPSHOT, "No view found with reactTag: " + tag); 
			 | 
		
	
		
			
			| 
				167
			 | 
			
				177
			 | 
			
			
				             return; 
			 | 
		
	
		
			
			| 
				168
			 | 
			
				178
			 | 
			
			
				         } 
			 | 
		
	
	
		
			
			| 
				
			 | 
			
			
				@@ -181,7 +191,8 @@ public class ViewShot implements UIBlock { 
			 | 
		
	
		
			
			| 
				181
			 | 
			
				191
			 | 
			
			
				             } else if (Results.DATA_URI.equals(result)) { 
			 | 
		
	
		
			
			| 
				182
			 | 
			
				192
			 | 
			
			
				                 saveToDataUriString(view); 
			 | 
		
	
		
			
			| 
				183
			 | 
			
				193
			 | 
			
			
				             } 
			 | 
		
	
		
			
			| 
				184
			 | 
			
				
			 | 
			
			
				-        } catch (final Throwable ignored) { 
			 | 
		
	
		
			
			| 
				
			 | 
			
				194
			 | 
			
			
				+        } catch (final Throwable ex) { 
			 | 
		
	
		
			
			| 
				
			 | 
			
				195
			 | 
			
			
				+            Log.e(TAG, "Failed to capture view snapshot", ex); 
			 | 
		
	
		
			
			| 
				185
			 | 
			
				196
			 | 
			
			
				             promise.reject(ERROR_UNABLE_TO_SNAPSHOT, "Failed to capture view snapshot"); 
			 | 
		
	
		
			
			| 
				186
			 | 
			
				197
			 | 
			
			
				         } 
			 | 
		
	
		
			
			| 
				187
			 | 
			
				198
			 | 
			
			
				     } 
			 | 
		
	
	
		
			
			| 
				
			 | 
			
			
				@@ -290,6 +301,8 @@ public class ViewShot implements UIBlock { 
			 | 
		
	
		
			
			| 
				290
			 | 
			
				301
			 | 
			
			
				      */ 
			 | 
		
	
		
			
			| 
				291
			 | 
			
				302
			 | 
			
			
				     private Point captureView(@NonNull final View view, @NonNull final OutputStream os) throws IOException { 
			 | 
		
	
		
			
			| 
				292
			 | 
			
				303
			 | 
			
			
				         try { 
			 | 
		
	
		
			
			| 
				
			 | 
			
				304
			 | 
			
			
				+            DebugViews.longDebug(TAG, DebugViews.logViewHierarchy(this.currentActivity)); 
			 | 
		
	
		
			
			| 
				
			 | 
			
				305
			 | 
			
			
				+ 
			 | 
		
	
		
			
			| 
				293
			 | 
			
				306
			 | 
			
			
				             return captureViewImpl(view, os); 
			 | 
		
	
		
			
			| 
				294
			 | 
			
				307
			 | 
			
			
				         } finally { 
			 | 
		
	
		
			
			| 
				295
			 | 
			
				308
			 | 
			
			
				             os.close(); 
			 | 
		
	
	
		
			
			| 
				
			 | 
			
			
				@@ -310,7 +323,7 @@ public class ViewShot implements UIBlock { 
			 | 
		
	
		
			
			| 
				310
			 | 
			
				323
			 | 
			
			
				             throw new RuntimeException("Impossible to snapshot the view: view is invalid"); 
			 | 
		
	
		
			
			| 
				311
			 | 
			
				324
			 | 
			
			
				         } 
			 | 
		
	
		
			
			| 
				312
			 | 
			
				325
			 | 
			
			
				  
			 | 
		
	
		
			
			| 
				313
			 | 
			
				
			 | 
			
			
				-        //evaluate real height 
			 | 
		
	
		
			
			| 
				
			 | 
			
				326
			 | 
			
			
				+        // evaluate real height 
			 | 
		
	
		
			
			| 
				314
			 | 
			
				327
			 | 
			
			
				         if (snapshotContentContainer) { 
			 | 
		
	
		
			
			| 
				315
			 | 
			
				328
			 | 
			
			
				             h = 0; 
			 | 
		
	
		
			
			| 
				316
			 | 
			
				329
			 | 
			
			
				             ScrollView scrollView = (ScrollView) view; 
			 | 
		
	
	
		
			
			| 
				
			 | 
			
			
				@@ -322,6 +335,14 @@ public class ViewShot implements UIBlock { 
			 | 
		
	
		
			
			| 
				322
			 | 
			
				335
			 | 
			
			
				         final Point resolution = new Point(w, h); 
			 | 
		
	
		
			
			| 
				323
			 | 
			
				336
			 | 
			
			
				         Bitmap bitmap = getBitmapForScreenshot(w, h); 
			 | 
		
	
		
			
			| 
				324
			 | 
			
				337
			 | 
			
			
				  
			 | 
		
	
		
			
			| 
				
			 | 
			
				338
			 | 
			
			
				+        final Paint paint = new Paint(); 
			 | 
		
	
		
			
			| 
				
			 | 
			
				339
			 | 
			
			
				+        paint.setAntiAlias(true); 
			 | 
		
	
		
			
			| 
				
			 | 
			
				340
			 | 
			
			
				+        paint.setFilterBitmap(true); 
			 | 
		
	
		
			
			| 
				
			 | 
			
				341
			 | 
			
			
				+        paint.setDither(true); 
			 | 
		
	
		
			
			| 
				
			 | 
			
				342
			 | 
			
			
				+ 
			 | 
		
	
		
			
			| 
				
			 | 
			
				343
			 | 
			
			
				+        // Uncomment next line if you want to wait attached android studio debugger: 
			 | 
		
	
		
			
			| 
				
			 | 
			
				344
			 | 
			
			
				+        //   Debug.waitForDebugger(); 
			 | 
		
	
		
			
			| 
				
			 | 
			
				345
			 | 
			
			
				+ 
			 | 
		
	
		
			
			| 
				325
			 | 
			
				346
			 | 
			
			
				         final Canvas c = new Canvas(bitmap); 
			 | 
		
	
		
			
			| 
				326
			 | 
			
				347
			 | 
			
			
				         view.draw(c); 
			 | 
		
	
		
			
			| 
				327
			 | 
			
				348
			 | 
			
			
				  
			 | 
		
	
	
		
			
			| 
				
			 | 
			
			
				@@ -331,28 +352,24 @@ public class ViewShot implements UIBlock { 
			 | 
		
	
		
			
			| 
				331
			 | 
			
				352
			 | 
			
			
				         for (final View child : childrenList) { 
			 | 
		
	
		
			
			| 
				332
			 | 
			
				353
			 | 
			
			
				             // skip any child that we don't know how to process 
			 | 
		
	
		
			
			| 
				333
			 | 
			
				354
			 | 
			
			
				             if (!(child instanceof TextureView)) continue; 
			 | 
		
	
		
			
			| 
				
			 | 
			
				355
			 | 
			
			
				+ 
			 | 
		
	
		
			
			| 
				334
			 | 
			
				356
			 | 
			
			
				             // skip all invisible to user child views 
			 | 
		
	
		
			
			| 
				335
			 | 
			
				
			 | 
			
			
				-            if (child.getVisibility() != View.VISIBLE) continue; 
			 | 
		
	
		
			
			| 
				
			 | 
			
				357
			 | 
			
			
				+            if (child.getVisibility() != VISIBLE) continue; 
			 | 
		
	
		
			
			| 
				336
			 | 
			
				358
			 | 
			
			
				  
			 | 
		
	
		
			
			| 
				337
			 | 
			
				359
			 | 
			
			
				             final TextureView tvChild = (TextureView) child; 
			 | 
		
	
		
			
			| 
				338
			 | 
			
				
			 | 
			
			
				-            tvChild.setOpaque(false); 
			 | 
		
	
		
			
			| 
				
			 | 
			
				360
			 | 
			
			
				+            tvChild.setOpaque(false); // <-- switch off background fill 
			 | 
		
	
		
			
			| 
				339
			 | 
			
				361
			 | 
			
			
				  
			 | 
		
	
		
			
			| 
				340
			 | 
			
				
			 | 
			
			
				-            final Point offsets = getParentOffsets(view, child); 
			 | 
		
	
		
			
			| 
				341
			 | 
			
				
			 | 
			
			
				-            final int left = child.getLeft() + child.getPaddingLeft() + offsets.x; 
			 | 
		
	
		
			
			| 
				342
			 | 
			
				
			 | 
			
			
				-            final int top = child.getTop() + child.getPaddingTop() + offsets.y; 
			 | 
		
	
		
			
			| 
				343
			 | 
			
				
			 | 
			
			
				-            final int childWidth = child.getWidth(); 
			 | 
		
	
		
			
			| 
				344
			 | 
			
				
			 | 
			
			
				-            final int childHeight = child.getHeight(); 
			 | 
		
	
		
			
			| 
				345
			 | 
			
				
			 | 
			
			
				-            final Rect source = new Rect(0, 0, childWidth, childHeight); 
			 | 
		
	
		
			
			| 
				346
			 | 
			
				
			 | 
			
			
				-            final RectF destination = new RectF(left, top, left + childWidth, top + childHeight); 
			 | 
		
	
		
			
			| 
				
			 | 
			
				362
			 | 
			
			
				+            // NOTE (olku): get re-usable bitmap. TextureView should use bitmaps with matching size, 
			 | 
		
	
		
			
			| 
				
			 | 
			
				363
			 | 
			
			
				+            // otherwise content of the TextureView will be scaled to provided bitmap dimensions 
			 | 
		
	
		
			
			| 
				
			 | 
			
				364
			 | 
			
			
				+            final Bitmap childBitmapBuffer = tvChild.getBitmap(getExactBitmapForScreenshot(child.getWidth(), child.getHeight())); 
			 | 
		
	
		
			
			| 
				347
			 | 
			
				365
			 | 
			
			
				  
			 | 
		
	
		
			
			| 
				348
			 | 
			
				
			 | 
			
			
				-            // get re-usable bitmap 
			 | 
		
	
		
			
			| 
				349
			 | 
			
				
			 | 
			
			
				-            final Bitmap childBitmapBuffer = tvChild.getBitmap(getBitmapForScreenshot(child.getWidth(), child.getHeight())); 
			 | 
		
	
		
			
			| 
				
			 | 
			
				366
			 | 
			
			
				+            final int countCanvasSave = c.save(); 
			 | 
		
	
		
			
			| 
				
			 | 
			
				367
			 | 
			
			
				+            applyTransformations(c, view, child); 
			 | 
		
	
		
			
			| 
				350
			 | 
			
				368
			 | 
			
			
				  
			 | 
		
	
		
			
			| 
				351
			 | 
			
				
			 | 
			
			
				-            c.save(); 
			 | 
		
	
		
			
			| 
				352
			 | 
			
				
			 | 
			
			
				-            c.setMatrix(concatMatrix(view, child)); 
			 | 
		
	
		
			
			| 
				353
			 | 
			
				369
			 | 
			
			
				             // due to re-use of bitmaps for screenshot, we can get bitmap that is bigger in size than requested 
			 | 
		
	
		
			
			| 
				354
			 | 
			
				
			 | 
			
			
				-            c.drawBitmap(childBitmapBuffer, source, destination, null); 
			 | 
		
	
		
			
			| 
				355
			 | 
			
				
			 | 
			
			
				-            c.restore(); 
			 | 
		
	
		
			
			| 
				
			 | 
			
				370
			 | 
			
			
				+            c.drawBitmap(childBitmapBuffer, 0, 0, paint); 
			 | 
		
	
		
			
			| 
				
			 | 
			
				371
			 | 
			
			
				+ 
			 | 
		
	
		
			
			| 
				
			 | 
			
				372
			 | 
			
			
				+            c.restoreToCount(countCanvasSave); 
			 | 
		
	
		
			
			| 
				356
			 | 
			
				373
			 | 
			
			
				             recycleBitmap(childBitmapBuffer); 
			 | 
		
	
		
			
			| 
				357
			 | 
			
				374
			 | 
			
			
				         } 
			 | 
		
	
		
			
			| 
				358
			 | 
			
				375
			 | 
			
			
				  
			 | 
		
	
	
		
			
			| 
				
			 | 
			
			
				@@ -380,38 +397,43 @@ public class ViewShot implements UIBlock { 
			 | 
		
	
		
			
			| 
				380
			 | 
			
				397
			 | 
			
			
				         return resolution; // return image width and height 
			 | 
		
	
		
			
			| 
				381
			 | 
			
				398
			 | 
			
			
				     } 
			 | 
		
	
		
			
			| 
				382
			 | 
			
				399
			 | 
			
			
				  
			 | 
		
	
		
			
			| 
				383
			 | 
			
				
			 | 
			
			
				-    /** Concat all the transformation matrix's from child to parent. */ 
			 | 
		
	
		
			
			| 
				
			 | 
			
				400
			 | 
			
			
				+    /** 
			 | 
		
	
		
			
			| 
				
			 | 
			
				401
			 | 
			
			
				+     * Concat all the transformation matrix's from parent to child. 
			 | 
		
	
		
			
			| 
				
			 | 
			
				402
			 | 
			
			
				+     */ 
			 | 
		
	
		
			
			| 
				384
			 | 
			
				403
			 | 
			
			
				     @NonNull 
			 | 
		
	
		
			
			| 
				385
			 | 
			
				
			 | 
			
			
				-    private Matrix concatMatrix(@NonNull final View view, @NonNull final View child){ 
			 | 
		
	
		
			
			| 
				
			 | 
			
				404
			 | 
			
			
				+    @SuppressWarnings("UnusedReturnValue") 
			 | 
		
	
		
			
			| 
				
			 | 
			
				405
			 | 
			
			
				+    private Matrix applyTransformations(final Canvas c, @NonNull final View root, @NonNull final View child) { 
			 | 
		
	
		
			
			| 
				386
			 | 
			
				406
			 | 
			
			
				         final Matrix transform = new Matrix(); 
			 | 
		
	
		
			
			| 
				
			 | 
			
				407
			 | 
			
			
				+        final LinkedList<View> ms = new LinkedList<>(); 
			 | 
		
	
		
			
			| 
				387
			 | 
			
				408
			 | 
			
			
				  
			 | 
		
	
		
			
			| 
				
			 | 
			
				409
			 | 
			
			
				+        // find all parents of the child view 
			 | 
		
	
		
			
			| 
				388
			 | 
			
				410
			 | 
			
			
				         View iterator = child; 
			 | 
		
	
		
			
			| 
				389
			 | 
			
				411
			 | 
			
			
				         do { 
			 | 
		
	
		
			
			| 
				
			 | 
			
				412
			 | 
			
			
				+            ms.add(iterator); 
			 | 
		
	
		
			
			| 
				390
			 | 
			
				413
			 | 
			
			
				  
			 | 
		
	
		
			
			| 
				391
			 | 
			
				
			 | 
			
			
				-            final Matrix m = iterator.getMatrix(); 
			 | 
		
	
		
			
			| 
				392
			 | 
			
				
			 | 
			
			
				-            transform.preConcat(m); 
			 | 
		
	
		
			
			| 
				393
			 | 
			
				
			 | 
			
			
				- 
			 | 
		
	
		
			
			| 
				394
			 | 
			
				
			 | 
			
			
				-            iterator = (View)iterator.getParent(); 
			 | 
		
	
		
			
			| 
				395
			 | 
			
				
			 | 
			
			
				-        } while( iterator != view ); 
			 | 
		
	
		
			
			| 
				
			 | 
			
				414
			 | 
			
			
				+            iterator = (View) iterator.getParent(); 
			 | 
		
	
		
			
			| 
				
			 | 
			
				415
			 | 
			
			
				+        } while (iterator != root); 
			 | 
		
	
		
			
			| 
				396
			 | 
			
				416
			 | 
			
			
				  
			 | 
		
	
		
			
			| 
				397
			 | 
			
				
			 | 
			
			
				-        return transform; 
			 | 
		
	
		
			
			| 
				398
			 | 
			
				
			 | 
			
			
				-    } 
			 | 
		
	
		
			
			| 
				399
			 | 
			
				
			 | 
			
			
				- 
			 | 
		
	
		
			
			| 
				400
			 | 
			
				
			 | 
			
			
				-    @NonNull 
			 | 
		
	
		
			
			| 
				401
			 | 
			
				
			 | 
			
			
				-    private Point getParentOffsets(@NonNull final View view, @NonNull final View child) { 
			 | 
		
	
		
			
			| 
				402
			 | 
			
				
			 | 
			
			
				-        int left = 0; 
			 | 
		
	
		
			
			| 
				403
			 | 
			
				
			 | 
			
			
				-        int top = 0; 
			 | 
		
	
		
			
			| 
				
			 | 
			
				417
			 | 
			
			
				+        // apply transformations from parent --> child order 
			 | 
		
	
		
			
			| 
				
			 | 
			
				418
			 | 
			
			
				+        Collections.reverse(ms); 
			 | 
		
	
		
			
			| 
				404
			 | 
			
				419
			 | 
			
			
				  
			 | 
		
	
		
			
			| 
				405
			 | 
			
				
			 | 
			
			
				-        View parentElem = (View) child.getParent(); 
			 | 
		
	
		
			
			| 
				406
			 | 
			
				
			 | 
			
			
				-        while (parentElem != null) { 
			 | 
		
	
		
			
			| 
				407
			 | 
			
				
			 | 
			
			
				-            if (parentElem == view) break; 
			 | 
		
	
		
			
			| 
				
			 | 
			
				420
			 | 
			
			
				+        for (final View v : ms) { 
			 | 
		
	
		
			
			| 
				
			 | 
			
				421
			 | 
			
			
				+            c.save(); 
			 | 
		
	
		
			
			| 
				408
			 | 
			
				422
			 | 
			
			
				  
			 | 
		
	
		
			
			| 
				409
			 | 
			
				
			 | 
			
			
				-            left += parentElem.getLeft(); 
			 | 
		
	
		
			
			| 
				410
			 | 
			
				
			 | 
			
			
				-            top += parentElem.getTop(); 
			 | 
		
	
		
			
			| 
				411
			 | 
			
				
			 | 
			
			
				-            parentElem = (View) parentElem.getParent(); 
			 | 
		
	
		
			
			| 
				
			 | 
			
				423
			 | 
			
			
				+            // apply each view transformations, so each child will be affected by them 
			 | 
		
	
		
			
			| 
				
			 | 
			
				424
			 | 
			
			
				+            final float dx = v.getLeft() + ((v != child) ? v.getPaddingLeft() : 0) + v.getTranslationX(); 
			 | 
		
	
		
			
			| 
				
			 | 
			
				425
			 | 
			
			
				+            final float dy = v.getTop() + ((v != child) ? v.getPaddingTop() : 0) + v.getTranslationY(); 
			 | 
		
	
		
			
			| 
				
			 | 
			
				426
			 | 
			
			
				+            c.translate(dx, dy); 
			 | 
		
	
		
			
			| 
				
			 | 
			
				427
			 | 
			
			
				+            c.rotate(v.getRotation(), v.getPivotX(), v.getPivotY()); 
			 | 
		
	
		
			
			| 
				
			 | 
			
				428
			 | 
			
			
				+            c.scale(v.getScaleX(), v.getScaleY()); 
			 | 
		
	
		
			
			| 
				
			 | 
			
				429
			 | 
			
			
				+ 
			 | 
		
	
		
			
			| 
				
			 | 
			
				430
			 | 
			
			
				+            // compute the matrix just for any future use 
			 | 
		
	
		
			
			| 
				
			 | 
			
				431
			 | 
			
			
				+            transform.postTranslate(dx, dy); 
			 | 
		
	
		
			
			| 
				
			 | 
			
				432
			 | 
			
			
				+            transform.postRotate(v.getRotation(), v.getPivotX(), v.getPivotY()); 
			 | 
		
	
		
			
			| 
				
			 | 
			
				433
			 | 
			
			
				+            transform.postScale(v.getScaleX(), v.getScaleY()); 
			 | 
		
	
		
			
			| 
				412
			 | 
			
				434
			 | 
			
			
				         } 
			 | 
		
	
		
			
			| 
				413
			 | 
			
				435
			 | 
			
			
				  
			 | 
		
	
		
			
			| 
				414
			 | 
			
				
			 | 
			
			
				-        return new Point(left, top); 
			 | 
		
	
		
			
			| 
				
			 | 
			
				436
			 | 
			
			
				+        return transform; 
			 | 
		
	
		
			
			| 
				415
			 | 
			
				437
			 | 
			
			
				     } 
			 | 
		
	
		
			
			| 
				416
			 | 
			
				438
			 | 
			
			
				  
			 | 
		
	
		
			
			| 
				417
			 | 
			
				439
			 | 
			
			
				     @SuppressWarnings("unchecked") 
			 | 
		
	
	
		
			
			| 
				
			 | 
			
			
				@@ -450,13 +472,32 @@ public class ViewShot implements UIBlock { 
			 | 
		
	
		
			
			| 
				450
			 | 
			
				472
			 | 
			
			
				     } 
			 | 
		
	
		
			
			| 
				451
			 | 
			
				473
			 | 
			
			
				  
			 | 
		
	
		
			
			| 
				452
			 | 
			
				474
			 | 
			
			
				     /** 
			 | 
		
	
		
			
			| 
				453
			 | 
			
				
			 | 
			
			
				-     * Try to find a bitmap for screenshot in reusabel set and if not found create a new one. 
			 | 
		
	
		
			
			| 
				
			 | 
			
				475
			 | 
			
			
				+     * Try to find a bitmap for screenshot in reusable set and if not found create a new one. 
			 | 
		
	
		
			
			| 
				454
			 | 
			
				476
			 | 
			
			
				      */ 
			 | 
		
	
		
			
			| 
				455
			 | 
			
				477
			 | 
			
			
				     @NonNull 
			 | 
		
	
		
			
			| 
				456
			 | 
			
				478
			 | 
			
			
				     private static Bitmap getBitmapForScreenshot(final int width, final int height) { 
			 | 
		
	
		
			
			| 
				457
			 | 
			
				479
			 | 
			
			
				         synchronized (guardBitmaps) { 
			 | 
		
	
		
			
			| 
				458
			 | 
			
				480
			 | 
			
			
				             for (final Bitmap bmp : weakBitmaps) { 
			 | 
		
	
		
			
			| 
				459
			 | 
			
				
			 | 
			
			
				-                if (bmp.getWidth() * bmp.getHeight() <= width * height) { 
			 | 
		
	
		
			
			| 
				
			 | 
			
				481
			 | 
			
			
				+                if (bmp.getWidth() >= width && bmp.getHeight() >= height) { 
			 | 
		
	
		
			
			| 
				
			 | 
			
				482
			 | 
			
			
				+                    weakBitmaps.remove(bmp); 
			 | 
		
	
		
			
			| 
				
			 | 
			
				483
			 | 
			
			
				+                    bmp.eraseColor(Color.TRANSPARENT); 
			 | 
		
	
		
			
			| 
				
			 | 
			
				484
			 | 
			
			
				+                    return bmp; 
			 | 
		
	
		
			
			| 
				
			 | 
			
				485
			 | 
			
			
				+                } 
			 | 
		
	
		
			
			| 
				
			 | 
			
				486
			 | 
			
			
				+            } 
			 | 
		
	
		
			
			| 
				
			 | 
			
				487
			 | 
			
			
				+        } 
			 | 
		
	
		
			
			| 
				
			 | 
			
				488
			 | 
			
			
				+ 
			 | 
		
	
		
			
			| 
				
			 | 
			
				489
			 | 
			
			
				+        return Bitmap.createBitmap(width, height, Bitmap.Config.ARGB_8888); 
			 | 
		
	
		
			
			| 
				
			 | 
			
				490
			 | 
			
			
				+    } 
			 | 
		
	
		
			
			| 
				
			 | 
			
				491
			 | 
			
			
				+ 
			 | 
		
	
		
			
			| 
				
			 | 
			
				492
			 | 
			
			
				+    /** 
			 | 
		
	
		
			
			| 
				
			 | 
			
				493
			 | 
			
			
				+     * Try to find a bitmap with exact width and height for screenshot in reusable set and if 
			 | 
		
	
		
			
			| 
				
			 | 
			
				494
			 | 
			
			
				+     * not found create a new one. 
			 | 
		
	
		
			
			| 
				
			 | 
			
				495
			 | 
			
			
				+     */ 
			 | 
		
	
		
			
			| 
				
			 | 
			
				496
			 | 
			
			
				+    @NonNull 
			 | 
		
	
		
			
			| 
				
			 | 
			
				497
			 | 
			
			
				+    private static Bitmap getExactBitmapForScreenshot(final int width, final int height) { 
			 | 
		
	
		
			
			| 
				
			 | 
			
				498
			 | 
			
			
				+        synchronized (guardBitmaps) { 
			 | 
		
	
		
			
			| 
				
			 | 
			
				499
			 | 
			
			
				+            for (final Bitmap bmp : weakBitmaps) { 
			 | 
		
	
		
			
			| 
				
			 | 
			
				500
			 | 
			
			
				+                if (bmp.getWidth() == width && bmp.getHeight() == height) { 
			 | 
		
	
		
			
			| 
				460
			 | 
			
				501
			 | 
			
			
				                     weakBitmaps.remove(bmp); 
			 | 
		
	
		
			
			| 
				461
			 | 
			
				502
			 | 
			
			
				                     bmp.eraseColor(Color.TRANSPARENT); 
			 | 
		
	
		
			
			| 
				462
			 | 
			
				503
			 | 
			
			
				                     return bmp; 
			 |