From 6982b42046ec4eb589419cc3fe3cfea705e5dc5c Mon Sep 17 00:00:00 2001
From: stepan <stepan.sindelar@oracle.com>
Date: Fri, 24 Mar 2017 15:48:51 +0100
Subject: [PATCH] FastR Grid: support view port rotation (rectangles and text)

---
 .../truffle/r/library/fastrGrid/GridTextNode.java  |  6 +++---
 .../truffle/r/library/fastrGrid/LPoints.java       |  2 +-
 .../oracle/truffle/r/library/fastrGrid/LRect.java  |  2 +-
 .../r/library/fastrGrid/ViewPortTransform.java     |  5 ++++-
 .../fastrGrid/device/BufferedJFrameDevice.java     |  6 +++---
 .../r/library/fastrGrid/device/GridDevice.java     |  6 +++++-
 .../r/library/fastrGrid/device/JFrameDevice.java   | 14 ++++++++++++--
 7 files changed, 29 insertions(+), 12 deletions(-)

diff --git a/com.oracle.truffle.r.library/src/com/oracle/truffle/r/library/fastrGrid/GridTextNode.java b/com.oracle.truffle.r.library/src/com/oracle/truffle/r/library/fastrGrid/GridTextNode.java
index 594bca1676..a088244c1b 100644
--- a/com.oracle.truffle.r.library/src/com/oracle/truffle/r/library/fastrGrid/GridTextNode.java
+++ b/com.oracle.truffle.r.library/src/com/oracle/truffle/r/library/fastrGrid/GridTextNode.java
@@ -145,7 +145,7 @@ public final class GridTextNode extends RBaseNode {
 
             // actual drawing
             if (draw && doDraw) {
-                text(loc.x, loc.y, text, hjust, vjust, rotation, gpar.getDrawingContext(i), dev);
+                text(loc.x, loc.y, text, hjust, vjust, rotation + vpTransform.rotationAngle, gpar.getDrawingContext(i), dev);
             }
 
             // or bounds checking
@@ -210,13 +210,13 @@ public final class GridTextNode extends RBaseNode {
 
     // transcribed from engine.c
 
-    private void text(double x, double y, String text, double xadjIn, double yadj, double rotation, DrawingContext drawingCtx, GridDevice device) {
+    private void text(double x, double y, String text, double xadjIn, double yadj, double rotationDegrees, DrawingContext drawingCtx, GridDevice device) {
         if (!Double.isFinite(yadj)) {
             throw RInternalError.unimplemented("'exact' vertical centering, see engine.c:1700");
         }
         double xadj = Double.isFinite(xadjIn) ? xadjIn : 0.5;
 
-        double radRotation = Math.toRadians(rotation);
+        double radRotation = Math.toRadians(rotationDegrees);
         double cosRot = Math.cos(radRotation);
         double sinRot = Math.sin(radRotation);
         String[] lines = text.split("\n");
diff --git a/com.oracle.truffle.r.library/src/com/oracle/truffle/r/library/fastrGrid/LPoints.java b/com.oracle.truffle.r.library/src/com/oracle/truffle/r/library/fastrGrid/LPoints.java
index 477e1e4993..4931572555 100644
--- a/com.oracle.truffle.r.library/src/com/oracle/truffle/r/library/fastrGrid/LPoints.java
+++ b/com.oracle.truffle.r.library/src/com/oracle/truffle/r/library/fastrGrid/LPoints.java
@@ -130,7 +130,7 @@ public abstract class LPoints extends RExternalBuiltinNode.Arg4 {
         if (cex > 0 && yc < 0.5) {
             yc = 0.5;
         }
-        dev.drawRect(drawingCtx, x - xc, y - yc, x + xc, y + yc);
+        dev.drawRect(drawingCtx, x - xc, y - yc, x + xc, y + yc, 0);
         return drawingCtx;
     }
 
diff --git a/com.oracle.truffle.r.library/src/com/oracle/truffle/r/library/fastrGrid/LRect.java b/com.oracle.truffle.r.library/src/com/oracle/truffle/r/library/fastrGrid/LRect.java
index 7c69b09329..8fc3969d15 100644
--- a/com.oracle.truffle.r.library/src/com/oracle/truffle/r/library/fastrGrid/LRect.java
+++ b/com.oracle.truffle.r.library/src/com/oracle/truffle/r/library/fastrGrid/LRect.java
@@ -65,7 +65,7 @@ public abstract class LRect extends RExternalBuiltinNode.Arg6 {
             Point origLoc = Point.fromUnits(unitToInches, xVec, yVec, i, conversionCtx);
             Point transLoc = TransformMatrix.transLocation(origLoc, vpTransform.transform);
             Point loc = transLoc.justify(size, getDataAtMod(hjust, i), getDataAtMod(vjust, i));
-            dev.drawRect(gpar.getDrawingContext(i), loc.x, loc.y, size.getWidth(), size.getHeight());
+            dev.drawRect(gpar.getDrawingContext(i), loc.x, loc.y, size.getWidth(), size.getHeight(), Math.toRadians(vpTransform.rotationAngle));
         }
         return RNull.instance;
     }
diff --git a/com.oracle.truffle.r.library/src/com/oracle/truffle/r/library/fastrGrid/ViewPortTransform.java b/com.oracle.truffle.r.library/src/com/oracle/truffle/r/library/fastrGrid/ViewPortTransform.java
index 0e8ea8aa08..bed955d7f2 100644
--- a/com.oracle.truffle.r.library/src/com/oracle/truffle/r/library/fastrGrid/ViewPortTransform.java
+++ b/com.oracle.truffle.r.library/src/com/oracle/truffle/r/library/fastrGrid/ViewPortTransform.java
@@ -25,7 +25,10 @@ import com.oracle.truffle.r.runtime.data.model.RAbstractDoubleVector;
  * Holds the data of a viewport needed to perform transformations.
  */
 public final class ViewPortTransform {
-    private final double rotationAngle;
+    /**
+     * Angle in radians.
+     */
+    public final double rotationAngle;
     public final double[][] transform;
     public final Size size;
 
diff --git a/com.oracle.truffle.r.library/src/com/oracle/truffle/r/library/fastrGrid/device/BufferedJFrameDevice.java b/com.oracle.truffle.r.library/src/com/oracle/truffle/r/library/fastrGrid/device/BufferedJFrameDevice.java
index fa8e3a5b6f..131165f954 100644
--- a/com.oracle.truffle.r.library/src/com/oracle/truffle/r/library/fastrGrid/device/BufferedJFrameDevice.java
+++ b/com.oracle.truffle.r.library/src/com/oracle/truffle/r/library/fastrGrid/device/BufferedJFrameDevice.java
@@ -86,10 +86,10 @@ public final class BufferedJFrameDevice implements GridDevice {
     }
 
     @Override
-    public void drawRect(DrawingContext ctx, double leftX, double topY, double width, double height) {
-        inner.drawRect(ctx, leftX, topY, width, height);
+    public void drawRect(DrawingContext ctx, double leftX, double topY, double width, double height, double rotationAnticlockWise) {
+        inner.drawRect(ctx, leftX, topY, width, height, rotationAnticlockWise);
         if (buffer != null) {
-            drawActions.add(() -> inner.drawRect(ctx, leftX, topY, width, height));
+            drawActions.add(() -> inner.drawRect(ctx, leftX, topY, width, height, rotationAnticlockWise));
         }
     }
 
diff --git a/com.oracle.truffle.r.library/src/com/oracle/truffle/r/library/fastrGrid/device/GridDevice.java b/com.oracle.truffle.r.library/src/com/oracle/truffle/r/library/fastrGrid/device/GridDevice.java
index 03df48b53f..afe759f3f0 100644
--- a/com.oracle.truffle.r.library/src/com/oracle/truffle/r/library/fastrGrid/device/GridDevice.java
+++ b/com.oracle.truffle.r.library/src/com/oracle/truffle/r/library/fastrGrid/device/GridDevice.java
@@ -46,7 +46,11 @@ public interface GridDevice {
     default void flush() {
     }
 
-    void drawRect(DrawingContext ctx, double leftX, double topY, double width, double height);
+    /**
+     * Draws a rectangle at given position, the center of the rotation should be the center of the
+     * rectangle. The rotation is given in radians.
+     */
+    void drawRect(DrawingContext ctx, double leftX, double topY, double width, double height, double rotationAnticlockWise);
 
     /**
      * Connects given points with a line, there has to be at least two points in order to actually
diff --git a/com.oracle.truffle.r.library/src/com/oracle/truffle/r/library/fastrGrid/device/JFrameDevice.java b/com.oracle.truffle.r.library/src/com/oracle/truffle/r/library/fastrGrid/device/JFrameDevice.java
index c92cb0558d..6ee2268766 100644
--- a/com.oracle.truffle.r.library/src/com/oracle/truffle/r/library/fastrGrid/device/JFrameDevice.java
+++ b/com.oracle.truffle.r.library/src/com/oracle/truffle/r/library/fastrGrid/device/JFrameDevice.java
@@ -83,9 +83,19 @@ public final class JFrameDevice implements GridDevice {
     }
 
     @Override
-    public void drawRect(DrawingContext ctx, double leftX, double topY, double width, double height) {
+    public void drawRect(DrawingContext ctx, double leftX, double topY, double width, double height, double rotationAnticlockWise) {
         setContext(ctx);
-        drawShape(ctx, new Rectangle2D.Double(leftX, topY, width, height));
+        if (rotationAnticlockWise == 0.) {
+            drawShape(ctx, new Rectangle2D.Double(leftX, topY, width, height));
+            return;
+        }
+        AffineTransform oldTr = graphics.getTransform();
+        AffineTransform newTr = new AffineTransform(oldTr);
+        newTr.translate(leftX + width / 2, topY + height / 2);
+        newTr.rotate(rotationAnticlockWise);
+        graphics.setTransform(newTr);
+        drawShape(ctx, new Rectangle2D.Double(-(width / 2), -(height / 2), width, height));
+        graphics.setTransform(oldTr);
     }
 
     @Override
-- 
GitLab