diff --git a/com.oracle.truffle.r.library/src/com/oracle/truffle/r/library/fastrGrid/DisplayList.java b/com.oracle.truffle.r.library/src/com/oracle/truffle/r/library/fastrGrid/DisplayList.java index 14cd2fda773ebceec382ffdd337cd510e2503e86..8c1b859999ec66ad62ac8a8eedcf4349488189df 100644 --- a/com.oracle.truffle.r.library/src/com/oracle/truffle/r/library/fastrGrid/DisplayList.java +++ b/com.oracle.truffle.r.library/src/com/oracle/truffle/r/library/fastrGrid/DisplayList.java @@ -47,7 +47,7 @@ public class DisplayList { return list; } - static void initDisplayList(GridState gridState) { + public static void initDisplayList(GridState gridState) { RList list = createInitialDisplayList(); list.setDataAt(0, gridState.getViewPort()); gridState.setDisplayList(list); diff --git a/com.oracle.truffle.r.library/src/com/oracle/truffle/r/library/fastrGrid/FastRGridExternalLookup.java b/com.oracle.truffle.r.library/src/com/oracle/truffle/r/library/fastrGrid/FastRGridExternalLookup.java index beb97cd30e1db39d6818bdc9726038447d2d9bd8..55292b2447aa975e55d9c867eddb485239594d69 100644 --- a/com.oracle.truffle.r.library/src/com/oracle/truffle/r/library/fastrGrid/FastRGridExternalLookup.java +++ b/com.oracle.truffle.r.library/src/com/oracle/truffle/r/library/fastrGrid/FastRGridExternalLookup.java @@ -31,6 +31,7 @@ import com.oracle.truffle.r.library.fastrGrid.grDevices.DevCairo; import com.oracle.truffle.r.library.fastrGrid.grDevices.DevCurr; import com.oracle.truffle.r.library.fastrGrid.grDevices.DevHoldFlush; import com.oracle.truffle.r.library.fastrGrid.grDevices.DevOff; +import com.oracle.truffle.r.library.fastrGrid.grDevices.DevSize; import com.oracle.truffle.r.library.fastrGrid.grDevices.InitWindowedDevice; import com.oracle.truffle.r.library.fastrGrid.grDevices.SavePlot; import com.oracle.truffle.r.library.fastrGrid.graphics.CPar; @@ -55,6 +56,8 @@ public final class FastRGridExternalLookup { switch (name) { case "devholdflush": return DevHoldFlush.create(); + case "devsize": + return new DevSize(); case "devcur": return new DevCurr(); case "devoff": diff --git a/com.oracle.truffle.r.library/src/com/oracle/truffle/r/library/fastrGrid/GridState.java b/com.oracle.truffle.r.library/src/com/oracle/truffle/r/library/fastrGrid/GridState.java index 3150a167f08fb8c0c35a75239d94af3ad8744ece..c1cfe4461c2f329c6d60fda68c3fe648c2db9791 100644 --- a/com.oracle.truffle.r.library/src/com/oracle/truffle/r/library/fastrGrid/GridState.java +++ b/com.oracle.truffle.r.library/src/com/oracle/truffle/r/library/fastrGrid/GridState.java @@ -102,7 +102,7 @@ public final class GridState { this.currentGrob = RNull.instance; } - void initGPar(GridDevice currentDevice) { + public void initGPar(GridDevice currentDevice) { devState.gpar = GPar.createNew(currentDevice); assert devState.gpar.verify(); } diff --git a/com.oracle.truffle.r.library/src/com/oracle/truffle/r/library/fastrGrid/LGridDirty.java b/com.oracle.truffle.r.library/src/com/oracle/truffle/r/library/fastrGrid/LGridDirty.java index 8d865b9172905d35b33224d962037ef465cd0134..23a07e326d676d8afff2433ef9d86eb973643528 100644 --- a/com.oracle.truffle.r.library/src/com/oracle/truffle/r/library/fastrGrid/LGridDirty.java +++ b/com.oracle.truffle.r.library/src/com/oracle/truffle/r/library/fastrGrid/LGridDirty.java @@ -15,6 +15,7 @@ import com.oracle.truffle.api.CompilerDirectives; import com.oracle.truffle.api.frame.VirtualFrame; import com.oracle.truffle.r.library.fastrGrid.ViewPort.InitViewPortNode; import com.oracle.truffle.r.library.fastrGrid.device.GridDevice; +import com.oracle.truffle.r.library.fastrGrid.grDevices.OpenDefaultDevice; import com.oracle.truffle.r.nodes.builtin.RExternalBuiltinNode; import com.oracle.truffle.r.runtime.data.RArgsValuesAndNames; import com.oracle.truffle.r.runtime.data.RNull; @@ -28,6 +29,7 @@ import com.oracle.truffle.r.runtime.data.RNull; */ final class LGridDirty extends RExternalBuiltinNode { @Child private InitViewPortNode initViewPort = new InitViewPortNode(); + @Child private OpenDefaultDevice openDefaultDevice = new OpenDefaultDevice(); static { Casts.noCasts(LGridDirty.class); @@ -41,16 +43,11 @@ final class LGridDirty extends RExternalBuiltinNode { } // the rest only takes place if the device has been changed since the last time - CompilerDirectives.transferToInterpreter(); - - // if no device has been opened yet, open the default one and make it current - if (GridContext.getContext().getCurrentDevice() == null) { - GridContext.getContext().openDefaultDevice(); - // grid state is device dependent - gridState = GridContext.getContext().getGridState(); - } + openDefaultDevice.execute(); + CompilerDirectives.transferToInterpreter(); // the current device has not been initialized yet... + gridState = GridContext.getContext().getGridState(); GridDevice device = GridContext.getContext().getCurrentDevice(); device.openNewPage(); gridState.initGPar(device); diff --git a/com.oracle.truffle.r.library/src/com/oracle/truffle/r/library/fastrGrid/ViewPort.java b/com.oracle.truffle.r.library/src/com/oracle/truffle/r/library/fastrGrid/ViewPort.java index 813782bb255540cbfc5dfae24fc3046158886027..0c5e860171d1f647728d31b27056e2f65a2bc11c 100644 --- a/com.oracle.truffle.r.library/src/com/oracle/truffle/r/library/fastrGrid/ViewPort.java +++ b/com.oracle.truffle.r.library/src/com/oracle/truffle/r/library/fastrGrid/ViewPort.java @@ -32,7 +32,7 @@ import com.oracle.truffle.r.runtime.data.model.RAbstractDoubleVector; * port. One such list is pushed using {@code pushViewpoint} it is transformed to a 'pushed * viewpoint', which is a copy of the original view point and it has some additional attributes. */ -final class ViewPort { +public final class ViewPort { /* * Structure of a viewport */ diff --git a/com.oracle.truffle.r.library/src/com/oracle/truffle/r/library/fastrGrid/grDevices/DevSize.java b/com.oracle.truffle.r.library/src/com/oracle/truffle/r/library/fastrGrid/grDevices/DevSize.java new file mode 100644 index 0000000000000000000000000000000000000000..0ae8b39372b58272c55df52cf232df8a1eb0eb37 --- /dev/null +++ b/com.oracle.truffle.r.library/src/com/oracle/truffle/r/library/fastrGrid/grDevices/DevSize.java @@ -0,0 +1,49 @@ +/* + * Copyright (c) 2017, Oracle and/or its affiliates. All rights reserved. + * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER. + * + * This code is free software; you can redistribute it and/or modify it + * under the terms of the GNU General Public License version 2 only, as + * published by the Free Software Foundation. + * + * This code is distributed in the hope that it will be useful, but WITHOUT + * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or + * FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License + * version 2 for more details (a copy is included in the LICENSE file that + * accompanied this code). + * + * You should have received a copy of the GNU General Public License version + * 2 along with this work; if not, write to the Free Software Foundation, + * Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA. + * + * Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA + * or visit www.oracle.com if you need additional information or have any + * questions. + */ +package com.oracle.truffle.r.library.fastrGrid.grDevices; + +import static com.oracle.truffle.r.library.fastrGrid.device.DrawingContext.INCH_TO_POINTS_FACTOR; + +import com.oracle.truffle.r.library.fastrGrid.GridContext; +import com.oracle.truffle.r.library.fastrGrid.device.GridDevice; +import com.oracle.truffle.r.nodes.builtin.RExternalBuiltinNode; +import com.oracle.truffle.r.runtime.data.RDataFactory; +import com.oracle.truffle.r.runtime.data.RDoubleVector; + +/** + * Unlike {@link com.oracle.truffle.r.library.fastrGrid.graphics.CPar} with argument {@code din}, + * which returns the size in inches, {@code dev.size} returns the size in pixels. + */ +public final class DevSize extends RExternalBuiltinNode.Arg0 { + static { + Casts.noCasts(DevSize.class); + } + + @Override + public RDoubleVector execute() { + GridDevice dev = GridContext.getContext().getCurrentDevice(); + double width = dev.getWidth() * INCH_TO_POINTS_FACTOR; + double height = dev.getHeight() * INCH_TO_POINTS_FACTOR; + return RDataFactory.createDoubleVector(new double[]{width, height}, RDataFactory.COMPLETE_VECTOR); + } +} diff --git a/com.oracle.truffle.r.library/src/com/oracle/truffle/r/library/fastrGrid/grDevices/OpenDefaultDevice.java b/com.oracle.truffle.r.library/src/com/oracle/truffle/r/library/fastrGrid/grDevices/OpenDefaultDevice.java new file mode 100644 index 0000000000000000000000000000000000000000..3307dd77efb932a6d360932c564a1757a1c31b0c --- /dev/null +++ b/com.oracle.truffle.r.library/src/com/oracle/truffle/r/library/fastrGrid/grDevices/OpenDefaultDevice.java @@ -0,0 +1,41 @@ +/* + * Copyright (c) 2017, Oracle and/or its affiliates. All rights reserved. + * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER. + * + * This code is free software; you can redistribute it and/or modify it + * under the terms of the GNU General Public License version 2 only, as + * published by the Free Software Foundation. + * + * This code is distributed in the hope that it will be useful, but WITHOUT + * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or + * FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License + * version 2 for more details (a copy is included in the LICENSE file that + * accompanied this code). + * + * You should have received a copy of the GNU General Public License version + * 2 along with this work; if not, write to the Free Software Foundation, + * Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA. + * + * Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA + * or visit www.oracle.com if you need additional information or have any + * questions. + */ +package com.oracle.truffle.r.library.fastrGrid.grDevices; + +import com.oracle.truffle.api.CompilerDirectives.TruffleBoundary; +import com.oracle.truffle.api.nodes.Node; +import com.oracle.truffle.r.library.fastrGrid.GridContext; + +/** + * Opens the default graphical device if no device is has been opened yet. Internal node not exposed + * directly through .Call/.External interface. + */ +public final class OpenDefaultDevice extends Node { + @TruffleBoundary + public void execute() { + // if no device has been opened yet, open the default one and make it current + if (GridContext.getContext().getCurrentDevice() == null) { + GridContext.getContext().openDefaultDevice(); + } + } +} diff --git a/com.oracle.truffle.r.library/src/com/oracle/truffle/r/library/fastrGrid/graphics/CPar.java b/com.oracle.truffle.r.library/src/com/oracle/truffle/r/library/fastrGrid/graphics/CPar.java index 2f19eafd4df206506301bb1ea24fca902eaaa1b1..9e8f8334770f9d701f3b92b2081505f88925c23b 100644 --- a/com.oracle.truffle.r.library/src/com/oracle/truffle/r/library/fastrGrid/graphics/CPar.java +++ b/com.oracle.truffle.r.library/src/com/oracle/truffle/r/library/fastrGrid/graphics/CPar.java @@ -22,9 +22,14 @@ */ package com.oracle.truffle.r.library.fastrGrid.graphics; +import static com.oracle.truffle.r.library.fastrGrid.device.DrawingContext.INCH_TO_POINTS_FACTOR; + import com.oracle.truffle.api.CompilerDirectives.TruffleBoundary; +import com.oracle.truffle.r.library.fastrGrid.GPar; import com.oracle.truffle.r.library.fastrGrid.GridContext; +import com.oracle.truffle.r.library.fastrGrid.device.DrawingContext; import com.oracle.truffle.r.library.fastrGrid.device.GridDevice; +import com.oracle.truffle.r.library.fastrGrid.grDevices.OpenDefaultDevice; import com.oracle.truffle.r.nodes.builtin.RExternalBuiltinNode; import com.oracle.truffle.r.runtime.RError; import com.oracle.truffle.r.runtime.RError.Message; @@ -39,13 +44,20 @@ public final class CPar extends RExternalBuiltinNode { Casts.noCasts(CPar.class); } + @Child private OpenDefaultDevice openDefaultDevice = new OpenDefaultDevice(); + @Override - @TruffleBoundary - protected Object call(RArgsValuesAndNames args) { + public Object call(RArgsValuesAndNames args) { if (args.getSignature().getNonNullCount() > 0) { throw error(Message.GENERIC, "Using par for setting device parameters is not supported in FastR grid emulation mode."); } + openDefaultDevice.execute(); + return getPar(args); + } + + @TruffleBoundary + private static Object getPar(RArgsValuesAndNames args) { GridDevice device = GridContext.getContext().getCurrentDevice(); RList names = RDataFactory.createList(args.getArguments()); // unwrap list if it is the first argument @@ -73,8 +85,31 @@ public final class CPar extends RExternalBuiltinNode { switch (name) { case "din": return RDataFactory.createDoubleVector(new double[]{device.getWidth(), device.getHeight()}, RDataFactory.COMPLETE_VECTOR); + case "cin": + /* + * character size ‘(width, height)’ in inches. These are the same measurements as + * ‘cra’, expressed in different units. + * + * Note: cin/cra is used in dev.size() to figure out the conversion ratio between + * pixels and inches. For the time being what is important is to choose the values + * to keep this ratio! + */ + double cin = getCurrentDrawingContext().getFontSize() / INCH_TO_POINTS_FACTOR; + return RDataFactory.createDoubleVector(new double[]{cin, cin}, RDataFactory.COMPLETE_VECTOR); + case "cra": + /* + * size of default character ‘(width, height)’ in ‘rasters’ (pixels). Some devices + * have no concept of pixels and so assume an arbitrary pixel size, usually 1/72 + * inch. These are the same measurements as ‘cin’, expressed in different units. + */ + double cra = getCurrentDrawingContext().getFontSize(); + return RDataFactory.createDoubleVector(new double[]{cra, cra}, RDataFactory.COMPLETE_VECTOR); default: throw RError.nyi(RError.NO_CALLER, "C_Par parameter '" + name + "'"); } } + + private static DrawingContext getCurrentDrawingContext() { + return GPar.create(GridContext.getContext().getGridState().getGpar()).getDrawingContext(0); + } } diff --git a/com.oracle.truffle.r.native/fficall/src/truffle_common/Rinternals_truffle_common.h b/com.oracle.truffle.r.native/fficall/src/truffle_common/Rinternals_truffle_common.h index 14461707794ccaa2bfce282df56de6741272c089..6cfe0a3c216e6495a0d9fdc8d8b5499409a86016 100644 --- a/com.oracle.truffle.r.native/fficall/src/truffle_common/Rinternals_truffle_common.h +++ b/com.oracle.truffle.r.native/fficall/src/truffle_common/Rinternals_truffle_common.h @@ -449,7 +449,8 @@ void Rf_copyVector(SEXP x, SEXP y) { int Rf_countContexts(int x, int y) { TRACE0(); - return (int) unimplemented("Rf_countContexts"); + unimplemented("Rf_countContexts"); + return 0; } Rboolean Rf_inherits(SEXP x, const char * klass) { @@ -775,14 +776,14 @@ SEXP CLOENV(SEXP x) { int RDEBUG(SEXP x) { TRACE0(); - SEXP result = ((call_RDEBUG) callbacks[RDEBUG_x])(x); + int result = ((call_RDEBUG) callbacks[RDEBUG_x])(x); checkExitCall(); return result; } int RSTEP(SEXP x) { TRACE0(); - SEXP result = ((call_RSTEP) callbacks[RSTEP_x])(x); + int result = ((call_RSTEP) callbacks[RSTEP_x])(x); checkExitCall(); return result; } @@ -925,7 +926,7 @@ SEXP PRVALUE(SEXP x) { int PRSEEN(SEXP x) { TRACE0(); - SEXP result = ((call_PRSEEN) callbacks[PRSEEN_x])(x); + int result = ((call_PRSEEN) callbacks[PRSEEN_x])(x); checkExitCall(); return result; } @@ -1104,14 +1105,14 @@ SEXP Rf_asCharacterFactor(SEXP x){ int Rf_asLogical(SEXP x) { TRACE0(); - SEXP result = ((call_Rf_asLogical) callbacks[Rf_asLogical_x])(x); + int result = ((call_Rf_asLogical) callbacks[Rf_asLogical_x])(x); checkExitCall(); return result; } int Rf_asInteger(SEXP x) { TRACE0(); - SEXP result = ((call_Rf_asInteger) callbacks[Rf_asInteger_x])(x); + int result = ((call_Rf_asInteger) callbacks[Rf_asInteger_x])(x); checkExitCall(); return result; } @@ -1214,7 +1215,8 @@ void R_qsort_int_I(int *iv, int *II, int i, int j) { R_len_t R_BadLongVector(SEXP x, const char *y, int z) { TRACE0(); - return (R_len_t) unimplemented("R_BadLongVector"); + unimplemented("R_BadLongVector"); + return (R_len_t) 0; } int IS_S4_OBJECT(SEXP x) { @@ -1494,7 +1496,8 @@ SEXP R_do_slot_assign(SEXP obj, SEXP name, SEXP value) { int R_has_slot(SEXP obj, SEXP name) { TRACE0(); - return (int) unimplemented("R_has_slot"); + unimplemented("R_has_slot"); + return 0; } SEXP R_do_MAKE_CLASS(const char *what) { @@ -1568,7 +1571,7 @@ void Rf_copyMatrix(SEXP s, SEXP t, Rboolean byrow) { int FASTR_getConnectionChar(SEXP conn) { TRACE0(); - SEXP result = ((call_FASTR_getConnectionChar) callbacks[FASTR_getConnectionChar_x])(conn); + int result = ((call_FASTR_getConnectionChar) callbacks[FASTR_getConnectionChar_x])(conn); checkExitCall(); return result; }