Move SSD viewport restore guards to typed Kotlin

ober

51ef0ba0d1ec800bcd0323fa864abc29dfa835a3

diff --git a/templates/ssd-review.ss b/templates/ssd-review.ss
index 3fd7b89..b1d14b2 100644
--- a/templates/ssd-review.ss
+++ b/templates/ssd-review.ss
@@ -1259,7 +1259,7 @@
                 nullableFloatArrayPresent nullableFloatArrayOrEmpty
                 nullableFirstFloatArrayPresent nullableFirstFloatArrayOrEmpty
                 nullableBitmapWidthOrZero nullableBitmapHeightOrZero
-                captureViewportState
+                captureViewportState restorableViewportState
                 bitmapViewReady bitmapViewNotReady bitmapViewNotReadyForBitmap
                 viewportMatchesImage viewportImageMismatch
                 motionActionIsDown motionActionIsMove
@@ -1384,6 +1384,20 @@
                   (reviewBitmapWidth img)
                   (reviewBitmapHeight img))))
             (nullable-none ViewportState)))
+        (def (restorableViewportState (bitmap : (Nullable Bitmap))
+                                      (viewport : (Nullable ViewportState))
+                                      (rotationDegrees : Int32)) : (Nullable ViewportState)
+          (if (or (nullable-null? bitmap) (nullable-null? viewport))
+            (nullable-none ViewportState)
+            (let ((img (nullable-get bitmap))
+                  (saved (nullable-get viewport)))
+              (if (viewportImageMismatch
+                    saved
+                    (reviewBitmapWidth img)
+                    (reviewBitmapHeight img)
+                    rotationDegrees)
+                (nullable-none ViewportState)
+                (nullable-some saved)))))
         (def (viewSizeChangeNeedsFitForBitmap (oldWidth : Int32)
                                               (oldHeight : Int32)
                                               (bitmap : (Nullable Bitmap))) : Bool
@@ -8471,11 +8485,9 @@
        "    }"
        ""
        "    fun restoreViewport(viewport: ViewportState?) {"
-       "        if (!bitmapLoaded(bitmap)) return"
-       "        val img = checkNotNull(bitmap)"
-       "        if (!viewportStatePresent(viewport)) return"
-       "        val savedViewport = viewportStateOrEmpty(viewport)"
-       "        if (viewportImageMismatch(savedViewport, img.width, img.height, rotationDegrees)) return"
+       "        val restoredViewport = restorableViewportState(bitmap, viewport, rotationDegrees)"
+       "        if (!viewportStatePresent(restoredViewport)) return"
+       "        val savedViewport = viewportStateOrEmpty(restoredViewport)"
 	       "        scale = savedViewport.scale"
 	       "        offsetX = savedViewport.offsetX"
 	       "        offsetY = savedViewport.offsetY"