Move SSD bitmap dimension checks to typed Kotlin

ober

2ce82aa07ca9a8a2d5257704a0b90fbb5fc9b268

diff --git a/templates/ssd-review.ss b/templates/ssd-review.ss
index 490aba1..67807d6 100644
--- a/templates/ssd-review.ss
+++ b/templates/ssd-review.ss
@@ -1241,6 +1241,7 @@
                 viewDimensionsReady previousViewSizeMissing
                 viewDimensionsMissing viewSizeChangeNeedsFit
                 bitmapLoaded viewSizeChangeNeedsFitForBitmap
+                nullableBitmapWidthOrZero nullableBitmapHeightOrZero
                 bitmapViewReady bitmapViewNotReady bitmapViewNotReadyForBitmap
                 viewportMatchesImage viewportImageMismatch
                 motionActionIsDown motionActionIsMove
@@ -1249,6 +1250,10 @@
         (type Float32)
         (type FloatArray)
         (type Bitmap)
+        (extern (reviewBitmapWidth (bitmap : Bitmap)) : Int32
+          (kotlin-member-get width))
+        (extern (reviewBitmapHeight (bitmap : Bitmap)) : Int32
+          (kotlin-member-get height))
         (def (selectionCellMatches? (rect : FloatArray) (cell : SsdCell)) : Bool
           (let ((overlap (rectOverlapArea rect (ssdCellRect cell)))
                 (area (* (SsdCell-w cell) (SsdCell-h cell))))
@@ -1320,6 +1325,14 @@
           (or (previousViewSizeMissing oldWidth oldHeight) (not hasBitmap)))
         (def (bitmapLoaded (bitmap : (Nullable Bitmap))) : Bool
           (not (nullable-null? bitmap)))
+        (def (nullableBitmapWidthOrZero (bitmap : (Nullable Bitmap))) : Int32
+          (if (nullable-null? bitmap)
+            (int32 0)
+            (reviewBitmapWidth (nullable-get bitmap))))
+        (def (nullableBitmapHeightOrZero (bitmap : (Nullable Bitmap))) : Int32
+          (if (nullable-null? bitmap)
+            (int32 0)
+            (reviewBitmapHeight (nullable-get bitmap))))
         (def (viewSizeChangeNeedsFitForBitmap (oldWidth : Int32)
                                               (oldHeight : Int32)
                                               (bitmap : (Nullable Bitmap))) : Bool
@@ -8312,19 +8325,21 @@
 	       "        canvas.drawCircle(viewAnchor[0], viewAnchor[1], touchPointerInnerRadius(), paint)"
 	       "    }"
 	       ""
-	       "    private fun updateMatrix() {"
+       "    private fun updateMatrix() {"
        "        val img = bitmap"
        "        matrix.reset()"
-       "        if (img != null) {"
+       "        if (bitmapLoaded(img)) {"
+       "            val imageWidth = nullableBitmapWidthOrZero(img)"
+       "            val imageHeight = nullableBitmapHeightOrZero(img)"
        "            if (rotationIs90(rotationDegrees)) {"
        "                matrix.postRotate(90f)"
-       "                matrix.postTranslate(img.height.toFloat(), 0f)"
+       "                matrix.postTranslate(imageHeight.toFloat(), 0f)"
        "            } else if (rotationIs180(rotationDegrees)) {"
        "                matrix.postRotate(180f)"
-       "                matrix.postTranslate(img.width.toFloat(), img.height.toFloat())"
+       "                matrix.postTranslate(imageWidth.toFloat(), imageHeight.toFloat())"
        "            } else if (rotationIs270(rotationDegrees)) {"
        "                matrix.postRotate(270f)"
-       "                matrix.postTranslate(0f, img.width.toFloat())"
+       "                matrix.postTranslate(0f, imageWidth.toFloat())"
        "            }"
        "        }"
        "        matrix.postScale(scale, scale)"
@@ -8359,9 +8374,9 @@
        "        val point = floatArrayOf(x, y)"
        "        inverse.mapPoints(point)"
        "        val img = bitmap"
-       "        if (img != null) {"
-       "            point[0] = clampImageCoordinate(point[0], img.width.toFloat())"
-       "            point[1] = clampImageCoordinate(point[1], img.height.toFloat())"
+       "        if (bitmapLoaded(img)) {"
+       "            point[0] = clampImageCoordinate(point[0], nullableBitmapWidthOrZero(img).toFloat())"
+       "            point[1] = clampImageCoordinate(point[1], nullableBitmapHeightOrZero(img).toFloat())"
        "        }"
 	       "        return point"
 	       "    }"