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

FastR Grid: implement L_points

parent f12f277a
No related branches found
No related tags found
No related merge requests found
......@@ -11,6 +11,8 @@
*/
package com.oracle.truffle.r.library.fastrGrid;
import static com.oracle.truffle.r.library.fastrGrid.GridUtils.asDouble;
import java.util.Arrays;
import com.oracle.truffle.r.library.fastrGrid.device.DrawingContext;
......@@ -97,6 +99,10 @@ public final class GPar {
return RDataFactory.createList(data, NAMES_VECTOR);
}
public static double getCex(RList gpar) {
return asDouble(gpar.getDataAt(GP_CEX));
}
public static DrawingContext asDrawingContext(RList gpar) {
return new GParDrawingContext(gpar);
}
......@@ -114,22 +120,40 @@ public final class GPar {
@Override
public String getColor() {
String result = RRuntime.asString(data[GP_COL]);
if (!result.startsWith("#")) {
result = ColorNames.findByName(result);
}
return result == null ? "#FFFFFF" : result;
return getHexColor(GP_COL);
}
@Override
public void setColor(String hexCode) {
data[GP_COL] = hexCode;
}
@Override
public double getFontSize() {
return GridUtils.asDouble(data[GP_FONTSIZE]) * GridUtils.asDouble(data[GP_CEX]);
return asDouble(data[GP_FONTSIZE]) * asDouble(data[GP_CEX]);
}
@Override
public double getLineHeight() {
return GridUtils.asDouble(data[GP_LINEHEIGHT]);
return asDouble(data[GP_LINEHEIGHT]);
}
@Override
public String getFillColor() {
return getHexColor(GP_FILL);
}
@Override
public void setFillColor(String hexCode) {
data[GP_FILL] = hexCode;
}
private String getHexColor(int index) {
String result = RRuntime.asString(data[index]);
if (!result.startsWith("#")) {
result = ColorNames.findByName(result);
}
return result == null ? "#FFFFFF" : result;
}
}
}
......@@ -19,8 +19,7 @@ import com.oracle.truffle.r.library.fastrGrid.Unit.UnitLengthNode;
import com.oracle.truffle.r.runtime.RError;
import com.oracle.truffle.r.runtime.RError.Message;
import com.oracle.truffle.r.runtime.data.RAttributable;
import com.oracle.truffle.r.runtime.data.RDouble;
import com.oracle.truffle.r.runtime.data.RInteger;
import com.oracle.truffle.r.runtime.data.RDataFactory;
import com.oracle.truffle.r.runtime.data.RList;
import com.oracle.truffle.r.runtime.data.RStringVector;
import com.oracle.truffle.r.runtime.data.model.RAbstractContainer;
......@@ -116,7 +115,7 @@ final class GridUtils {
static RAbstractIntVector asIntVector(Object value) {
if (value instanceof Integer) {
return RInteger.valueOf((Integer) value);
return RDataFactory.createIntVectorFromScalar((Integer) value);
} else if (value instanceof RAbstractIntVector) {
return (RAbstractIntVector) value;
}
......@@ -125,7 +124,7 @@ final class GridUtils {
public static RAbstractDoubleVector asDoubleVector(Object obj) {
if (obj instanceof Double) {
return RDouble.valueOf((Double) obj);
return RDataFactory.createDoubleVectorFromScalar((Double) obj);
} else if (obj instanceof RAbstractDoubleVector) {
return (RAbstractDoubleVector) obj;
}
......@@ -134,9 +133,9 @@ final class GridUtils {
static RAbstractContainer asAbstractContainer(Object value) {
if (value instanceof Integer) {
return RInteger.valueOf((Integer) value);
return RDataFactory.createIntVectorFromScalar((Integer) value);
} else if (value instanceof Double) {
return RDouble.valueOf((Double) value);
return RDataFactory.createDoubleVectorFromScalar((Double) value);
} else if (value instanceof RAbstractContainer) {
return (RAbstractContainer) value;
}
......
/*
* This material is distributed under the GNU General Public License
* Version 2. You may review the terms of this license at
* http://www.gnu.org/licenses/gpl-2.0.html
*
* Copyright (C) 2001-3 Paul Murrell
* Copyright (c) 1998-2015, The R Core Team
* Copyright (c) 2017, Oracle and/or its affiliates
*
* All rights reserved.
*/
package com.oracle.truffle.r.library.fastrGrid;
import static com.oracle.truffle.r.nodes.builtin.CastBuilder.Predef.abstractVectorValue;
import static com.oracle.truffle.r.nodes.builtin.CastBuilder.Predef.numericValue;
import com.oracle.truffle.api.dsl.Specialization;
import com.oracle.truffle.r.library.fastrGrid.Unit.UnitConversionContext;
import com.oracle.truffle.r.library.fastrGrid.Unit.UnitLengthNode;
import com.oracle.truffle.r.library.fastrGrid.Unit.UnitToInchesNode;
import com.oracle.truffle.r.library.fastrGrid.ViewPortContext.VPContextFromVPNode;
import com.oracle.truffle.r.library.fastrGrid.ViewPortTransform.GetViewPortTransformNode;
import com.oracle.truffle.r.library.fastrGrid.device.DrawingContext;
import com.oracle.truffle.r.library.fastrGrid.device.GridDevice;
import com.oracle.truffle.r.nodes.builtin.RExternalBuiltinNode;
import com.oracle.truffle.r.runtime.RError.Message;
import com.oracle.truffle.r.runtime.RInternalError;
import com.oracle.truffle.r.runtime.data.RList;
import com.oracle.truffle.r.runtime.data.RNull;
import com.oracle.truffle.r.runtime.data.model.RAbstractIntVector;
import com.oracle.truffle.r.runtime.data.model.RAbstractVector;
public abstract class LPoints extends RExternalBuiltinNode.Arg4 {
private static final double SMALL = 0.25;
private static final double RADIUS = 0.375;
private static final double SQRC = 0.88622692545275801364; /* sqrt(pi / 4) */
private static final double DMDC = 1.25331413731550025119; /* sqrt(pi / 4) * sqrt(2) */
private static final double TRC0 = 1.55512030155621416073; /* sqrt(4 * pi/(3 * sqrt(3))) */
private static final double TRC1 = 1.34677368708859836060; /* TRC0 * sqrt(3) / 2 */
private static final double TRC2 = 0.77756015077810708036; /* TRC0 / 2 */
private static final String TRANSPARENT = "white"; // TODO: should be actually transparent
@Child private GetViewPortTransformNode getViewPortTransform = new GetViewPortTransformNode();
@Child private VPContextFromVPNode vpContextFromVP = new VPContextFromVPNode();
@Child private UnitLengthNode unitLength = Unit.createLengthNode();
@Child private UnitToInchesNode unitToInches = Unit.createToInchesNode();
static {
Casts casts = new Casts(LPoints.class);
casts.arg(0).mustBe(abstractVectorValue());
casts.arg(1).mustBe(abstractVectorValue());
casts.arg(2).mustBe(numericValue(), Message.GENERIC, "grid.points: pch argument not implemented for characters yet").asIntegerVector();
casts.arg(3).mustBe(abstractVectorValue());
}
public static LPoints create() {
return LPointsNodeGen.create();
}
@Specialization
public Object doPoints(RAbstractVector xVec, RAbstractVector yVec, RAbstractIntVector pchVec, RAbstractVector sizeVec) {
GridContext ctx = GridContext.getContext();
GridDevice dev = ctx.getCurrentDevice();
RList currentVP = ctx.getGridState().getViewPort();
RList gpar = ctx.getGridState().getGpar();
DrawingContext drawingCtx = GPar.asDrawingContext(gpar);
double cex = GPar.getCex(gpar);
ViewPortTransform vpTransform = getViewPortTransform.execute(currentVP);
ViewPortContext vpContext = vpContextFromVP.execute(currentVP);
UnitConversionContext conversionCtx = new UnitConversionContext(vpTransform.size, vpContext, drawingCtx);
// Note: unlike in other drawing primitives, we only consider length of x
int length = unitLength.execute(xVec);
for (int i = 0; i < length; i++) {
Point loc = TransformMatrix.transLocation(Point.fromUnits(unitToInches, xVec, yVec, i, conversionCtx), vpTransform.transform);
double size = unitToInches.convertWidth(sizeVec, i, conversionCtx);
if (loc.isFinite() && Double.isFinite(size)) {
drawSymbol(drawingCtx, dev, cex, pchVec.getDataAt(i % pchVec.getLength()), size, loc.x, loc.y);
}
}
return RNull.instance;
}
// transcribed from engine.c function GESymbol
private void drawSymbol(DrawingContext drawingCtx, GridDevice dev, double cex, int pch, double size, double x, double y) {
// pch 0 - 25 are interpreted as geometrical shapes, pch from ascii code of ' ' are
// interpreted as corresponding ascii character, which should be drawn
switch (pch) {
case 46:
drawDot(drawingCtx, dev, cex, x, y);
break;
case 1:
drawOctahedron(drawingCtx, dev, GridColor.TRANSPARENT, size, x, y);
break;
case 16:
drawOctahedron(drawingCtx, dev, drawingCtx.getColor(), size, x, y);
break;
default:
throw RInternalError.unimplemented("grid.points unimplemented symbol " + pch);
}
}
private static void drawOctahedron(DrawingContext drawingCtx, GridDevice dev, GridColor fill, double size, double x, double y) {
GridColor originalFill = drawingCtx.getFillColor();
drawingCtx.setFillColor(fill);
dev.drawCircle(drawingCtx, x, y, RADIUS * size);
drawingCtx.setFillColor(originalFill);
}
private static void drawDot(DrawingContext drawingCtx, GridDevice dev, double cex, double x, double y) {
// NOTE: we are *filling* a rect with the current colour (we are not drawing the border AND
// we are not using the current fill colour)
String originalFill = drawingCtx.getFillColor();
drawingCtx.setFillColor(drawingCtx.getColor());
drawingCtx.setColor(TRANSPARENT);
/*
* The idea here is to use a 0.01" square, but to be of at least one device unit in each
* direction, assuming that corresponds to pixels. That may be odd if pixels are not square,
* but only on low resolution devices where we can do nothing better.
*
* For this symbol only, size is cex (see engine.c).
*
* Prior to 2.1.0 the offsets were always 0.5.
*/
double xc = cex * 0.005;
double yc = cex * 0.005;
if (cex > 0 && xc < 0.5) {
xc = 0.5;
}
if (cex > 0 && yc < 0.5) {
yc = 0.5;
}
dev.drawRect(drawingCtx, x - xc, y - yc, x + xc, y + yc);
drawingCtx.setColor(drawingCtx.getFillColor());
drawingCtx.setFillColor(originalFill);
}
}
......@@ -34,6 +34,12 @@ public interface DrawingContext {
*/
String getColor();
/**
* Alows to set the color. The parameter may also be a synonym defined in
* {@link com.oracle.truffle.r.library.fastrGrid.ColorNames}.
*/
void setColor(String hexCode);
/**
* Gets the font size in points.
*
......@@ -45,4 +51,16 @@ public interface DrawingContext {
* Gets the height of a line in multiplies of the base line height.
*/
double getLineHeight();
/**
* @return Hexadecimal string of the color with leading '#', e.g. '#FFA8B2'. Never returns a
* synonym.
*/
String getFillColor();
/**
* Alows to set the fill color. The parameter may also be a synonym defined in
* {@link com.oracle.truffle.r.library.fastrGrid.ColorNames}.
*/
void setFillColor(String hexCode);
}
......@@ -34,6 +34,7 @@ import com.oracle.truffle.r.library.fastrGrid.LInitGrid;
import com.oracle.truffle.r.library.fastrGrid.LInitViewPortStack;
import com.oracle.truffle.r.library.fastrGrid.LLines;
import com.oracle.truffle.r.library.fastrGrid.LNewPage;
import com.oracle.truffle.r.library.fastrGrid.LPoints;
import com.oracle.truffle.r.library.fastrGrid.LRect;
import com.oracle.truffle.r.library.fastrGrid.LSegments;
import com.oracle.truffle.r.library.fastrGrid.LText;
......@@ -709,6 +710,8 @@ public class CallAndExternalFunctions {
return LSegments.create();
case "L_circle":
return LCircle.create();
case "L_points":
return LPoints.create();
// Simple grid state access
case "L_getGPar":
......
......@@ -767,6 +767,7 @@ com.oracle.truffle.r.nodes.builtin/src/com/oracle/truffle/r/nodes/builtin/base/p
com.oracle.truffle.r.library/src/com/oracle/truffle/r/library/stats/deriv/Deriv.java,gnu_r_gentleman_ihaka2.copyright
com.oracle.truffle.r.library/src/com/oracle/truffle/r/library/stats/deriv/DerivVisitor.java,gnu_r_gentleman_ihaka2.copyright
com.oracle.truffle.r.library/src/com/oracle/truffle/r/library/fastrGrid/LRect.java,gnu_r_murrel_core.copyright
com.oracle.truffle.r.library/src/com/oracle/truffle/r/library/fastrGrid/LPoints.java,gnu_r_murrel_core.copyright
com.oracle.truffle.r.library/src/com/oracle/truffle/r/library/fastrGrid/GridState.java,gnu_r_murrel_core.copyright
com.oracle.truffle.r.library/src/com/oracle/truffle/r/library/fastrGrid/DoSetViewPortBuiltin.java,gnu_r_murrel_core.copyright
com.oracle.truffle.r.library/src/com/oracle/truffle/r/library/fastrGrid/LUpViewPort.java,gnu_r_murrel_core.copyright
......
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