diff --git a/bench/bench.R b/bench/bench.R index d10504a13bddf47615899f4c60a76e6479fcd882..0b4ba16e7d385692e5c1e6c8644bc3d912343874 100755 --- a/bench/bench.R +++ b/bench/bench.R @@ -12,7 +12,7 @@ runBenchmarks = any(is.element(args, "generate")) # generates the result file with t threads, results the data frame benchRun = function(n, t) { if (runBenchmarks) { - cmd = paste("java -jar pdfbox-benchmark/target/pdfbox-benchmark-1.0.0.jar", opts, "-t", t, "-rff", n) + cmd = paste("java -jar pdfbox-benchmark/target/pdfbox-benchmark-1.0.2.jar", opts, "-t", t, "-rff", n) print(cmd) system(cmd) } diff --git a/pdfbox-benchmark/pom.xml b/pdfbox-benchmark/pom.xml index eae85c2effa184c970a6473d20692ab8f470153b..e18d8e6fe4cbcb78e5368edcd924d279c4889e2a 100644 --- a/pdfbox-benchmark/pom.xml +++ b/pdfbox-benchmark/pom.xml @@ -2,7 +2,7 @@ xsi:schemaLocation="http://maven.apache.org/POM/4.0.0 http://maven.apache.org/xsd/maven-4.0.0.xsd"> <modelVersion>4.0.0</modelVersion> <artifactId>pdfbox-benchmark</artifactId> - <version>1.0.0</version> + <version>1.0.0-SNAPSHOT</version> <packaging>jar</packaging> <properties> @@ -13,14 +13,14 @@ <parent> <groupId>fi.utu.tech</groupId> <artifactId>pdfbox-suite</artifactId> - <version>1.0.0</version> + <version>1.0.2</version> </parent> <dependencies> <dependency> <groupId>fi.utu.tech</groupId> <artifactId>pdfbox-wrapper</artifactId> - <version>1.0.0</version> + <version>${pdfboxwrapper.version}</version> </dependency> <dependency> <groupId>org.openjdk.jmh</groupId> @@ -45,7 +45,6 @@ <plugin> <groupId>org.apache.maven.plugins</groupId> <artifactId>maven-jar-plugin</artifactId> - <version>3.1.2</version> <configuration> <!-- DO NOT include log4j.properties file in your Jar --> <excludes> @@ -59,20 +58,9 @@ </configuration> </plugin> - <plugin> - <groupId>org.apache.maven.plugins</groupId> - <artifactId>maven-compiler-plugin</artifactId> - <version>3.8.1</version> - <configuration> - <source>${jdk.version}</source> - <target>${jdk.version}</target> - </configuration> - </plugin> - <plugin> <groupId>org.codehaus.mojo</groupId> <artifactId>exec-maven-plugin</artifactId> - <version>1.6.0</version> <executions> <execution> <goals> diff --git a/pdfbox-gui/pom.xml b/pdfbox-gui/pom.xml new file mode 100644 index 0000000000000000000000000000000000000000..770590bedea8866169688e3fc31629701b918949 --- /dev/null +++ b/pdfbox-gui/pom.xml @@ -0,0 +1,92 @@ +<project xmlns="http://maven.apache.org/POM/4.0.0" xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" + xsi:schemaLocation="http://maven.apache.org/POM/4.0.0 http://maven.apache.org/xsd/maven-4.0.0.xsd"> + <modelVersion>4.0.0</modelVersion> + <artifactId>pdfbox-gui</artifactId> + <version>1.0.0-SNAPSHOT</version> + <packaging>jar</packaging> + + <properties> + <project.mainclass>fi.utu.tech.pdfbox.gui.Main</project.mainclass> + </properties> + + <parent> + <groupId>fi.utu.tech</groupId> + <artifactId>pdfbox-suite</artifactId> + <version>1.0.2</version> + </parent> + + <dependencies> + <dependency> + <groupId>fi.utu.tech</groupId> + <artifactId>pdfbox-wrapper</artifactId> + <version>${pdfboxwrapper.version}</version> + </dependency> + <dependency> + <groupId>org.openjfx</groupId> + <artifactId>javafx-base</artifactId> + <version>${javafx.version}</version> + </dependency> + <dependency> + <groupId>org.openjfx</groupId> + <artifactId>javafx-controls</artifactId> + <version>${javafx.version}</version> + </dependency> + </dependencies> + + <build> + <plugins> + <!-- Make a 'fat' jar, that is, jar that contains all its dependencies and runs as is. + See: https://stackoverflow.com/a/57691362 --> + <plugin> + <groupId>org.apache.maven.plugins</groupId> + <artifactId>maven-shade-plugin</artifactId> + <version>3.2.4</version> + <executions> + <execution> + <phase>package</phase> + <goals> + <goal>shade</goal> + </goals> + <configuration> + <createDependencyReducedPom>false</createDependencyReducedPom> + <filters> + <filter> + <artifact>*:*</artifact> + <excludes> + <exclude>module-info.class</exclude> + <exclude>META-INF/*.SF</exclude> + <exclude>META-INF/*.DSA</exclude> + <exclude>META-INF/*.RSA</exclude> + </excludes> + </filter> + </filters> + <transformers> + <transformer implementation="org.apache.maven.plugins.shade.resource.ManifestResourceTransformer"> + <mainClass>${project.mainclass}</mainClass> + </transformer> + </transformers> + </configuration> + </execution> + </executions> + </plugin> + + <!-- Run this app with exec:java --> + <plugin> + <groupId>org.codehaus.mojo</groupId> + <artifactId>exec-maven-plugin</artifactId> + <version>3.0.0</version> + <executions> + <execution> + <goals> + <goal>java</goal> + </goals> + </execution> + </executions> + <configuration> + <skip>false</skip> + <mainClass>${project.mainclass}</mainClass> + </configuration> + </plugin> + </plugins> + </build> +</project> diff --git a/pdfbox-gui/src/main/java/fi/utu/tech/pdfbox/gui/Main.java b/pdfbox-gui/src/main/java/fi/utu/tech/pdfbox/gui/Main.java new file mode 100644 index 0000000000000000000000000000000000000000..2e82e65e61536c91e3bb82cdd3209223f5feff81 --- /dev/null +++ b/pdfbox-gui/src/main/java/fi/utu/tech/pdfbox/gui/Main.java @@ -0,0 +1,7 @@ +package fi.utu.tech.pdfbox.gui; + +public class Main { + public static void main(String[] args) { + MainApp.launch(MainApp.class, args); + } +} diff --git a/pdfbox-gui/src/main/java/fi/utu/tech/pdfbox/gui/MainApp.java b/pdfbox-gui/src/main/java/fi/utu/tech/pdfbox/gui/MainApp.java new file mode 100644 index 0000000000000000000000000000000000000000..b832bb9a5551b87eb1d791690811d5ed28fff356 --- /dev/null +++ b/pdfbox-gui/src/main/java/fi/utu/tech/pdfbox/gui/MainApp.java @@ -0,0 +1,90 @@ +package fi.utu.tech.pdfbox.gui; + +import fi.utu.tech.pdfbox.controls.DocumentView; +import fi.utu.tech.pdfbox.document.*; +import javafx.application.Application; +import javafx.application.Platform; +import javafx.beans.binding.Bindings; +import javafx.scene.Scene; +import javafx.scene.control.Button; +import javafx.scene.control.Label; +import javafx.scene.layout.BorderPane; +import javafx.scene.layout.FlowPane; +import javafx.stage.FileChooser; +import javafx.stage.Screen; +import javafx.stage.Stage; + +import java.io.File; +import java.io.IOException; +import java.util.function.Consumer; + +public class MainApp extends Application { + DocumentView view = new DocumentView(); + + void setDoc(DataSource src) { + view.getDocumentProperty().set( + new CachedDocument(new PDFDocument((int) view.getFitWidth() * 2, (int) view.getFitHeight() * 2, src, null), 3) + ); + } + + void openFile() { + singleFileDialog("Select PDF file", "PDF file", "pdf", false, f -> + setDoc(new FileSource(f)) + ); + } + + public void singleFileDialog(String title, String type, String ext, boolean saveDialog, Consumer<File> handler) { + FileChooser chooser = new FileChooser(); + chooser.getExtensionFilters().add(new FileChooser.ExtensionFilter(type + " (." + ext + ")", "*." + ext)); + chooser.setTitle(title); + File selected; + if (saveDialog) { + selected = chooser.showSaveDialog(null); + if (selected == null) return; + String file = selected.getAbsolutePath(); + if (!file.endsWith("." + ext)) + file += "." + ext; + selected = new File(file); + } else { + selected = chooser.showOpenDialog(null); + } + if (selected == null) return; + handler.accept(selected); + } + + @Override + public void start(Stage stage) throws IOException { + var prev = new Button("Previous"); + prev.setOnAction(e -> view.prev()); + + var next = new Button("Next"); + next.setOnAction(e -> view.next()); + + var open = new Button("Open"); + open.setOnAction(e -> openFile()); + + var exit = new Button("Exit"); + exit.setOnAction(e -> Platform.exit()); + + var pages = new Label(); + pages.textProperty().bind(Bindings.concat( + "Page ", view.getPageProperty(), " / ", view.getPageCountProperty() + )); + + var pane = new BorderPane(view); + var controls = new FlowPane(prev, next, open, exit, pages); + pane.setBottom(controls); + view.fitWidthProperty().bind(pane.widthProperty()); + view.fitHeightProperty().bind(pane.heightProperty().subtract(controls.heightProperty())); + view.setPreserveRatio(true); + + stage.setTitle("PDF viewer"); + stage.setScene(new Scene(pane)); + var screen = Screen.getScreens().get(0).getBounds(); + stage.setWidth(screen.getWidth() * 2 / 3); + stage.setHeight(screen.getHeight() * 2 / 3); + stage.show(); + + setDoc(new ResourceSource("/presentation.pdf")); + } +} diff --git a/pdfbox-gui/src/main/java/module-info.java b/pdfbox-gui/src/main/java/module-info.java new file mode 100644 index 0000000000000000000000000000000000000000..5e5960295552e64076d62b9cc0a97b44ec1c4dc8 --- /dev/null +++ b/pdfbox-gui/src/main/java/module-info.java @@ -0,0 +1,7 @@ +module fi.utu.tech.pdfbox.gui { + requires transitive javafx.base; + requires transitive javafx.controls; + requires fi.utu.tech.pdfbox; + exports fi.utu.tech.pdfbox.gui; + opens fi.utu.tech.pdfbox.gui; +} diff --git a/pdfbox-gui/src/main/resources/presentation.pdf b/pdfbox-gui/src/main/resources/presentation.pdf new file mode 100644 index 0000000000000000000000000000000000000000..3296b851ea93706b4aecebb4b3dc609cf4d5f329 Binary files /dev/null and b/pdfbox-gui/src/main/resources/presentation.pdf differ diff --git a/pdfbox-wrapper/pom.xml b/pdfbox-wrapper/pom.xml index 569bcdb048c29b48b7d89b173a19c09e3ac0afe0..9c9e052791bba9f2b401151dc8afc644c87cf354 100644 --- a/pdfbox-wrapper/pom.xml +++ b/pdfbox-wrapper/pom.xml @@ -2,13 +2,13 @@ xsi:schemaLocation="http://maven.apache.org/POM/4.0.0 http://maven.apache.org/xsd/maven-4.0.0.xsd"> <modelVersion>4.0.0</modelVersion> <artifactId>pdfbox-wrapper</artifactId> - <version>1.0.0</version> + <version>1.0.2</version> <packaging>jar</packaging> <parent> <groupId>fi.utu.tech</groupId> <artifactId>pdfbox-suite</artifactId> - <version>1.0.0</version> + <version>1.0.2</version> </parent> <dependencies> diff --git a/pdfbox-wrapper/src/main/java/fi/utu/tech/pdfbox/controls/DocumentView.kt b/pdfbox-wrapper/src/main/java/fi/utu/tech/pdfbox/controls/DocumentView.kt new file mode 100644 index 0000000000000000000000000000000000000000..d0d0c66b31b9fa65aa6219071b124f3b7f0f0a37 --- /dev/null +++ b/pdfbox-wrapper/src/main/java/fi/utu/tech/pdfbox/controls/DocumentView.kt @@ -0,0 +1,51 @@ +package fi.utu.tech.pdfbox.controls + +import fi.utu.tech.pdfbox.document.Document +import fi.utu.tech.pdfbox.document.RenderedPage +import javafx.application.Platform +import javafx.beans.Observable +import javafx.beans.property.SimpleIntegerProperty +import javafx.beans.property.SimpleObjectProperty +import javafx.scene.image.ImageView + +open class DocumentView : ImageView { + val documentProperty = SimpleObjectProperty<Document>() + val pageProperty = SimpleIntegerProperty(0) + val pageCountProperty = SimpleIntegerProperty(0) + + constructor() : this(null) + + constructor(document: Document?) { + documentProperty.set(document) + documentProperty.addListener(::reload) + pageProperty.addListener(::reload) + document?.let { reload(null) } + } + + fun next() { + documentProperty.get()?.let { + pageProperty.set(Math.min(it.pageCount(), pageProperty.get() + 1)) + } + } + + fun prev() { + documentProperty.get()?.let { + pageProperty.set(Math.max(0, pageProperty.get() - 1)) + } + } + + open fun renderCallback(page: RenderedPage) { + Platform.runLater { + image = page.image + } + } + + protected fun reload(e: Observable?) { + documentProperty.get()?.let { + pageCountProperty.set(it.pageCount()) + val page = pageProperty.get() + if (it.pageCount() > page && page >= 0) + it.render(page).rendered.thenAccept(::renderCallback) + } + } +} \ No newline at end of file diff --git a/pdfbox-wrapper/src/main/java/fi/utu/tech/pdfbox/document/DataSource.kt b/pdfbox-wrapper/src/main/java/fi/utu/tech/pdfbox/document/DataSource.kt new file mode 100644 index 0000000000000000000000000000000000000000..d69227688a7d35cbf9e2eae0f193c57c606bba16 --- /dev/null +++ b/pdfbox-wrapper/src/main/java/fi/utu/tech/pdfbox/document/DataSource.kt @@ -0,0 +1,22 @@ +package fi.utu.tech.pdfbox.document + +import java.io.File +import java.nio.file.Files +import java.nio.file.Path +import java.nio.file.Paths + +abstract class DataSource { + abstract fun load(): ByteArray +} + +data class FileSource(val path: Path) : DataSource() { + constructor(path: String) : this(Paths.get(path)) + + constructor(file: File) : this(file.toPath()) + + override fun load() = Files.readAllBytes(path)!! +} + +data class ResourceSource(val path: String) : DataSource() { + override fun load() = javaClass.getResourceAsStream(path).readAllBytes()!! +} \ No newline at end of file diff --git a/pdfbox-wrapper/src/main/java/fi/utu/tech/pdfbox/document/Document.kt b/pdfbox-wrapper/src/main/java/fi/utu/tech/pdfbox/document/Document.kt index f5443c9af8a8a9b49419f98443ce3d0d2ab55984..27a1c086f97d8bb54ce63b37e161a54516f78c19 100644 --- a/pdfbox-wrapper/src/main/java/fi/utu/tech/pdfbox/document/Document.kt +++ b/pdfbox-wrapper/src/main/java/fi/utu/tech/pdfbox/document/Document.kt @@ -6,7 +6,6 @@ import org.apache.pdfbox.rendering.ImageType import org.apache.pdfbox.rendering.PDFRenderer import java.util.concurrent.CompletableFuture import java.util.concurrent.Executor -import java.util.function.Supplier abstract class Document( val requestWidth: Int, @@ -45,10 +44,10 @@ abstract class Document( val fxImage = SwingFXUtils.toFXImage(swingImage, null) - //println("Requested: " + requestWidth + "x" + requestHeight) - //println("Size: " + widthPt + "x" + heightPt) - //println("Got: " + swingImage.width + "x" + swingImage.height) - //println("Scale: " + scale) + println("Requested: " + requestWidth + "x" + requestHeight) + println("Size: " + widthPt + "x" + heightPt) + println("Got: " + swingImage.width + "x" + swingImage.height) + println("Scale: " + scale) RenderedPage( swingImage.width, @@ -61,7 +60,7 @@ abstract class Document( val renderedPage = if (executor == null) CompletableFuture.supplyAsync { renderNow(pageIdx) } else - CompletableFuture.supplyAsync(Supplier { renderNow(pageIdx) }, executor) + CompletableFuture.supplyAsync({ renderNow(pageIdx) }, executor) return PageData(pageIdx, caption(pageIdx), renderedPage) } diff --git a/pdfbox-wrapper/src/main/java/fi/utu/tech/pdfbox/document/PDFDocument.kt b/pdfbox-wrapper/src/main/java/fi/utu/tech/pdfbox/document/PDFDocument.kt index 15f98087f3ae7f80abf1548a2f7216dd3bcf07b2..f2289ef847b3c84a4f59b6ef9a3fe62b44196236 100644 --- a/pdfbox-wrapper/src/main/java/fi/utu/tech/pdfbox/document/PDFDocument.kt +++ b/pdfbox-wrapper/src/main/java/fi/utu/tech/pdfbox/document/PDFDocument.kt @@ -1,16 +1,13 @@ package fi.utu.tech.pdfbox.document import org.apache.pdfbox.pdmodel.PDDocument -import java.nio.file.Files -import java.nio.file.Path -import java.nio.file.Paths import java.util.concurrent.Executor class PDFDocument( requestWidth: Int, requestHeight: Int, private var documentData: ByteArray, - val docPath: Path? = null, + val source: DataSource? = null, executor: Executor? = null ) : Document(requestWidth, requestHeight, executor) { @@ -22,23 +19,18 @@ class PDFDocument( constructor( requestWidth: Int, requestHeight: Int, - docPath: Path, + source: DataSource, executor: Executor? = null - ) : this(requestWidth, requestHeight, Files.readAllBytes(docPath), docPath, executor) - - constructor( - requestWidth: Int, - requestHeight: Int, - docPath: String, - executor: Executor? = null - ) : this(requestWidth, requestHeight, Paths.get(docPath), executor) + ) : this(requestWidth, requestHeight, source.load(), source, executor) override fun refresh() { - docPath?.let { documentData = Files.readAllBytes(docPath) } - pageCount = parsePageCount() + source?.let { + documentData = it.load() + pageCount = parsePageCount() + } } - override fun resize(width: Int, height: Int) = PDFDocument(width, height, documentData, docPath) + override fun resize(width: Int, height: Int) = PDFDocument(width, height, documentData, source, executor) override fun documentData(pageIdx: Int) = documentData diff --git a/pdfbox-wrapper/src/main/java/fi/utu/tech/pdfbox/document/Page.kt b/pdfbox-wrapper/src/main/java/fi/utu/tech/pdfbox/document/Page.kt new file mode 100644 index 0000000000000000000000000000000000000000..af497bc0aee9d641650983a2acb13f5ff6dd084d --- /dev/null +++ b/pdfbox-wrapper/src/main/java/fi/utu/tech/pdfbox/document/Page.kt @@ -0,0 +1,7 @@ +package fi.utu.tech.pdfbox.document + +interface Page<X : Page<X>> : Comparable<X>{ + val pageNum: Int + + override fun compareTo(other: X) = pageNum.compareTo(other.pageNum) +} \ No newline at end of file diff --git a/pdfbox-wrapper/src/main/java/fi/utu/tech/pdfbox/document/PageData.kt b/pdfbox-wrapper/src/main/java/fi/utu/tech/pdfbox/document/PageData.kt index 7706f953cca36049e1199614539c650a4dc162ba..9ac12914ba6412d90aaadc0002c277fe14ba3f75 100644 --- a/pdfbox-wrapper/src/main/java/fi/utu/tech/pdfbox/document/PageData.kt +++ b/pdfbox-wrapper/src/main/java/fi/utu/tech/pdfbox/document/PageData.kt @@ -3,9 +3,7 @@ package fi.utu.tech.pdfbox.document import java.util.concurrent.CompletableFuture data class PageData( - val pageNum: Int, + override val pageNum: Int, val caption: String, val rendered: CompletableFuture<RenderedPage> -) : Comparable<PageData> { - override fun compareTo(other: PageData) = pageNum.compareTo(other.pageNum) -} \ No newline at end of file +) : Page<PageData> \ No newline at end of file diff --git a/pdfbox-wrapper/src/main/java/module-info.java b/pdfbox-wrapper/src/main/java/module-info.java index 3e0e776d54e9f70fc414cb84e6e253f4a78dba77..44855b04b8d986fd71fc251b09b7a26bf03a022b 100644 --- a/pdfbox-wrapper/src/main/java/module-info.java +++ b/pdfbox-wrapper/src/main/java/module-info.java @@ -1,8 +1,10 @@ module fi.utu.tech.pdfbox { - requires kotlin.stdlib; - requires org.apache.pdfbox; - requires transitive javafx.base; - requires transitive javafx.swing; - exports fi.utu.tech.pdfbox.document; - exports fi.utu.tech.pdfbox.utils; + requires kotlin.stdlib; + requires org.apache.pdfbox; + requires java.desktop; + requires javafx.swing; + requires transitive javafx.base; + exports fi.utu.tech.pdfbox.document; + exports fi.utu.tech.pdfbox.utils; + exports fi.utu.tech.pdfbox.controls; } diff --git a/pom.xml b/pom.xml index fd790760213cf83bad395ff91216f3677f2f15d2..e50d0e7bee292c6d26bd059eb18bd3ec7a0f7830 100644 --- a/pom.xml +++ b/pom.xml @@ -3,21 +3,22 @@ <modelVersion>4.0.0</modelVersion> <groupId>fi.utu.tech</groupId> <artifactId>pdfbox-suite</artifactId> - <version>1.0.0</version> + <version>1.0.2</version> <packaging>pom</packaging> <properties> <jdk.version>11</jdk.version> -<!-- <kotlin.version>1.3.72</kotlin.version>--> - <kotlin.version>1.4.0-rc</kotlin.version> - <javafx.version>14.0.1</javafx.version> + <kotlin.version>1.4.30</kotlin.version> + <javafx.version>15.0.1</javafx.version> <project.build.sourceEncoding>UTF-8</project.build.sourceEncoding> - <pdfbox.version>2.0.20</pdfbox.version> + <pdfbox.version>2.0.22</pdfbox.version> + <pdfboxwrapper.version>1.0.2</pdfboxwrapper.version> </properties> <modules> <module>pdfbox-wrapper</module> <module>pdfbox-benchmark</module> + <module>pdfbox-gui</module> </modules> <repositories> @@ -26,11 +27,6 @@ <name>Central Repository</name> <url>https://repo.maven.apache.org/maven2</url> </repository> - <repository> - <id>jcenter</id> - <name>jcenter</name> - <url>https://jcenter.bintray.com/</url> - </repository> </repositories> <build> @@ -38,7 +34,7 @@ <plugin> <groupId>org.codehaus.mojo</groupId> <artifactId>exec-maven-plugin</artifactId> - <version>1.6.0</version> + <version>3.0.0</version> <executions> <execution> <goals> @@ -54,7 +50,7 @@ <plugin> <groupId>org.apache.maven.plugins</groupId> <artifactId>maven-jar-plugin</artifactId> - <version>3.1.2</version> + <version>3.2.0</version> <configuration> <!-- DO NOT include log4j.properties file in your Jar --> <excludes> @@ -93,7 +89,7 @@ <extension> <groupId>org.apache.maven.wagon</groupId> <artifactId>wagon-ssh</artifactId> - <version>3.3.3</version> + <version>3.4.1</version> </extension> </extensions> </build>