Skip to content
Snippets Groups Projects
Commit ab0a8631 authored by Andrey Ruzhanskiy's avatar Andrey Ruzhanskiy
Browse files

Merge remote-tracking branch 'origin/master' into feat/cli_update-37

parents d7a5d004 c7f6e264
No related branches found
No related tags found
1 merge request!39App restructuring
Showing
with 108 additions and 27 deletions
package de.tudresden.inf.mci.brailleplot.configparser;
import de.tudresden.inf.mci.brailleplot.rendering.language.BrailleLanguage;
import de.tudresden.inf.mci.brailleplot.util.GeneralResource;
import de.tudresden.inf.mci.brailleplot.printerbackend.PrinterCapability;
import org.slf4j.Logger;
......@@ -76,6 +77,8 @@ public final class JavaPropertiesConfigurationValidator implements Configuration
// Definition of valid representation properties
defineRepresentationProperty("general.nonexistentDataText", requireNotEmpty);
defineRepresentationProperty("general.brailleLanguage", requireNotEmpty);
defineRepresentationProperty("general.legendKeyword", requireNotEmpty);
defineRepresentationProperty("general.maxTitleHeight", requireInteger.and(requirePositive).and(requireNonZero));
defineRepresentationProperty("rasterize.barChart.maxBarThickness", requireInteger.and(requirePositive));
defineRepresentationProperty("rasterize.barChart.minBarThickness", requireInteger.and(requirePositive));
......@@ -98,6 +101,9 @@ public final class JavaPropertiesConfigurationValidator implements Configuration
case "brailletable":
case "semantictable":
return new GeneralResource(value, mSearchPath).getResourcePath();
case "general.brailleLanguage":
BrailleLanguage.Language language = BrailleLanguage.Language.valueOf(value.toUpperCase());
return language.toString();
default: return value;
}
} catch (Exception e) {
......
......@@ -54,6 +54,7 @@ public class BarChartRasterizer implements Rasterizer<CategoricalBarChart> {
private int mGroupPaddingCells; // the padding size between two neighbouring bar groups in cells
private int mBarPaddingCells; // the padding size between two bars inside the same group in cells
private String nonexistentDataText; // the text which is displayed for a missing datapoint
private BrailleLanguage.Language mBrailleLanguage; // the preferred language & level for titles, captions, ...
// Texture Management
private List<Texture<Boolean>> mTextures = new ArrayList<>(); // A list of textures to differentiate bars inside a group
......@@ -98,6 +99,8 @@ public class BarChartRasterizer implements Rasterizer<CategoricalBarChart> {
nonexistentDataText = canvas.getRepresentation().getProperty("general.nonexistentDataText").toString();
mBrailleLanguage = BrailleLanguage.Language.valueOf(canvas.getRepresentation().getProperty("general.brailleLanguage").toString());
// Load textures
double[] rotate90 = {0, 0, 0, 1, 1, 0};
registerTexture(new Texture<>(TexturedArea.BOTTOM_T_PATTERN).applyAffineTransformation(rotate90), 0, 0);
......@@ -139,7 +142,7 @@ public class BarChartRasterizer implements Rasterizer<CategoricalBarChart> {
// PHASE 1 - LAYOUT: The following calculations will divide the canvas area to create the basic chart layout.
// Diagram Title
String title = diagram.getTitle();
int titleLength = mTextRasterizer.getBrailleStringLength(title);
int titleLength = mTextRasterizer.getBrailleStringLength(title, mBrailleLanguage);
int titleHeight = (int) Math.ceil(titleLength / referenceCellArea.getWidth());
if (titleHeight > mMaximumTitleHeightCells) {
throw new InsufficientRenderingAreaException("Title is too long. (Exceeds maximum height)");
......@@ -198,20 +201,20 @@ public class BarChartRasterizer implements Rasterizer<CategoricalBarChart> {
// PHASE 2 - RASTERIZING: Now, every element of the chart will be drawn onto the according area.
// Diagram Title
mTextRasterizer.rasterize(new BrailleText(title, titleDotArea), canvas);
mTextRasterizer.rasterize(new BrailleText(title, titleDotArea, mBrailleLanguage), canvas);
// Y-Axis: no units, no tickmarks
Axis yAxis = new Axis(Axis.Type.Y_AXIS, originXDotCoordinate, originYDotCoordinate, 1, 0);
yAxis.setBoundary(yAxisDotArea);
mAxisRasterizer.rasterize(yAxis, canvas);
// Y-Axis name
mTextRasterizer.rasterize(new BrailleText(diagram.getYAxisName(), yAxisNameDotArea), canvas);
mTextRasterizer.rasterize(new BrailleText(diagram.getYAxisName(), yAxisNameDotArea, mBrailleLanguage), canvas);
// X-Axis: units and labels
Axis xAxis = new Axis(Axis.Type.X_AXIS, originXDotCoordinate, originYDotCoordinate, X_AXIS_UNIT_SIZE_DOTS, X_AXIS_TICK_SIZE_DOTS);
xAxis.setBoundary(xAxisDotArea);
xAxis.setLabels(generateNumericAxisLabels(xAxisScaling, xAxisScalingMagnitude, negativeAvailableUnits, positiveAvailableUnits));
mAxisRasterizer.rasterize(xAxis, canvas);
// X-Axis name
mTextRasterizer.rasterize(new BrailleText(diagram.getXAxisName(), xAxisNameDotArea), canvas);
mTextRasterizer.rasterize(new BrailleText(diagram.getXAxisName(), xAxisNameDotArea, mBrailleLanguage), canvas);
// The actual groups and bars:
// This is done by iterating through the diagram data set and drawing borders with the respective padding based on whether switched
// from one bar to another or a group to another. In between, the bars are rasterized as textured areas, with a line on the bars top.
......@@ -270,7 +273,7 @@ public class BarChartRasterizer implements Rasterizer<CategoricalBarChart> {
}
// PHASE 3 - DIAGRAM LEGEND: Symbols and textures are explained in the legend which will be created by the LegendRasterizer
Legend diagramLegend = new Legend(title); // Create a legend container
Legend diagramLegend = new Legend(title, mBrailleLanguage); // Create a legend container
diagramLegend.addSymbolExplanation("Achsenskalierung:", "X-Achse", "Faktor " + xAxisScalingMagnitude); // Explain axis scaling
diagramLegend.addSymbolExplanationGroup("Kategorien:", groupNameExplanations); // Explain bar group single character captions
if (textureExplanations.size() > 1) { // Explain textures (if multiple of them were used)
......
......@@ -15,6 +15,10 @@ public class BrailleText implements Renderable {
private String mContent;
private Rectangle mArea;
/**
* Getter for the associated language used in this braille text.
* @return String containing the language
*/
public String getLanguage() {
return mLanguage;
}
......@@ -32,7 +36,7 @@ public class BrailleText implements Renderable {
mLanguage = "de-g0.utb";
}
public BrailleText(final String content, final Rectangle area, BrailleLanguage.Language language) {
public BrailleText(final String content, final Rectangle area, final BrailleLanguage.Language language) {
setText(content);
setArea(area);
mLanguage = BrailleLanguage.getCorrectLanguage(language);
......
package de.tudresden.inf.mci.brailleplot.rendering;
import de.tudresden.inf.mci.brailleplot.rendering.language.BrailleLanguage;
import java.util.LinkedHashMap;
import java.util.Map;
import java.util.Objects;
......@@ -12,6 +14,7 @@ import java.util.Objects;
public class Legend implements Renderable {
private String mTitle;
private BrailleLanguage.Language mLanguage;
private Map<String, Map<String, String>> mStringExplanationLists = new LinkedHashMap<>();
private Map<String, Map<Texture<Boolean>, String>> mTextureExplanationLists = new LinkedHashMap<>();
......@@ -19,11 +22,22 @@ public class Legend implements Renderable {
private int mTextureExampleHeightCells = 1;
/**
* Constructor. Creates a legend.
* Constructor. Creates a legend with default language (DE_BASISSCHRIFT).
* @param title The title of the legend.
*/
public Legend(final String title) {
setTitle(title);
setLanguage(BrailleLanguage.Language.DE_BASISSCHRIFT);
}
/**
* Constructor. Creates a legend with a defined language.
* @param title The title of the legend.
* @param language A {@link BrailleLanguage.Language}.
*/
public Legend(final String title, final BrailleLanguage.Language language) {
setTitle(title);
setLanguage(language);
}
/**
......@@ -34,6 +48,14 @@ public class Legend implements Renderable {
mTitle = Objects.requireNonNull(title);
}
/**
* Sets the braille language and level.
* @param language The new language.
*/
public void setLanguage(final BrailleLanguage.Language language) {
mLanguage = Objects.requireNonNull(language);
}
/**
* Gets the current title of the legend.
* @return A {@link String} containing the title.
......@@ -42,6 +64,14 @@ public class Legend implements Renderable {
return mTitle;
}
/**
* Gets the current braille language and level.
* @return A {@link BrailleLanguage.Language} determining the language and braille level.
*/
public BrailleLanguage.Language getLanguage() {
return mLanguage;
}
/**
* Add a text symbol and the associated description text to the legend.
* @param groupName The name of the header under which explanations of this group will be placed. (e.g. "Categories")
......
......@@ -4,6 +4,8 @@ import de.tudresden.inf.mci.brailleplot.layout.InsufficientRenderingAreaExceptio
import de.tudresden.inf.mci.brailleplot.layout.RasterCanvas;
import de.tudresden.inf.mci.brailleplot.layout.Rectangle;
import de.tudresden.inf.mci.brailleplot.printabledata.MatrixData;
import de.tudresden.inf.mci.brailleplot.rendering.language.BrailleLanguage;
import java.util.Map;
import static java.lang.Integer.max;
......@@ -16,10 +18,12 @@ public class LegendRasterizer implements Rasterizer<Legend> {
private RasterCanvas mCanvas;
private Legend mLegend;
private BrailleLanguage.Language mLanguage;
private String mLegendKeyword; // title for the legend
private static final int MIN_TEXT_WIDTH_CELLS = 10; // how much space should be available for an explanation text at least. (To avoid excessive line breaking)
private static final int EXPLANATION_TEXT_INDENTATION_CELLS = 1; // indentation for explanation texts.
private static final String LEGEND_KEYWORD = "Legende:"; // title for the legend
private static final BrailleLanguage.Language EXPLANATION_LIST_LANGUAGE = BrailleLanguage.Language.DE_BASISSCHRIFT;
// Sub rasterizers
private LiblouisBrailleTextRasterizer mTextRasterizer;
......@@ -36,6 +40,7 @@ public class LegendRasterizer implements Rasterizer<Legend> {
mTextRasterizer = new LiblouisBrailleTextRasterizer(canvas.getPrinter());
mCanvas = canvas;
mLegend = legend;
mLegendKeyword = mCanvas.getRepresentation().getProperty("general.legendKeyword").toString();
// Create a fresh page on the canvas.
MatrixData<Boolean> page = canvas.getNewPage();
......@@ -44,32 +49,38 @@ public class LegendRasterizer implements Rasterizer<Legend> {
try {
// Write "Legend" keyword + title
writeLine(LEGEND_KEYWORD + " " + legend.getTitle(), referenceCellArea);
setLanguage(legend.getLanguage());
writeLine(mLegendKeyword + " " + legend.getTitle(), referenceCellArea);
// String explanation lists
for (Map.Entry<String, Map<String, String>> list : legend.getSymbolExplanationGroups().entrySet()) {
// Texture explanation lists
for (Map.Entry<String, Map<Texture<Boolean>, String>> list : legend.getTextureExplanationGroups().entrySet()) {
String groupName = list.getKey();
setLanguage(legend.getLanguage());
writeLine("", referenceCellArea); // Leave space of one empty line
writeLine(groupName + ":", referenceCellArea);
writeLine(groupName, referenceCellArea);
moveIndentation(referenceCellArea, EXPLANATION_TEXT_INDENTATION_CELLS); // set indentation
for (Map.Entry<String, String> explanation : list.getValue().entrySet()) {
String symbol = explanation.getKey();
setLanguage(EXPLANATION_LIST_LANGUAGE);
for (Map.Entry<Texture<Boolean>, String> explanation : list.getValue().entrySet()) {
Texture<Boolean> texture = explanation.getKey();
String description = explanation.getValue();
writeLine(symbol + " - " + description, referenceCellArea);
drawTextureExample(referenceCellArea, texture, description);
}
moveIndentation(referenceCellArea, -1 * EXPLANATION_TEXT_INDENTATION_CELLS); // reset indentation
}
// Texture explanation lists
for (Map.Entry<String, Map<Texture<Boolean>, String>> list : legend.getTextureExplanationGroups().entrySet()) {
// String explanation lists
for (Map.Entry<String, Map<String, String>> list : legend.getSymbolExplanationGroups().entrySet()) {
String groupName = list.getKey();
setLanguage(legend.getLanguage());
writeLine("", referenceCellArea); // Leave space of one empty line
writeLine(groupName + ":", referenceCellArea);
writeLine(groupName, referenceCellArea);
moveIndentation(referenceCellArea, EXPLANATION_TEXT_INDENTATION_CELLS); // set indentation
for (Map.Entry<Texture<Boolean>, String> explanation : list.getValue().entrySet()) {
Texture<Boolean> texture = explanation.getKey();
setLanguage(EXPLANATION_LIST_LANGUAGE);
for (Map.Entry<String, String> explanation : list.getValue().entrySet()) {
String symbol = explanation.getKey();
String description = explanation.getValue();
drawTextureExample(referenceCellArea, texture, description);
writeLine(symbol + " " + description, referenceCellArea);
}
moveIndentation(referenceCellArea, -1 * EXPLANATION_TEXT_INDENTATION_CELLS); // reset indentation
}
......@@ -136,10 +147,18 @@ public class LegendRasterizer implements Rasterizer<Legend> {
throw new InsufficientRenderingAreaException("Not enough space for legend text.");
}
// write text lines
int textLength = mTextRasterizer.getBrailleStringLength(text);
int textLength = mTextRasterizer.getBrailleStringLength(text, getLanguage());
int textHeight = max(1, (int) Math.ceil(textLength / cellArea.getWidth()));
Rectangle textLineDotArea = mCanvas.toDotRectangle(cellArea.removeFromTop(textHeight));
mTextRasterizer.rasterize(new BrailleText(text, textLineDotArea), mCanvas);
mTextRasterizer.rasterize(new BrailleText(text, textLineDotArea, getLanguage()), mCanvas);
}
private void setLanguage(final BrailleLanguage.Language language) {
mLanguage = language;
}
private BrailleLanguage.Language getLanguage() {
return mLanguage;
}
}
package de.tudresden.inf.mci.brailleplot.rendering.language;
/**
* Helper class for braillelanguage
* Helper class for braillelanguage.
* @author Andrey Ruzhanskiy
* @version 27.09.2019
*/
@SuppressWarnings("HideUtilityClassConstructor")
public class BrailleLanguage {
public static String getCorrectLanguage(Language language){
/**
* Method to get the correct name of the table for the given enum.
* @param language Enum, for which the table is to be known.
* @return String containing the name of the table.
*/
public static String getCorrectLanguage(final Language language) {
switch (language) {
case GERMAN_VOLLSCHRIFT:
case DE_VOLLSCHRIFT:
......@@ -18,11 +24,14 @@ public class BrailleLanguage {
case GERMAN_KURZSCHRIFT:
case DE_KURZSCHRIFT:
return "de-g2.ctb";
default:
throw new RuntimeException("Unsupported language given as braillelanguage! \"" + language.toString() + "\"");
}
throw new RuntimeException("Unsupported language given as braillelanguage! \"" + language.toString() + "\"");
}
/**
* Enum describing the current supported braille languages and grammars.
*/
public enum Language {
DE_KURZSCHRIFT,
DE_BASISSCHRIFT,
......
/**
* This package contains the language helper class and the braille language declaration.
*/
package de.tudresden.inf.mci.brailleplot.rendering.language;
\ No newline at end of file
......@@ -57,7 +57,9 @@ format.default.margin.right=0
### Diagram Formatting
### ==================
representation.general.brailleLanguage=DE_BASISSCHRIFT
representation.general.nonexistentDataText=n/a
representation.general.legendKeyword=Legende:
representation.general.maxTitleHeight=2
representation.rasterize.barChart.maxBarThickness=3
representation.rasterize.barChart.minBarThickness=1
......
......@@ -56,7 +56,9 @@ format.default.margin.right=10
### Diagram Formatting
### ==================
representation.general.brailleLanguage=DE_BASISSCHRIFT
representation.general.nonexistentDataText=n/a
representation.general.legendKeyword=Legende:
representation.general.maxTitleHeight=2
representation.rasterize.barChart.maxBarThickness=3
representation.rasterize.barChart.minBarThickness=1
......
......@@ -45,7 +45,9 @@ format.default.margin.right=0
### Diagram Formatting
### ==================
representation.general.brailleLanguage=DE_BASISSCHRIFT
representation.general.nonexistentDataText=n/a
representation.general.legendKeyword=Legende:
representation.general.maxTitleHeight=2
representation.rasterize.barChart.maxBarThickness=3
representation.rasterize.barChart.minBarThickness=1
......
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