Indentations break the feed.
[SquirrelJME.git] / tools / squirreljme-font / build.gradle
blobf490731e197ba578ef7f8f871519edab2a85016e
1 import cc.squirreljme.plugin.tasks.MimeDecodeResourcesTask
2 import cc.squirreljme.plugin.util.GradleLoggerOutputStream
3 import cc.squirreljme.plugin.util.JavaExecSpecFiller
4 import cc.squirreljme.plugin.util.SimpleJavaExecSpecFiller
5 import lombok.Getter
7 import javax.inject.Inject
8 import java.nio.file.Files
9 import java.nio.file.StandardCopyOption
10 import java.nio.file.StandardOpenOption
12 plugins {
13         id "java"
14         id "application"
17 apply plugin: "com.github.johnrengelman.shadow"
19 description = "SquirrelJME Font Compiler."
20 mainClassName = "cc.squirreljme.fontcompile.Main"
22 tasks.register("mimeDecode", MimeDecodeResourcesTask.class,
23         "main",
24         tasks.named("processResources").get(),
25         tasks.named("clean").get())
27 processResources.dependsOn("mimeDecode")
28 jar.dependsOn("mimeDecode")
30 dependencies {
31         implementation project(":emulators:emulator-base")
32         implementation project(":modules:cldc-compact")
33         implementation project(":tools:c-source-writer")
34         implementation project(":modules:io")
35         implementation project(":modules:io-file")
36         implementation project(":modules:zip")
37         
38         // Lombok for simpler getters/setters
39         implementation 'org.projectlombok:lombok:1.18.30'
40         annotationProcessor 'org.projectlombok:lombok:1.18.30'
43 class CompileFontTask extends DefaultTask {
44         /** The font path. */
45         @Getter
46         @Internal
47         final java.nio.file.Path fontPath
48         
49         /** The output path. */
50         @Getter
51         @Internal
52         final java.nio.file.Path compiledPath
53         
54         /** Writing C source? */
55         @Getter
56         @Internal
57         final boolean cSource
58         
59         @Inject
60         public CompileFontTask(String __pathy, String __outName,
61                 boolean __cSource) {
62                 if (__pathy == null || __outName == null) {
63                         throw new NullPointerException("No path.")
64                 }
65                 
66                 this.group = "squirreljme"
67                 this.description = "Compiles font ${__pathy}."
68                 
69                 this.cSource = __cSource
70                 
71                 // Clean must always be done first
72                 this.mustRunAfter(this.project.provider({ ->
73                         this.project.tasks.named("clean")}))
74                 
75                 // We need the actual program first
76                 Provider<Task> shadowTask = this.project.provider({ ->
77                         this.project.tasks.getByName("shadowJar")})
78                 this.dependsOn(shadowTask)
79                 
80                 // Determine where the font is
81                 java.nio.file.Path fontPath = this.project.rootProject.rootDir
82                         .toPath().resolve("assets").resolve("font").resolve(__pathy)
83                 this.fontPath = fontPath
84                 
85                 // Where does this go?
86                 java.nio.file.Path compiledPath = this.project.buildDir.toPath()
87                         .resolve("fonts").resolve(__outName + (__cSource ? ".c" : ".zip"))
88                 this.compiledPath = compiledPath
89                 
90                 // Make the shadow Jar input for the task just to make sure that
91                 // is up to date!
92                 this.inputs.file(this.project.provider({ ->
93                         shadowTask.get().outputs.files.singleFile}))
94                 
95                 // Set font data as input
96                 if (Files.isDirectory(fontPath)) {
97                         this.inputs.dir(fontPath)
98                 } else {
99                         this.inputs.file(fontPath)
100                 }
101                 
102                 // Compiled output is an output for this
103                 this.outputs.file(compiledPath)
104                 
105                 this.doFirst({Task tasky ->
106                         java.nio.file.Path temp = null
107                         try {
108                                 // Write to a temporary file first to keep things clean
109                                 temp = Files.createTempFile("font", ".sqf")
110                                 
111                                 // Setup task for execution then execute it
112                                 ExecResult exitResult
113                                 try (OutputStream out = Files.newOutputStream(
114                                         temp, StandardOpenOption.WRITE,
115                                         StandardOpenOption.CREATE,
116                                         StandardOpenOption.TRUNCATE_EXISTING)) {
117                                         exitResult = tasky.project.javaexec(
118                                                 { JavaExecSpec spec ->
119                                                         // Use the output Jar
120                                                         spec.classpath(
121                                                                 shadowTask.get().outputs.files.singleFile)
122                                                         spec.main("cc.squirreljme.fontcompile.Main")
123                                                         
124                                                         // Input and output
125                                                         spec.args(fontPath.toAbsolutePath().toString(),
126                                                                 (__cSource ? "-.c" : "-"))
127                                                         
128                                                         // Use these streams directly
129                                                         spec.setStandardOutput(out)
130                                                         spec.setErrorOutput(new GradleLoggerOutputStream(
131                                                                 tasky.getLogger(), LogLevel.ERROR,
132                                                                 -1, -1))
133                                                 })
134                                 }
135                                         
136                                 // Did the task fail?
137                                 int exitValue = exitResult.getExitValue()
138                                 if (exitValue != 0)
139                                         throw new RuntimeException(
140                                                 String.format("Task exited with: %d %08x", exitValue, exitValue))
141                                 
142                                 // Move it over
143                                 Files.createDirectories(compiledPath.getParent())
144                                 Files.move(temp, compiledPath,
145                                         StandardCopyOption.REPLACE_EXISTING)
146                         } finally {
147                                 Files.deleteIfExists(temp)
148                         }
149                 })
150         }
153 // Generic task to compile all fonts
154 TaskProvider<Task> compileFonts = tasks.register("compileFonts") {
155         this.group = "squirreljme"
156         this.description = "Compiles all fonts."
159 for (String fn in [
160         "monospace.sfdir/8.strike",
161         "monospace.sfdir/12.strike",
162         "monospace.sfdir/16.strike",
163         "sansserif.sfdir/8.strike",
164         "sansserif.sfdir/12.strike",
165         "sansserif.sfdir/16.strike",
166         "serif.sfdir/8.strike",
167         "serif.sfdir/12.strike",
168         "serif.sfdir/16.strike",
169         "misaki8.bdf",
170         "misaki12.bdf",
171         "unifont16.bdf",
172         "unifont-upper16.bdf"]) {
173         // Determine a better name for it
174         String shortish = fn.substring(0, 1).toUpperCase() + fn.replaceAll(
175                 "(\\.sfdir|\\.strike|\\.bdf|/)", "").substring(1)
176         
177         // Register base SQF compiler
178         TaskProvider<Task> compileFont = tasks.register("compileFont${shortish}",
179                 CompileFontTask.class,
180                 fn, shortish.toLowerCase(Locale.ROOT), false)
181         
182         // Include all SQFs in the default compile
183         compileFonts.get().dependsOn(compileFont)
184         
185         // Add source code compilation
186         tasks.register("sourceFont${shortish}",
187                 CompileFontTask.class,
188                 fn, shortish.toLowerCase(Locale.ROOT), true)