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
7 import javax.inject.Inject
8 import java.nio.file.Files
9 import java.nio.file.StandardCopyOption
10 import java.nio.file.StandardOpenOption
17 apply plugin: "com.github.johnrengelman.shadow"
19 description = "SquirrelJME Font Compiler."
20 mainClassName = "cc.squirreljme.fontcompile.Main"
22 tasks.register("mimeDecode", MimeDecodeResourcesTask.class,
24 tasks.named("processResources").get(),
25 tasks.named("clean").get())
27 processResources.dependsOn("mimeDecode")
28 jar.dependsOn("mimeDecode")
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")
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 {
47 final java.nio.file.Path fontPath
49 /** The output path. */
52 final java.nio.file.Path compiledPath
54 /** Writing C source? */
60 public CompileFontTask(String __pathy, String __outName,
62 if (__pathy == null || __outName == null) {
63 throw new NullPointerException("No path.")
66 this.group = "squirreljme"
67 this.description = "Compiles font ${__pathy}."
69 this.cSource = __cSource
71 // Clean must always be done first
72 this.mustRunAfter(this.project.provider({ ->
73 this.project.tasks.named("clean")}))
75 // We need the actual program first
76 Provider<Task> shadowTask = this.project.provider({ ->
77 this.project.tasks.getByName("shadowJar")})
78 this.dependsOn(shadowTask)
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
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
90 // Make the shadow Jar input for the task just to make sure that
92 this.inputs.file(this.project.provider({ ->
93 shadowTask.get().outputs.files.singleFile}))
95 // Set font data as input
96 if (Files.isDirectory(fontPath)) {
97 this.inputs.dir(fontPath)
99 this.inputs.file(fontPath)
102 // Compiled output is an output for this
103 this.outputs.file(compiledPath)
105 this.doFirst({Task tasky ->
106 java.nio.file.Path temp = null
108 // Write to a temporary file first to keep things clean
109 temp = Files.createTempFile("font", ".sqf")
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
121 shadowTask.get().outputs.files.singleFile)
122 spec.main("cc.squirreljme.fontcompile.Main")
125 spec.args(fontPath.toAbsolutePath().toString(),
126 (__cSource ? "-.c" : "-"))
128 // Use these streams directly
129 spec.setStandardOutput(out)
130 spec.setErrorOutput(new GradleLoggerOutputStream(
131 tasky.getLogger(), LogLevel.ERROR,
136 // Did the task fail?
137 int exitValue = exitResult.getExitValue()
139 throw new RuntimeException(
140 String.format("Task exited with: %d %08x", exitValue, exitValue))
143 Files.createDirectories(compiledPath.getParent())
144 Files.move(temp, compiledPath,
145 StandardCopyOption.REPLACE_EXISTING)
147 Files.deleteIfExists(temp)
153 // Generic task to compile all fonts
154 TaskProvider<Task> compileFonts = tasks.register("compileFonts") {
155 this.group = "squirreljme"
156 this.description = "Compiles all fonts."
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",
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)
177 // Register base SQF compiler
178 TaskProvider<Task> compileFont = tasks.register("compileFont${shortish}",
179 CompileFontTask.class,
180 fn, shortish.toLowerCase(Locale.ROOT), false)
182 // Include all SQFs in the default compile
183 compileFonts.get().dependsOn(compileFont)
185 // Add source code compilation
186 tasks.register("sourceFont${shortish}",
187 CompileFontTask.class,
188 fn, shortish.toLowerCase(Locale.ROOT), true)