Skip to content
Snippets Groups Projects
Commit 592900b5 authored by stepan's avatar stepan
Browse files

Fix NPE in "par" function when no graphical device has not been opened yet

parent 871e00c7
No related branches found
No related tags found
No related merge requests found
......@@ -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);
......
......@@ -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();
}
......
......@@ -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);
......
......@@ -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
*/
......
/*
* 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();
}
}
}
......@@ -25,11 +25,11 @@ 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.api.frame.VirtualFrame;
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;
......@@ -44,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
......@@ -80,19 +87,20 @@ public final class CPar extends RExternalBuiltinNode {
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.
* 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!
* 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.
* 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);
......
0% Loading or .
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment