Move SSD review viewport transforms to typed Kotlin

ober

e99632cda006f5752c3efc85a3c407bad7f8f372

diff --git a/templates/ssd-review.ss b/templates/ssd-review.ss
index 7287bc6..76b63a3 100644
--- a/templates/ssd-review.ss
+++ b/templates/ssd-review.ss
@@ -4647,6 +4647,8 @@
                 reviewViewSetSsdAreaFromNullableSession reviewViewShowSession
                 reviewViewClearSessionState reviewViewShowBitmap
                 reviewViewSetViewportState reviewViewSetViewportOffsets
+                reviewViewSetScale reviewViewSetRotationDegrees
+                reviewViewTranslateViewportOffsets
                 mainActivitySelectGroupId mainActivityClearSession
                 mainActivityShowSession mainActivitySetAppendMode
                 mainActivitySetSsdAreaMode mainActivityClearInteractionModes
@@ -4784,6 +4786,9 @@
         (extern (reviewViewOffsetYSet (view : SsdReviewView)
                                       (offset : Float32)) : Unit
           (kotlin-member-set offsetY))
+        (extern (reviewViewRotationDegreesSet (view : SsdReviewView)
+                                             (degrees : Int32)) : Unit
+          (kotlin-member-set rotationDegrees))
         (extern (mainActivityCurrentSessionSet
                   (activity : MainActivity)
                   (session : (Nullable SsdSession))) : Unit
@@ -5364,6 +5369,22 @@
           (begin
             (reviewViewOffsetXSet view offsetX)
             (reviewViewOffsetYSet view offsetY)))
+        (def (reviewViewSetScale (view : SsdReviewView)
+                                 (scale : Float32)) : Unit
+          (reviewViewScaleSet view scale))
+        (def (reviewViewSetRotationDegrees (view : SsdReviewView)
+                                           (degrees : Int32)) : Unit
+          (reviewViewRotationDegreesSet view degrees))
+        (def (reviewViewTranslateViewportOffsets
+               (view : SsdReviewView)
+               (offsetX : Float32)
+               (offsetY : Float32)
+               (deltaX : Float32)
+               (deltaY : Float32)) : Unit
+          (reviewViewSetViewportOffsets
+            view
+            (+ offsetX deltaX)
+            (+ offsetY deltaY)))
         (def (mainActivitySelectGroupId (activity : MainActivity)
                                         (view : SsdReviewView)
                                         (id : (Nullable String))) : Unit
@@ -8769,7 +8790,7 @@
 	       "    internal var scale = 1f"
        "    internal var offsetX = 0f"
        "    internal var offsetY = 0f"
-       "    private var rotationDegrees = 0"
+       "    internal var rotationDegrees = 0"
        "    private var lastX = 0f"
        "    private var lastY = 0f"
 	       "    private var dragStart: FloatArray? = null"
@@ -8841,8 +8862,7 @@
 	       "                    pointerActive = true"
 	       "                    dragEnd = selectionPoint(event)"
 		       "                } else if (touchPanReady(selectMode, scaler.isInProgress)) {"
-	       "                    offsetX += dx"
-	       "                    offsetY += dy"
+	       "                    reviewViewTranslateViewportOffsets(this, offsetX, offsetY, dx, dy)"
 	       "                    clampOffsets()"
 	       "                    updateMatrix()"
 	       "                }"
@@ -8884,7 +8904,7 @@
 	       "    }"
        ""
        "    fun rotateClockwise() {"
-       "        rotationDegrees = nextRotationDegrees(rotationDegrees)"
+       "        reviewViewSetRotationDegrees(this, nextRotationDegrees(rotationDegrees))"
        "        fitImage()"
        "    }"
        ""
@@ -8904,12 +8924,11 @@
 	       ""
 	       "    fun centerOnGroup(group: SsdGroup) {"
        "        if (bitmapViewNotReadyForBitmap(bitmap, width, height)) return"
-	       "        scale = focusGroupScale(scale, width.toFloat(), height.toFloat(), group)"
+	       "        reviewViewSetScale(this, focusGroupScale(scale, width.toFloat(), height.toFloat(), group))"
 	       "        updateMatrix()"
 	       "        val groupCenter = groupCenterPoint(group)"
 	       "        val center = imageToView(groupCenter[0], groupCenter[1])"
-	       "        offsetX += viewportCenterOffsetDelta(width, center[0])"
-	       "        offsetY += viewportCenterOffsetDelta(height, center[1])"
+	       "        reviewViewTranslateViewportOffsets(this, offsetX, offsetY, viewportCenterOffsetDelta(width, center[0]), viewportCenterOffsetDelta(height, center[1]))"
 	       "        clampOffsets()"
 	       "        updateMatrix()"
 	       "        invalidate()"
@@ -9092,11 +9111,10 @@
 	       ""
 	       "    private fun zoomAt(viewX: Float, viewY: Float, factor: Float) {"
 	       "        val before = viewToImage(viewX, viewY)"
-	       "        scale = clampScale(scale * factor)"
+	       "        reviewViewSetScale(this, clampScale(scale * factor))"
 	       "        updateMatrix()"
 	       "        val after = imageToView(before[0], before[1])"
-	       "        offsetX += viewX - after[0]"
-	       "        offsetY += viewY - after[1]"
+	       "        reviewViewTranslateViewportOffsets(this, offsetX, offsetY, viewX - after[0], viewY - after[1])"
 	       "        clampOffsets()"
 	       "        updateMatrix()"
 	       "        invalidate()"