Add (very simple) PDF renderer.
	
		
			
	
		
	
	
		
	
		
			Some checks failed
		
		
	
	
		
			
				
	
				continuous-integration/drone/push Build is failing
				
			
		
		
	
	
				
					
				
			
		
			Some checks failed
		
		
	
	continuous-integration/drone/push Build is failing
				
			This commit is contained in:
		
							parent
							
								
									5d07cfe1fc
								
							
						
					
					
						commit
						93dd5a26fa
					
				
					 4 changed files with 209 additions and 2 deletions
				
			
		
							
								
								
									
										5
									
								
								pom.xml
									
										
									
									
									
								
							
							
						
						
									
										5
									
								
								pom.xml
									
										
									
									
									
								
							|  | @ -25,6 +25,11 @@ | |||
| 			<groupId>io.vavr</groupId> | ||||
| 			<artifactId>vavr</artifactId> | ||||
| 		</dependency> | ||||
| 		<dependency> | ||||
| 			<groupId>org.apache.pdfbox</groupId> | ||||
| 			<artifactId>pdfbox</artifactId> | ||||
| 			<version>2.0.20</version> | ||||
| 		</dependency> | ||||
| 		<dependency> | ||||
| 			<groupId>org.junit.jupiter</groupId> | ||||
| 			<artifactId>junit-jupiter-api</artifactId> | ||||
|  |  | |||
|  | @ -7,8 +7,8 @@ import java.nio.file.Paths; | |||
| 
 | ||||
| public class Main { | ||||
|     public static void main(@NonNull final String[] args) { | ||||
|         int width = 80; | ||||
|         int height = 40; | ||||
|         int width = 20; | ||||
|         int height = 20; | ||||
|         final Labyrinth labyrinth = new Labyrinth(width, height); | ||||
|         final TextRenderer textRenderer = TextRenderer.newInstance(); | ||||
|         final HTMLRenderer htmlRenderer = HTMLRenderer.newInstance(); | ||||
|  | @ -18,6 +18,8 @@ public class Main { | |||
|                 .setTargetSolutionFile(userHome.resolve("labyrinth-solution.txt")); | ||||
|         final HTMLFileRenderer htmlFileRenderer = HTMLFileRenderer.newInstance() | ||||
|                 .setTargetFile(userHome.resolve("labyrinth.html")); | ||||
|         final PDFFileRenderer pdfFileRenderer = PDFFileRenderer.newInstance().setTargetFile(userHome.resolve("labyrinth.pdf")); | ||||
| 
 | ||||
|         // Render Labyrinth to stdout | ||||
|         System.out.println(textRenderer.render(labyrinth)); | ||||
|         // Render Labyrinth solution to stdout | ||||
|  | @ -28,5 +30,7 @@ public class Main { | |||
|         System.out.println(textFileRenderer.render(labyrinth)); | ||||
|         // Render HTML to file | ||||
|         System.out.println(htmlFileRenderer.render(labyrinth)); | ||||
|         // Render PDF to file | ||||
|         System.out.println(pdfFileRenderer.render(labyrinth)); | ||||
|     } | ||||
| } | ||||
|  |  | |||
							
								
								
									
										56
									
								
								src/main/java/ch/fritteli/labyrinth/PDFFileRenderer.java
									
										
									
									
									
										Normal file
									
								
							
							
						
						
									
										56
									
								
								src/main/java/ch/fritteli/labyrinth/PDFFileRenderer.java
									
										
									
									
									
										Normal file
									
								
							|  | @ -0,0 +1,56 @@ | |||
| package ch.fritteli.labyrinth; | ||||
| 
 | ||||
| import lombok.NonNull; | ||||
| 
 | ||||
| import java.io.IOException; | ||||
| import java.nio.file.Files; | ||||
| import java.nio.file.Path; | ||||
| 
 | ||||
| public class PDFFileRenderer implements Renderer<Path> { | ||||
|     @NonNull | ||||
|     private static final PDFRenderer PDF_RENDERER = PDFRenderer.newInstance(); | ||||
|     private Path targetFile; | ||||
| 
 | ||||
|     private PDFFileRenderer() { | ||||
|         try { | ||||
|             this.targetFile = Files.createTempFile("labyrinth_", ".pdf"); | ||||
|         } catch (IOException e) { | ||||
|             System.err.println("Unable to set default target file."); | ||||
|             e.printStackTrace(); | ||||
|         } | ||||
|     } | ||||
| 
 | ||||
|     @NonNull | ||||
|     public static PDFFileRenderer newInstance() { | ||||
|         return new PDFFileRenderer(); | ||||
|     } | ||||
| 
 | ||||
|     public boolean isTargetFileDefinedAndWritable() { | ||||
|         return this.targetFile != null && this.targetFile.toFile().canWrite(); | ||||
|     } | ||||
| 
 | ||||
|     @NonNull | ||||
|     public PDFFileRenderer setTargetFile(@NonNull final Path targetFile) { | ||||
|         this.targetFile = targetFile; | ||||
|         return this; | ||||
|     } | ||||
| 
 | ||||
|     @Override | ||||
|     public Path render(@NonNull final Labyrinth labyrinth) { | ||||
|         if (!this.isTargetFileDefinedAndWritable()) { | ||||
|             try { | ||||
|                 Files.createFile(this.targetFile); | ||||
|             } catch (IOException e) { | ||||
|                 throw new IllegalArgumentException("Cannot write to target file.", e); | ||||
|             } | ||||
|         } | ||||
|         final byte[] bytes = PDF_RENDERER.render(labyrinth); | ||||
|         try { | ||||
|             Files.write(this.targetFile, bytes); | ||||
|         } catch (IOException e) { | ||||
|             System.err.println("Failed writing to file " + this.targetFile.normalize().toString()); | ||||
|             e.printStackTrace(); | ||||
|         } | ||||
|         return this.targetFile; | ||||
|     } | ||||
| } | ||||
							
								
								
									
										142
									
								
								src/main/java/ch/fritteli/labyrinth/PDFRenderer.java
									
										
									
									
									
										Normal file
									
								
							
							
						
						
									
										142
									
								
								src/main/java/ch/fritteli/labyrinth/PDFRenderer.java
									
										
									
									
									
										Normal file
									
								
							|  | @ -0,0 +1,142 @@ | |||
| package ch.fritteli.labyrinth; | ||||
| 
 | ||||
| import lombok.NonNull; | ||||
| import org.apache.pdfbox.pdmodel.PDDocument; | ||||
| import org.apache.pdfbox.pdmodel.PDPage; | ||||
| import org.apache.pdfbox.pdmodel.PDPageContentStream; | ||||
| 
 | ||||
| import java.awt.*; | ||||
| import java.io.ByteArrayOutputStream; | ||||
| import java.io.IOException; | ||||
| 
 | ||||
| public class PDFRenderer implements Renderer<byte[]> { | ||||
|     private PDFRenderer() { | ||||
| 
 | ||||
|     } | ||||
| 
 | ||||
|     @NonNull | ||||
|     public static PDFRenderer newInstance() { | ||||
|         return new PDFRenderer(); | ||||
|     } | ||||
| 
 | ||||
|     @Override | ||||
|     @NonNull | ||||
|     public byte[] render(@NonNull final Labyrinth labyrinth) { | ||||
|         final PDDocument pdDocument = new PDDocument(); | ||||
|         final PDPage page = new PDPage(); | ||||
|         pdDocument.addPage(page); | ||||
|         try (PDPageContentStream pdPageContentStream = new PDPageContentStream(pdDocument, page)) { | ||||
|             pdPageContentStream.setLineCapStyle(BasicStroke.CAP_BUTT); | ||||
|             pdPageContentStream.setLineJoinStyle(BasicStroke.JOIN_MITER); | ||||
|             pdPageContentStream.setLineWidth(1.0f); | ||||
|             pdPageContentStream.setStrokingColor(Color.BLACK); | ||||
|             pdPageContentStream.setNonStrokingColor(Color.BLACK); | ||||
|             final float scale = 10; | ||||
|             final float margin = 5; | ||||
|             this.drawHorizonzalLines(labyrinth, pdPageContentStream, margin, scale); | ||||
|             this.drawVerticalLines(labyrinth, pdPageContentStream, margin, scale); | ||||
|         } catch (IOException e) { | ||||
|             e.printStackTrace(); | ||||
|         } | ||||
|         final ByteArrayOutputStream output = new ByteArrayOutputStream(); | ||||
|         try { | ||||
|             pdDocument.save(output); | ||||
|             pdDocument.close(); | ||||
|         } catch (IOException e) { | ||||
|             e.printStackTrace(); | ||||
|         } | ||||
|         return output.toByteArray(); | ||||
|     } | ||||
| 
 | ||||
|     private void drawHorizonzalLines(@NonNull final Labyrinth labyrinth, @NonNull final PDPageContentStream pdPageContentStream, final float margin, final float scale) throws IOException { | ||||
|         for (int y = 0; y < labyrinth.getHeight(); y++) { | ||||
|             boolean isPainting = false; | ||||
|             for (int x = 0; x < labyrinth.getWidth(); x++) { | ||||
|                 final Tile currentTile = labyrinth.getTileAt(x, y); | ||||
|                 if (currentTile.hasWallAt(Direction.TOP)) { | ||||
|                     if (!isPainting) { | ||||
|                         pdPageContentStream.moveTo(x * scale + margin, y * scale + margin); | ||||
|                         isPainting = true; | ||||
|                     } | ||||
|                 } else { | ||||
|                     if (isPainting) { | ||||
|                         pdPageContentStream.lineTo(x * scale + margin, y * scale + margin); | ||||
|                         pdPageContentStream.stroke(); | ||||
|                         isPainting = false; | ||||
|                     } | ||||
|                 } | ||||
|             } | ||||
|             if (isPainting) { | ||||
|                 pdPageContentStream.lineTo(labyrinth.getWidth() * scale + margin, y * scale + margin); | ||||
|                 pdPageContentStream.stroke(); | ||||
|             } | ||||
|         } | ||||
|         boolean isPainting = false; | ||||
|         int y = labyrinth.getHeight(); | ||||
|         for (int x = 0; x < labyrinth.getWidth(); x++) { | ||||
|             final Tile currentTile = labyrinth.getTileAt(x, y - 1); | ||||
|             if (currentTile.hasWallAt(Direction.BOTTOM)) { | ||||
|                 if (!isPainting) { | ||||
|                     pdPageContentStream.moveTo(x * scale + margin, y * scale + margin); | ||||
|                     isPainting = true; | ||||
|                 } | ||||
|             } else { | ||||
|                 if (isPainting) { | ||||
|                     pdPageContentStream.lineTo(x * scale + margin, y * scale + margin); | ||||
|                     pdPageContentStream.stroke(); | ||||
|                     isPainting = false; | ||||
|                 } | ||||
|             } | ||||
|         } | ||||
|         if (isPainting) { | ||||
|             pdPageContentStream.lineTo(labyrinth.getWidth() * scale + margin, labyrinth.getHeight() * scale + margin); | ||||
|             pdPageContentStream.stroke(); | ||||
|         } | ||||
|     } | ||||
| 
 | ||||
|     private void drawVerticalLines(@NonNull final Labyrinth labyrinth, @NonNull final PDPageContentStream pdPageContentStream, final float margin, final float scale) throws IOException { | ||||
|         for (int x = 0; x < labyrinth.getWidth(); x++) { | ||||
|             boolean isPainting = false; | ||||
|             for (int y = 0; y < labyrinth.getHeight(); y++) { | ||||
|                 final Tile currentTile = labyrinth.getTileAt(x, y); | ||||
|                 if (currentTile.hasWallAt(Direction.LEFT)) { | ||||
|                     if (!isPainting) { | ||||
|                         pdPageContentStream.moveTo(x * scale + margin, y * scale + margin); | ||||
|                         isPainting = true; | ||||
|                     } | ||||
|                 } else { | ||||
|                     if (isPainting) { | ||||
|                         pdPageContentStream.lineTo(x * scale + margin, y * scale + margin); | ||||
|                         pdPageContentStream.stroke(); | ||||
|                         isPainting = false; | ||||
|                     } | ||||
|                 } | ||||
|             } | ||||
|             if (isPainting) { | ||||
|                 pdPageContentStream.lineTo(x * scale + margin, labyrinth.getHeight() * scale + margin); | ||||
|                 pdPageContentStream.stroke(); | ||||
|             } | ||||
|         } | ||||
|         boolean isPainting = false; | ||||
|         int x = labyrinth.getWidth(); | ||||
|         for (int y = 0; y < labyrinth.getHeight(); y++) { | ||||
|             final Tile currentTile = labyrinth.getTileAt(x - 1, y); | ||||
|             if (currentTile.hasWallAt(Direction.RIGHT)) { | ||||
|                 if (!isPainting) { | ||||
|                     pdPageContentStream.moveTo(x * scale + margin, y * scale + margin); | ||||
|                     isPainting = true; | ||||
|                 } | ||||
|             } else { | ||||
|                 if (isPainting) { | ||||
|                     pdPageContentStream.lineTo(x * scale + margin, y * scale + margin); | ||||
|                     pdPageContentStream.stroke(); | ||||
|                     isPainting = false; | ||||
|                 } | ||||
|             } | ||||
|         } | ||||
|         if (isPainting) { | ||||
|             pdPageContentStream.lineTo(labyrinth.getWidth() * scale + margin, labyrinth.getHeight() * scale + margin); | ||||
|             pdPageContentStream.stroke(); | ||||
|         } | ||||
|     } | ||||
| } | ||||
		Loading…
	
	Add table
		Add a link
		
	
		Reference in a new issue