diff --git a/com.oracle.truffle.r.library/src/com/oracle/truffle/r/library/fastrGrid/Unit.java b/com.oracle.truffle.r.library/src/com/oracle/truffle/r/library/fastrGrid/Unit.java
index 8d8dd780d0216317b241dfcf78d16776b8d58fcb..f881cc708180ce2e8da82a15ad5704eb000c8788 100644
--- a/com.oracle.truffle.r.library/src/com/oracle/truffle/r/library/fastrGrid/Unit.java
+++ b/com.oracle.truffle.r.library/src/com/oracle/truffle/r/library/fastrGrid/Unit.java
@@ -185,6 +185,9 @@ public final class Unit {
 
     private static double convertToInches(double value, int index, int unitId, RList data, UnitConversionContext ctx, AxisOrDimension axisOrDim) {
         double vpSize = ctx.getViewPortSize(axisOrDim);
+        String str;
+        String[] lines;
+        double result = 0;
         switch (unitId) {
             case INCHES:
                 return value;
@@ -207,10 +210,20 @@ public final class Unit {
                 return (value * ctx.gpar.getDrawingContext(index).getFontSize() * ctx.gpar.getDrawingContext(index).getLineHeight()) / INCH_TO_POINTS_FACTOR;
             case STRINGWIDTH:
             case MYSTRINGWIDTH:
-                return ctx.device.getStringWidth(ctx.gpar.getDrawingContext(index), RRuntime.asString(data.getDataAt(0)));
+                str = RRuntime.asString(data.getDataAt(0));
+                lines = str.split("\n");
+                for (int i = 0; i < lines.length; i++) {
+                    result = Math.max(result, ctx.device.getStringWidth(ctx.gpar.getDrawingContext(index), lines[i]));
+                }
+                return result;
             case STRINGHEIGHT:
             case MYSTRINGHEIGHT:
-                return ctx.device.getStringHeight(ctx.gpar.getDrawingContext(index), RRuntime.asString(data.getDataAt(0)));
+                str = RRuntime.asString(data.getDataAt(0));
+                lines = str.split("\n");
+                for (int i = 0; i < lines.length; i++) {
+                    result += ctx.device.getStringHeight(ctx.gpar.getDrawingContext(index), lines[i]);
+                }
+                return result;
             case NULL:
                 return evaluateNullUnit(value, vpSize, ctx.nullLayoutMode, ctx.nullArithmeticMode);
             default:
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 53f08304db39afd43a06adb56d6e8d48cfdf334e..90a2dcd6e941b70aa7f45f1dd1cefecc4c6eb6a3 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
@@ -106,13 +106,11 @@ public interface GridDevice {
     double getStringWidth(DrawingContext ctx, String text);
 
     /**
-     * Gets the height of a line of text in inches, the default implementation uses only the
-     * parameters from the drawing context, but we allow the device to override this calculation
-     * with something more precise.
+     * Gets the height of a line of text in inches. This should include ascent and descent, i.e.
+     * from the very bottom to the very top of the tallest letter(s). The text is guaranteed to not
+     * contain any new lines.
      */
-    default double getStringHeight(DrawingContext ctx, String text) {
-        return (ctx.getLineHeight() * ctx.getFontSize()) / INCH_TO_POINTS_FACTOR;
-    }
+    double getStringHeight(DrawingContext ctx, String text);
 
     final class DeviceCloseException extends Exception {
         private static final long serialVersionUID = 1182697755931636214L;
diff --git a/com.oracle.truffle.r.library/src/com/oracle/truffle/r/library/fastrGrid/device/awt/Graphics2DDevice.java b/com.oracle.truffle.r.library/src/com/oracle/truffle/r/library/fastrGrid/device/awt/Graphics2DDevice.java
index 74540e4d11274fe25b9694fc59475a1b034b271b..055084a451c858ad163dd07e432c2121f14c67b4 100644
--- a/com.oracle.truffle.r.library/src/com/oracle/truffle/r/library/fastrGrid/device/awt/Graphics2DDevice.java
+++ b/com.oracle.truffle.r.library/src/com/oracle/truffle/r/library/fastrGrid/device/awt/Graphics2DDevice.java
@@ -28,6 +28,7 @@ import static java.awt.geom.Path2D.WIND_EVEN_ODD;
 import java.awt.BasicStroke;
 import java.awt.Color;
 import java.awt.Font;
+import java.awt.FontMetrics;
 import java.awt.Graphics2D;
 import java.awt.Paint;
 import java.awt.Shape;
@@ -128,7 +129,8 @@ public class Graphics2DDevice implements GridDevice {
     public void drawString(DrawingContext ctx, double leftXIn, double bottomYIn, double rotationAnticlockWise, String text) {
         setContextAndFont(ctx);
         int leftX = transX(leftXIn);
-        int bottomY = transY(bottomYIn);
+        FontMetrics fontMetrics = graphics.getFontMetrics(graphics.getFont());
+        int bottomY = transY(bottomYIn) - fontMetrics.getDescent();
         transformed(leftX, bottomY, rotationAnticlockWise, () -> graphics.drawString(text, 0, 0));
     }
 
@@ -152,7 +154,8 @@ public class Graphics2DDevice implements GridDevice {
     @Override
     public double getStringHeight(DrawingContext ctx, String text) {
         setContextAndFont(ctx);
-        int swingUnits = graphics.getFont().getSize();
+        FontMetrics fontMetrics = graphics.getFontMetrics(graphics.getFont());
+        double swingUnits = fontMetrics.getAscent() + fontMetrics.getDescent();
         return swingUnits / AWT_POINTS_IN_INCH;
     }