Skip to content
Snippets Groups Projects
Commit 05028084 authored by Georg Graßnick's avatar Georg Graßnick :thinking:
Browse files

Merge branch 'feat/libluis_bin' into 'master'

Feat/libluis bin

See merge request !35
parents a8c8e3ac e043535d
No related branches found
No related tags found
1 merge request!35Feat/libluis bin
......@@ -22,3 +22,8 @@ src/main/resources/mapping/liblouis
# Exported SVG files
*.svg
# Native libraries
*.so
*.dylib
*.dll
[submodule "third_party/liblouis"]
path = third_party/liblouis
url = https://github.com/liblouis/liblouis
[submodule "third_party/liblouis_bin"]
path = third_party/liblouis_bin
url = ../../brailleplot/liblouis_bin.git
......@@ -68,6 +68,23 @@ clean {
delete "$rootDir/src/main/resources/mapping/liblouis"
}
// Copy native liblouis libraries for major platforms to the resource folder
task copyLibLouisBinary(type: Copy) {
from "$projectDir/third_party/liblouis_bin/bin/"
into "$rootDir/src/main/resources/native/liblouis"
}
processResources.dependsOn copyLibLouisBinary
// Abort if files are missing
gradle.taskGraph.afterTask { copyLibLouisBinary ->
if(copyLibLouisBinary.state.noSource){
throw new GradleException("Could not find liblouis native libraries in \"$projectDir/third_party/liblouis_bin/bin/\". Please make sure you updated all git submodules using \"git submodule update --init --recursive\" ")
}
}
// Delete libraries on "clean" task
clean {
delete "$rootDir/src/main/resources/native/liblouis"
}
// Define the main class for the application
mainClassName = 'de.tudresden.inf.mci.brailleplot.App'
......
......@@ -153,8 +153,6 @@ public final class App {
try {
// Logging example
mLogger.info("Application started");
// Needed for Windows machines
System.setProperty("jna.library.path", System.getProperty("user.dir") + "/third_party");
// Parse command line parameters
CommandLineParser cliParser = new CommandLineParser();
SettingsWriter settings = cliParser.parse(args);
......@@ -198,6 +196,7 @@ public final class App {
barChart.setYAxisName("Länge in m");
// Render diagram
LiblouisBrailleTextRasterizer.initModule();
MasterRenderer renderer = new MasterRenderer(indexV4Printer, representationParameters, a4Format);
RasterCanvas canvas = renderer.rasterize(barChart);
// SVG exporting
......
......@@ -8,8 +8,11 @@ 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.printerbackend.NotSupportedFileExtensionException;
import de.tudresden.inf.mci.brailleplot.util.NativeLibraryHelper;
import de.tudresden.inf.mci.brailleplot.util.NoSuchNativeLibraryException;
import org.liblouis.DisplayException;
import org.liblouis.DisplayTable;
import org.liblouis.Louis;
import org.liblouis.TranslationException;
import org.liblouis.TranslationResult;
import org.liblouis.Translator;
......@@ -27,6 +30,8 @@ import static java.lang.Math.ceil;
public class LiblouisBrailleTextRasterizer implements Rasterizer<BrailleText> {
private static boolean mNativeLibInitialized = false;
private AbstractBrailleTableParser mParser;
// Parameters for rasterizing
private int x;
......@@ -241,4 +246,33 @@ public class LiblouisBrailleTextRasterizer implements Rasterizer<BrailleText> {
mTranslator = temp;
return length;
}
/**
* Initializes the Module.
* @throws LibLouisLibraryMissingException If liblouis could not be loaded from neither the jar or the default JNI include path.
*/
public static void initModule() throws LibLouisLibraryMissingException {
if (!mNativeLibInitialized) {
try {
NativeLibraryHelper.loadNativeLibrary("liblouis");
} catch (NoSuchNativeLibraryException e) {
// Even if the library is not distributed within the jar file, it might be installed on the system.
}
try {
Louis.getVersion();
} catch (java.lang.UnsatisfiedLinkError e) {
throw new LibLouisLibraryMissingException(e);
}
mNativeLibInitialized = true;
}
}
/**
* Indicates, the native liblouis library was not found.
*/
public static class LibLouisLibraryMissingException extends NoSuchNativeLibraryException {
LibLouisLibraryMissingException(final Throwable cause) {
super(cause);
}
}
}
package de.tudresden.inf.mci.brailleplot.util;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;
import java.io.File;
/**
* This class offers static methods for native library loading purposes.
* @author Georg Graßnick
* @version 2019.09.26
*/
public final class NativeLibraryHelper {
private static final Logger LOG = LoggerFactory.getLogger(NativeLibraryHelper.class);
private static final String LIB_PATH = calculateLibPath();
private NativeLibraryHelper() { }
/**
* Loads a library from the resources according to the current system architecture and operating system.
* @param libName The name of the library. Library prefixes ({@literal "}lib{@literal "}) are not treated separately.
* The system specific file ending is added automatically and must not be included in the parameter.
* @return A File object representing the file of the library. The JNI is automatically set up to take of the library,
* so there is most likely no need for this return value.
* @throws NoSuchNativeLibraryException If the requested library could not be found or read.
*/
public static synchronized File loadNativeLibrary(final String libName) throws NoSuchNativeLibraryException {
File libFile;
try {
String libPath = "native/" + libName + "/" + LIB_PATH + "/" + libName + dynamicLibFileEnding();
libFile = GeneralResource.getOrExportResourceFile(libPath).getAbsoluteFile();
registerNewSystemLibPath(libFile.getParent());
} catch (Exception e) {
throw new NoSuchNativeLibraryException("Could not provide native library from java resources", e);
}
LOG.debug("Found and exported native library \"" + libFile + "\" for requested library \"" + libName + "\"");
return libFile;
}
/**
* Adds a path in the file system to the search path of the JNI.
* @param path The path to add.
*/
private static synchronized void registerNewSystemLibPath(final String path) {
String currentLibPath = System.getProperty("jna.library.path");
String newLibPath = null;
boolean pathExists = false;
if (currentLibPath == null) {
newLibPath = path;
} else {
// Do not insert path if it already is included
String[] existingPaths = currentLibPath.split(File.pathSeparator);
for (String s : existingPaths) {
if (s.equals(path)) {
pathExists = true;
break;
}
}
newLibPath = currentLibPath + File.pathSeparator + path;
}
if (!pathExists) {
LOG.debug("Setting JNI library path property to \"" + newLibPath + "\"");
System.setProperty("jna.library.path", newLibPath);
}
}
private static String calculateLibPath() {
return getArch() + "/" + getOs();
}
private static String getArch() {
String arch = System.getProperty("os.arch");
// reference: https://stackoverflow.com/a/36926327
switch (arch) {
case "x86":
case "i386":
case "i486":
case "i586":
case "i686":
return "x86_32";
case "x86_64":
case "amd64":
return "x86_64";
default:
throw new RuntimeException("Operating System architecture \"" + arch + "\" is currently not supported");
}
}
private static String getOs() {
String name = System.getProperty("os.name");
String nameLow = name.toLowerCase();
if (nameLow.contains("linux")) {
return "linux";
} else if (nameLow.contains("mac")) {
return "osx";
} else if (nameLow.contains("win")) {
return "win32";
} else {
throw new RuntimeException("Operating System \"" + name + "\" is currently not supported");
}
}
private static String dynamicLibFileEnding() {
switch (getOs()) {
case "win32":
return ".dll";
case "linux":
return ".so";
case "osx":
return ".dylib";
default:
throw new IllegalStateException("If this exception was thrown, something is wrong with your code");
}
}
}
package de.tudresden.inf.mci.brailleplot.util;
/**
* Indicates, some error has occurred while trying to load a native library from the java resources.
* @author Georg Graßnick
* @version 2019.09.26
*/
public class NoSuchNativeLibraryException extends RuntimeException {
public NoSuchNativeLibraryException() { }
public NoSuchNativeLibraryException(final String message) {
super(message);
}
public NoSuchNativeLibraryException(final Throwable cause) {
super(cause);
}
public NoSuchNativeLibraryException(final String message, final Throwable cause) {
super(message, cause);
}
}
Subproject commit 24b6908d0b167ce785c0f9ce8295d9845b69a303
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