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

FastR Grid: implement line styles

parent 193fbef0
Branches
No related tags found
No related merge requests found
......@@ -11,18 +11,23 @@
*/
package com.oracle.truffle.r.library.fastrGrid;
import static com.oracle.truffle.r.library.fastrGrid.GridUtils.asAbstractContainer;
import static com.oracle.truffle.r.library.fastrGrid.GridUtils.asDouble;
import java.util.Arrays;
import com.oracle.truffle.r.library.fastrGrid.device.DrawingContext;
import com.oracle.truffle.r.library.fastrGrid.device.GridColor;
import com.oracle.truffle.r.runtime.RError;
import com.oracle.truffle.r.runtime.RError.Message;
import com.oracle.truffle.r.runtime.RRuntime;
import com.oracle.truffle.r.runtime.data.RDataFactory;
import com.oracle.truffle.r.runtime.data.RList;
import com.oracle.truffle.r.runtime.data.RNull;
import com.oracle.truffle.r.runtime.data.RStringVector;
import com.oracle.truffle.r.runtime.data.model.RAbstractContainer;
import com.oracle.truffle.r.runtime.data.model.RAbstractDoubleVector;
import com.oracle.truffle.r.runtime.data.model.RAbstractIntVector;
/**
* In the context of grid package, GPar is a list that contains the parameters for the drawing, like
......@@ -85,7 +90,7 @@ public final class GPar {
data[GP_FILL] = "transparent";
data[GP_COL] = "black";
data[GP_GAMMA] = newDoubleVec(0);
data[GP_LTY] = "solid"; // TODO: LineType enum...
data[GP_LTY] = "solid";
data[GP_LWD] = newDoubleVec(1);
data[GP_CEX] = newDoubleVec(1);
data[GP_FONTSIZE] = newDoubleVec(16);
......@@ -119,6 +124,35 @@ public final class GPar {
data = list.getDataWithoutCopying();
}
@Override
public GridLineType getLineType() {
Object lty = data[GP_LTY];
if (lty == null || lty == RNull.instance) {
return GridLineType.SOLID;
}
String name = RRuntime.asString(lty);
if (name != null) {
return lineTypeFromName(name);
}
RAbstractContainer ltyVec = asAbstractContainer(lty);
int num;
if (ltyVec.getLength() == 0) {
num = RRuntime.INT_NA;
} else if (ltyVec instanceof RAbstractDoubleVector) {
double realVal = ((RAbstractDoubleVector) ltyVec).getDataAt(0);
num = RRuntime.isNA(realVal) ? RRuntime.INT_NA : (int) realVal;
} else if (ltyVec instanceof RAbstractIntVector) {
num = ((RAbstractIntVector) ltyVec).getDataAt(0);
} else {
num = RRuntime.INT_NA;
}
if (RRuntime.isNA(num)) {
throw RError.error(RError.NO_CALLER, Message.GENERIC, "Invalid line type.");
}
return GridLineType.fromInt(num);
}
@Override
public GridColor getColor() {
return getGridColor(GP_COL);
......@@ -152,5 +186,27 @@ public final class GPar {
private GridColor getGridColor(int index) {
return GridColorUtils.gridColorFromString(RRuntime.asString(data[index]));
}
private GridLineType lineTypeFromName(String name) {
switch (name) {
case "solid":
return GridLineType.SOLID;
case "dashed":
return GridLineType.DASHED;
case "dotted":
return GridLineType.DOTTED;
case "dotdashed":
return GridLineType.DOTDASHED;
case "longdash":
return GridLineType.LONGDASH;
case "twodash":
return GridLineType.TWODASH;
case "blank":
return GridLineType.BLANK;
default:
// TODO: implement hex digits as line style
throw RError.error(RError.NO_CALLER, Message.GENERIC, "Unexpected line type '" + name + "'.");
}
}
}
}
......@@ -28,6 +28,30 @@ package com.oracle.truffle.r.library.fastrGrid.device;
public interface DrawingContext {
double INCH_TO_POINTS_FACTOR = 72.27;
enum GridLineType {
// The order is important!
BLANK,
SOLID,
DASHED,
DOTTED,
DOTDASHED,
LONGDASH,
TWODASH;
private static final int LINE_TYPES_COUNT = 7;
private static final GridLineType[] allValues = values();
public static GridLineType fromInt(int num) {
if (num == -1) {
return BLANK;
}
assert num >= 1;
return allValues[(num - 1) % LINE_TYPES_COUNT + 1];
}
}
GridLineType getLineType();
GridColor getColor();
/**
......
......@@ -36,7 +36,9 @@ import java.awt.geom.Path2D;
import java.awt.geom.Rectangle2D;
import java.util.function.Supplier;
import com.oracle.truffle.r.library.fastrGrid.device.DrawingContext.GridLineType;
import com.oracle.truffle.r.library.graphics.FastRFrame;
import com.oracle.truffle.r.runtime.RInternalError;
public class JFrameDevice implements GridDevice {
// Grid's coordinate system has origin in left bottom corner and y axis grows from bottom to
......@@ -46,11 +48,20 @@ public class JFrameDevice implements GridDevice {
// only, we reset the transformation completely and transform the coordinates ourselves
private static final double POINTS_IN_INCH = 72.;
private static BasicStroke solidStroke;
private static BasicStroke blankStroke;
private static BasicStroke dashedStroke;
private static BasicStroke longdashedStroke;
private static BasicStroke twodashedStroke;
private static BasicStroke dotdashedStroke;
private static BasicStroke dottedStroke;
private FastRFrame currentFrame;
private Graphics2D graphics;
@Override
public void openNewPage() {
initStrokes();
if (currentFrame == null) {
currentFrame = new FastRFrame();
currentFrame.setVisible(true);
......@@ -147,6 +158,7 @@ public class JFrameDevice implements GridDevice {
private void setContext(DrawingContext ctx) {
graphics.setColor(fromGridColor(ctx.getColor()));
graphics.setStroke(fromGridLineType(ctx.getLineType()));
}
private void setFontSize(DrawingContext ctx) {
......@@ -165,4 +177,41 @@ public class JFrameDevice implements GridDevice {
private static Color fromGridColor(GridColor color) {
return new Color(color.getRed(), color.getGreen(), color.getBlue(), color.getAlpha());
}
private static BasicStroke fromGridLineType(GridLineType type) {
switch (type) {
case SOLID:
return solidStroke;
case BLANK:
return blankStroke;
case DASHED:
return dashedStroke;
case DOTDASHED:
return dotdashedStroke;
case DOTTED:
return dottedStroke;
case TWODASH:
return twodashedStroke;
case LONGDASH:
return longdashedStroke;
default:
throw RInternalError.shouldNotReachHere("unexpected value of GridLineType enum");
}
}
private static void initStrokes() {
if (solidStroke != null) {
return;
}
float defaultWidth = (float) (1. / POINTS_IN_INCH);
float dashSize = (float) (10. / POINTS_IN_INCH);
float dotSize = (float) (2. / POINTS_IN_INCH);
solidStroke = new BasicStroke((float) (1f / POINTS_IN_INCH));
blankStroke = new BasicStroke(0f);
dashedStroke = new BasicStroke(defaultWidth, BasicStroke.CAP_SQUARE, BasicStroke.JOIN_MITER, 10f, new float[]{dashSize}, 0f);
dottedStroke = new BasicStroke(defaultWidth, BasicStroke.CAP_SQUARE, BasicStroke.JOIN_MITER, 10f, new float[]{dotSize}, 0f);
dotdashedStroke = new BasicStroke(defaultWidth, BasicStroke.CAP_SQUARE, BasicStroke.JOIN_MITER, 10f, new float[]{dotSize, dashSize}, 0f);
twodashedStroke = new BasicStroke(defaultWidth, BasicStroke.CAP_SQUARE, BasicStroke.JOIN_MITER, 10f, new float[]{dashSize / 2f, dashSize}, 0f);
longdashedStroke = new BasicStroke(defaultWidth, BasicStroke.CAP_SQUARE, BasicStroke.JOIN_MITER, 10f, new float[]{2f * dashSize}, 0f);
}
}
0% Loading or .
You are about to add 0 people to the discussion. Proceed with caution.
Please register or to comment