├── .gitignore ├── LICENSE ├── README-kotlin.md ├── README.md ├── README.md.src ├── build.gradle.kts ├── gradle.properties ├── gradle └── wrapper │ ├── gradle-wrapper.jar │ └── gradle-wrapper.properties ├── gradlew ├── gradlew.bat ├── settings.gradle.kts └── src ├── main └── kotlin │ └── com │ └── github │ └── blueboxware │ └── gdxplugin │ ├── GdxPlugin.kt │ ├── Utils.kt │ ├── dsl │ ├── BitmapFontSettings.kt │ ├── Constants.kt │ ├── SolidColorSpec.kt │ └── Utils.kt │ ├── tasks │ ├── BitmapFont.kt │ ├── DistanceField.kt │ ├── NinePatch.kt │ └── PackTextures.kt │ └── utils │ └── FontGenerator.kt └── test ├── kotlin ├── ProjectFixture.kt ├── TestBitmapFontTask.kt ├── TestConfigCacheError.kt ├── TestDistanceFieldTask.kt ├── TestEffectsKotlin.kt ├── TestNinePatchTask.kt ├── TestPackTexturesTask.kt ├── TestPlugin.kt ├── TestReadme.kt └── Utils.kt └── testData ├── etc ├── freesans.ttf ├── roboto.ttf └── wat.jpg ├── images1 ├── binary.png ├── deb.png ├── document.png ├── empty.png └── sub │ ├── binary.png │ ├── image.png │ ├── pack.json │ └── subsub │ ├── pack.json │ ├── plan.png │ └── spreadsheet.png ├── images2 ├── add.png ├── back.png ├── bottom.png └── pack.json ├── ninePatch ├── document.png ├── gradient.jpg ├── overlap.png ├── rect.png ├── red.jpg ├── red.png ├── resizable.png └── thingy.png ├── readme ├── fonts │ └── roboto.ttf └── textures │ ├── border.png │ ├── game │ ├── add.png │ ├── document.png │ ├── pack.json │ └── sub │ │ ├── pack.json │ │ ├── plan.png │ │ └── spreadsheet.png │ ├── gameOver │ ├── back.png │ └── bottom.png │ ├── logo.png │ ├── menu │ ├── empty.png │ ├── image.png │ └── pack.json │ ├── pack.json │ ├── rect.png │ ├── title.jpg │ └── title.png └── results ├── bitmapFont ├── arial16px.fnt ├── arial16px.png ├── distanceField.fnt ├── distanceField.png ├── gradient.fnt ├── gradient.png ├── outline.fnt ├── outline.png ├── outlineAndShadow.fnt ├── outlineAndShadow.png ├── roboto32px.fnt ├── roboto32px.png ├── wobble.fnt ├── wobble.png ├── zigzag.fnt └── zigzag.png ├── distanceField ├── df_red.png ├── df_wat.jpg ├── df_white.png └── wat-df.png └── packTextures ├── customSettings ├── pack1Foo.atlas ├── pack1Scaled.jpg ├── pack2Normal2.jpg └── pack2Scaled.atlas ├── customTask.atlas ├── filteringAndRenaming.atlas ├── minimalSpec.atlas ├── minimalSpecAfterDeletingImage.atlas ├── multipleScales1.atlas ├── multipleScales2.atlas ├── multipleScales3.atlas ├── multipleScalesSubdir1.atlas ├── multipleScalesSubdir2.atlas ├── multipleScalesSubdir3.atlas ├── namedContainerPack1.atlas ├── namedContainerPack2.atlas ├── namedContainerPack3.atlas ├── noLegacyOutput.atlas ├── solids.atlas ├── solids.png ├── withAllSettings1.atlas ├── withAllSettings1.jpg ├── withAllSettings2.atlas ├── withAllSettings2.jpg ├── withSettingsAndCustomName.atlas ├── withSettingsAndCustomName2.atlas ├── withSettingsFile.atlas └── withUsePackJson.atlas /.gitignore: -------------------------------------------------------------------------------- 1 | /.idea/ 2 | /out/ 3 | /build/ 4 | /.gradle/ 5 | /testProject/ -------------------------------------------------------------------------------- /LICENSE: -------------------------------------------------------------------------------- 1 | Apache License 2 | Version 2.0, January 2004 3 | http://www.apache.org/licenses/ 4 | 5 | TERMS AND CONDITIONS FOR USE, REPRODUCTION, AND DISTRIBUTION 6 | 7 | 1. Definitions. 8 | 9 | "License" shall mean the terms and conditions for use, reproduction, 10 | and distribution as defined by Sections 1 through 9 of this document. 11 | 12 | "Licensor" shall mean the copyright owner or entity authorized by 13 | the copyright owner that is granting the License. 14 | 15 | "Legal Entity" shall mean the union of the acting entity and all 16 | other entities that control, are controlled by, or are under common 17 | control with that entity. For the purposes of this definition, 18 | "control" means (i) the power, direct or indirect, to cause the 19 | direction or management of such entity, whether by contract or 20 | otherwise, or (ii) ownership of fifty percent (50%) or more of the 21 | outstanding shares, or (iii) beneficial ownership of such entity. 22 | 23 | "You" (or "Your") shall mean an individual or Legal Entity 24 | exercising permissions granted by this License. 25 | 26 | "Source" form shall mean the preferred form for making modifications, 27 | including but not limited to software source code, documentation 28 | source, and configuration files. 29 | 30 | "Object" form shall mean any form resulting from mechanical 31 | transformation or translation of a Source form, including but 32 | not limited to compiled object code, generated documentation, 33 | and conversions to other media types. 34 | 35 | "Work" shall mean the work of authorship, whether in Source or 36 | Object form, made available under the License, as indicated by a 37 | copyright notice that is included in or attached to the work 38 | (an example is provided in the Appendix below). 39 | 40 | "Derivative Works" shall mean any work, whether in Source or Object 41 | form, that is based on (or derived from) the Work and for which the 42 | editorial revisions, annotations, elaborations, or other modifications 43 | represent, as a whole, an original work of authorship. For the purposes 44 | of this License, Derivative Works shall not include works that remain 45 | separable from, or merely link (or bind by name) to the interfaces of, 46 | the Work and Derivative Works thereof. 47 | 48 | "Contribution" shall mean any work of authorship, including 49 | the original version of the Work and any modifications or additions 50 | to that Work or Derivative Works thereof, that is intentionally 51 | submitted to Licensor for inclusion in the Work by the copyright owner 52 | or by an individual or Legal Entity authorized to submit on behalf of 53 | the copyright owner. For the purposes of this definition, "submitted" 54 | means any form of electronic, verbal, or written communication sent 55 | to the Licensor or its representatives, including but not limited to 56 | communication on electronic mailing lists, source code control systems, 57 | and issue tracking systems that are managed by, or on behalf of, the 58 | Licensor for the purpose of discussing and improving the Work, but 59 | excluding communication that is conspicuously marked or otherwise 60 | designated in writing by the copyright owner as "Not a Contribution." 61 | 62 | "Contributor" shall mean Licensor and any individual or Legal Entity 63 | on behalf of whom a Contribution has been received by Licensor and 64 | subsequently incorporated within the Work. 65 | 66 | 2. Grant of Copyright License. Subject to the terms and conditions of 67 | this License, each Contributor hereby grants to You a perpetual, 68 | worldwide, non-exclusive, no-charge, royalty-free, irrevocable 69 | copyright license to reproduce, prepare Derivative Works of, 70 | publicly display, publicly perform, sublicense, and distribute the 71 | Work and such Derivative Works in Source or Object form. 72 | 73 | 3. Grant of Patent License. Subject to the terms and conditions of 74 | this License, each Contributor hereby grants to You a perpetual, 75 | worldwide, non-exclusive, no-charge, royalty-free, irrevocable 76 | (except as stated in this section) patent license to make, have made, 77 | use, offer to sell, sell, import, and otherwise transfer the Work, 78 | where such license applies only to those patent claims licensable 79 | by such Contributor that are necessarily infringed by their 80 | Contribution(s) alone or by combination of their Contribution(s) 81 | with the Work to which such Contribution(s) was submitted. If You 82 | institute patent litigation against any entity (including a 83 | cross-claim or counterclaim in a lawsuit) alleging that the Work 84 | or a Contribution incorporated within the Work constitutes direct 85 | or contributory patent infringement, then any patent licenses 86 | granted to You under this License for that Work shall terminate 87 | as of the date such litigation is filed. 88 | 89 | 4. Redistribution. You may reproduce and distribute copies of the 90 | Work or Derivative Works thereof in any medium, with or without 91 | modifications, and in Source or Object form, provided that You 92 | meet the following conditions: 93 | 94 | (a) You must give any other recipients of the Work or 95 | Derivative Works a copy of this License; and 96 | 97 | (b) You must cause any modified files to carry prominent notices 98 | stating that You changed the files; and 99 | 100 | (c) You must retain, in the Source form of any Derivative Works 101 | that You distribute, all copyright, patent, trademark, and 102 | attribution notices from the Source form of the Work, 103 | excluding those notices that do not pertain to any part of 104 | the Derivative Works; and 105 | 106 | (d) If the Work includes a "NOTICE" text file as part of its 107 | distribution, then any Derivative Works that You distribute must 108 | include a readable copy of the attribution notices contained 109 | within such NOTICE file, excluding those notices that do not 110 | pertain to any part of the Derivative Works, in at least one 111 | of the following places: within a NOTICE text file distributed 112 | as part of the Derivative Works; within the Source form or 113 | documentation, if provided along with the Derivative Works; or, 114 | within a display generated by the Derivative Works, if and 115 | wherever such third-party notices normally appear. The contents 116 | of the NOTICE file are for informational purposes only and 117 | do not modify the License. You may add Your own attribution 118 | notices within Derivative Works that You distribute, alongside 119 | or as an addendum to the NOTICE text from the Work, provided 120 | that such additional attribution notices cannot be construed 121 | as modifying the License. 122 | 123 | You may add Your own copyright statement to Your modifications and 124 | may provide additional or different license terms and conditions 125 | for use, reproduction, or distribution of Your modifications, or 126 | for any such Derivative Works as a whole, provided Your use, 127 | reproduction, and distribution of the Work otherwise complies with 128 | the conditions stated in this License. 129 | 130 | 5. Submission of Contributions. Unless You explicitly state otherwise, 131 | any Contribution intentionally submitted for inclusion in the Work 132 | by You to the Licensor shall be under the terms and conditions of 133 | this License, without any additional terms or conditions. 134 | Notwithstanding the above, nothing herein shall supersede or modify 135 | the terms of any separate license agreement you may have executed 136 | with Licensor regarding such Contributions. 137 | 138 | 6. Trademarks. This License does not grant permission to use the trade 139 | names, trademarks, service marks, or product names of the Licensor, 140 | except as required for reasonable and customary use in describing the 141 | origin of the Work and reproducing the content of the NOTICE file. 142 | 143 | 7. Disclaimer of Warranty. Unless required by applicable law or 144 | agreed to in writing, Licensor provides the Work (and each 145 | Contributor provides its Contributions) on an "AS IS" BASIS, 146 | WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or 147 | implied, including, without limitation, any warranties or conditions 148 | of TITLE, NON-INFRINGEMENT, MERCHANTABILITY, or FITNESS FOR A 149 | PARTICULAR PURPOSE. You are solely responsible for determining the 150 | appropriateness of using or redistributing the Work and assume any 151 | risks associated with Your exercise of permissions under this License. 152 | 153 | 8. Limitation of Liability. In no event and under no legal theory, 154 | whether in tort (including negligence), contract, or otherwise, 155 | unless required by applicable law (such as deliberate and grossly 156 | negligent acts) or agreed to in writing, shall any Contributor be 157 | liable to You for damages, including any direct, indirect, special, 158 | incidental, or consequential damages of any character arising as a 159 | result of this License or out of the use or inability to use the 160 | Work (including but not limited to damages for loss of goodwill, 161 | work stoppage, computer failure or malfunction, or any and all 162 | other commercial damages or losses), even if such Contributor 163 | has been advised of the possibility of such damages. 164 | 165 | 9. Accepting Warranty or Additional Liability. While redistributing 166 | the Work or Derivative Works thereof, You may choose to offer, 167 | and charge a fee for, acceptance of support, warranty, indemnity, 168 | or other liability obligations and/or rights consistent with this 169 | License. However, in accepting such obligations, You may act only 170 | on Your own behalf and on Your sole responsibility, not on behalf 171 | of any other Contributor, and only if You agree to indemnify, 172 | defend, and hold each Contributor harmless for any liability 173 | incurred by, or claims asserted against, such Contributor by reason 174 | of your accepting any such warranty or additional liability. 175 | 176 | END OF TERMS AND CONDITIONS 177 | 178 | APPENDIX: How to apply the Apache License to your work. 179 | 180 | To apply the Apache License to your work, attach the following 181 | boilerplate notice, with the fields enclosed by brackets "[]" 182 | replaced with your own identifying information. (Don't include 183 | the brackets!) The text should be enclosed in the appropriate 184 | comment syntax for the file format. We also recommend that a 185 | file or class name and description of purpose be included on the 186 | same "printed page" as the copyright notice for easier 187 | identification within third-party archives. 188 | 189 | Copyright [yyyy] [name of copyright owner] 190 | 191 | Licensed under the Apache License, Version 2.0 (the "License"); 192 | you may not use this file except in compliance with the License. 193 | You may obtain a copy of the License at 194 | 195 | http://www.apache.org/licenses/LICENSE-2.0 196 | 197 | Unless required by applicable law or agreed to in writing, software 198 | distributed under the License is distributed on an "AS IS" BASIS, 199 | WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. 200 | See the License for the specific language governing permissions and 201 | limitations under the License. 202 | -------------------------------------------------------------------------------- /build.gradle.kts: -------------------------------------------------------------------------------- 1 | fun properties(key: String) = project.findProperty(key).toString() 2 | 3 | plugins { 4 | kotlin("jvm") version "1.7.10" 5 | id("java") 6 | id("java-gradle-plugin") 7 | id("maven-publish") 8 | id("com.gradle.plugin-publish") version "0.12.0" 9 | id("com.github.blueboxware.tocme") version "1.7" 10 | id("com.github.gmazzo.buildconfig") version "3.1.0" 11 | } 12 | 13 | group = properties("group") 14 | version = properties("pluginVersion") 15 | 16 | repositories { 17 | mavenCentral() 18 | } 19 | 20 | dependencies { 21 | implementation("org.jetbrains.kotlin:kotlin-reflect") 22 | implementation("com.badlogicgames.gdx:gdx-tools:" + properties("gdxVersion")) 23 | implementation("com.badlogicgames.gdx:gdx-backend-lwjgl3:" + properties("gdxVersion")) 24 | implementation("com.badlogicgames.gdx:gdx-platform:" + properties("gdxVersion") + ":natives-desktop") 25 | implementation("com.badlogicgames.gdx:gdx-freetype-platform:" + properties("gdxVersion") + ":natives-desktop") 26 | implementation("commons-io:commons-io:2.7") 27 | implementation("org.apache.commons:commons-text:1.2") 28 | 29 | testImplementation(gradleTestKit()) 30 | testImplementation(kotlin("test")) 31 | 32 | testImplementation("io.kotest:kotest-runner-junit5:" + properties("kotestVersion")) 33 | testImplementation("io.kotest:kotest-assertions-core:" + properties("kotestVersion")) 34 | testImplementation("io.kotest:kotest-framework-datatest:" + properties("kotestVersion")) 35 | } 36 | 37 | tasks { 38 | 39 | withType { 40 | useJUnitPlatform() 41 | } 42 | 43 | register("createReadmes") { 44 | 45 | inputs.file("README.md.src") 46 | inputs.file("gradle.properties") 47 | 48 | outputs.files(fileTree("dir" to ".", "include" to "*.md")) 49 | 50 | dependsOn(project.tasks.named("insertTocs")) 51 | 52 | doLast { 53 | 54 | val baseText = file("README.md.src") 55 | .readText() 56 | .replace(Regex("(?s).*?\\s?"), "") 57 | .replace(Regex("(?s)]*>\\s*"), "") 58 | .replace("", properties("releasedPluginVersion")) 59 | .replace("", properties("pluginVersion")) 60 | .replace("", properties("gdxVersion")) 61 | 62 | file("README.md").writeText( 63 | baseText 64 | .replace(Regex("(?s).*?"), "") 65 | .replace(Regex("(?s)```kotlin.*?```\\n?"), "") 66 | .replace(Regex("(?s)"), "") 67 | ) 68 | file("README-kotlin.md").writeText( 69 | baseText 70 | .replace(Regex("(?s).*?"), "") 71 | .replace(Regex("(?s)```groovy.*?```\\n?"), "") 72 | .replace(Regex("(?s)"), "") 73 | ) 74 | 75 | } 76 | 77 | } 78 | 79 | } 80 | 81 | buildConfig { 82 | packageName("com.github.blueboxware") 83 | buildConfigField("String", "GDX_VERSION", "\"" + properties("gdxVersion") + "\"") 84 | } 85 | 86 | gradlePlugin { 87 | plugins { 88 | register("gdxPlugin") { 89 | id = "com.github.blueboxware.gdx" 90 | implementationClass = "com.github.blueboxware.gdxplugin.GdxPlugin" 91 | displayName = "LibGDX Gradle plugin" 92 | version = properties("pluginVersion") 93 | } 94 | } 95 | } 96 | 97 | pluginBundle { 98 | website = "https://github.com/BlueBoxWare/LibGDXGradlePlugin" 99 | vcsUrl = "https://github.com/BlueBoxWare/LibGDXGradlePlugin.git" 100 | description = "Plugin to create Texture Packs, Bitmap Fonts, Nine patches and Distance Fields for use with LibGDX" 101 | tags = listOf("LibGDX") 102 | } 103 | 104 | tocme { 105 | docs("README.md.src") 106 | } 107 | 108 | 109 | 110 | 111 | -------------------------------------------------------------------------------- /gradle.properties: -------------------------------------------------------------------------------- 1 | group = com.github.blueboxware 2 | pluginVersion = 1.5 3 | releasedPluginVersion = 1.5 4 | gdxVersion = 1.12.1 5 | 6 | #https://github.com/kotest/kotest/issues/3059#issuecomment-1155457089 7 | kotestVersion = 5.8.0 8 | 9 | -------------------------------------------------------------------------------- /gradle/wrapper/gradle-wrapper.jar: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/BlueBoxWare/LibGDXGradlePlugin/3fe89c80b9deeae63ee404c281ff004b195d58b9/gradle/wrapper/gradle-wrapper.jar -------------------------------------------------------------------------------- /gradle/wrapper/gradle-wrapper.properties: -------------------------------------------------------------------------------- 1 | distributionBase=GRADLE_USER_HOME 2 | distributionPath=wrapper/dists 3 | zipStoreBase=GRADLE_USER_HOME 4 | zipStorePath=wrapper/dists 5 | distributionUrl=https\://services.gradle.org/distributions/gradle-7.6-all.zip 6 | -------------------------------------------------------------------------------- /gradlew: -------------------------------------------------------------------------------- 1 | #!/usr/bin/env sh 2 | 3 | ############################################################################## 4 | ## 5 | ## Gradle start up script for UN*X 6 | ## 7 | ############################################################################## 8 | 9 | # Attempt to set APP_HOME 10 | # Resolve links: $0 may be a link 11 | PRG="$0" 12 | # Need this for relative symlinks. 13 | while [ -h "$PRG" ] ; do 14 | ls=`ls -ld "$PRG"` 15 | link=`expr "$ls" : '.*-> \(.*\)$'` 16 | if expr "$link" : '/.*' > /dev/null; then 17 | PRG="$link" 18 | else 19 | PRG=`dirname "$PRG"`"/$link" 20 | fi 21 | done 22 | SAVED="`pwd`" 23 | cd "`dirname \"$PRG\"`/" >/dev/null 24 | APP_HOME="`pwd -P`" 25 | cd "$SAVED" >/dev/null 26 | 27 | APP_NAME="Gradle" 28 | APP_BASE_NAME=`basename "$0"` 29 | 30 | # Add default JVM options here. You can also use JAVA_OPTS and GRADLE_OPTS to pass JVM options to this script. 31 | DEFAULT_JVM_OPTS="" 32 | 33 | # Use the maximum available, or set MAX_FD != -1 to use that value. 34 | MAX_FD="maximum" 35 | 36 | warn () { 37 | echo "$*" 38 | } 39 | 40 | die () { 41 | echo 42 | echo "$*" 43 | echo 44 | exit 1 45 | } 46 | 47 | # OS specific support (must be 'true' or 'false'). 48 | cygwin=false 49 | msys=false 50 | darwin=false 51 | nonstop=false 52 | case "`uname`" in 53 | CYGWIN* ) 54 | cygwin=true 55 | ;; 56 | Darwin* ) 57 | darwin=true 58 | ;; 59 | MINGW* ) 60 | msys=true 61 | ;; 62 | NONSTOP* ) 63 | nonstop=true 64 | ;; 65 | esac 66 | 67 | CLASSPATH=$APP_HOME/gradle/wrapper/gradle-wrapper.jar 68 | 69 | # Determine the Java command to use to start the JVM. 70 | if [ -n "$JAVA_HOME" ] ; then 71 | if [ -x "$JAVA_HOME/jre/sh/java" ] ; then 72 | # IBM's JDK on AIX uses strange locations for the executables 73 | JAVACMD="$JAVA_HOME/jre/sh/java" 74 | else 75 | JAVACMD="$JAVA_HOME/bin/java" 76 | fi 77 | if [ ! -x "$JAVACMD" ] ; then 78 | die "ERROR: JAVA_HOME is set to an invalid directory: $JAVA_HOME 79 | 80 | Please set the JAVA_HOME variable in your environment to match the 81 | location of your Java installation." 82 | fi 83 | else 84 | JAVACMD="java" 85 | which java >/dev/null 2>&1 || die "ERROR: JAVA_HOME is not set and no 'java' command could be found in your PATH. 86 | 87 | Please set the JAVA_HOME variable in your environment to match the 88 | location of your Java installation." 89 | fi 90 | 91 | # Increase the maximum file descriptors if we can. 92 | if [ "$cygwin" = "false" -a "$darwin" = "false" -a "$nonstop" = "false" ] ; then 93 | MAX_FD_LIMIT=`ulimit -H -n` 94 | if [ $? -eq 0 ] ; then 95 | if [ "$MAX_FD" = "maximum" -o "$MAX_FD" = "max" ] ; then 96 | MAX_FD="$MAX_FD_LIMIT" 97 | fi 98 | ulimit -n $MAX_FD 99 | if [ $? -ne 0 ] ; then 100 | warn "Could not set maximum file descriptor limit: $MAX_FD" 101 | fi 102 | else 103 | warn "Could not query maximum file descriptor limit: $MAX_FD_LIMIT" 104 | fi 105 | fi 106 | 107 | # For Darwin, add options to specify how the application appears in the dock 108 | if $darwin; then 109 | GRADLE_OPTS="$GRADLE_OPTS \"-Xdock:name=$APP_NAME\" \"-Xdock:icon=$APP_HOME/media/gradle.icns\"" 110 | fi 111 | 112 | # For Cygwin, switch paths to Windows format before running java 113 | if $cygwin ; then 114 | APP_HOME=`cygpath --path --mixed "$APP_HOME"` 115 | CLASSPATH=`cygpath --path --mixed "$CLASSPATH"` 116 | JAVACMD=`cygpath --unix "$JAVACMD"` 117 | 118 | # We build the pattern for arguments to be converted via cygpath 119 | ROOTDIRSRAW=`find -L / -maxdepth 1 -mindepth 1 -type d 2>/dev/null` 120 | SEP="" 121 | for dir in $ROOTDIRSRAW ; do 122 | ROOTDIRS="$ROOTDIRS$SEP$dir" 123 | SEP="|" 124 | done 125 | OURCYGPATTERN="(^($ROOTDIRS))" 126 | # Add a user-defined pattern to the cygpath arguments 127 | if [ "$GRADLE_CYGPATTERN" != "" ] ; then 128 | OURCYGPATTERN="$OURCYGPATTERN|($GRADLE_CYGPATTERN)" 129 | fi 130 | # Now convert the arguments - kludge to limit ourselves to /bin/sh 131 | i=0 132 | for arg in "$@" ; do 133 | CHECK=`echo "$arg"|egrep -c "$OURCYGPATTERN" -` 134 | CHECK2=`echo "$arg"|egrep -c "^-"` ### Determine if an option 135 | 136 | if [ $CHECK -ne 0 ] && [ $CHECK2 -eq 0 ] ; then ### Added a condition 137 | eval `echo args$i`=`cygpath --path --ignore --mixed "$arg"` 138 | else 139 | eval `echo args$i`="\"$arg\"" 140 | fi 141 | i=$((i+1)) 142 | done 143 | case $i in 144 | (0) set -- ;; 145 | (1) set -- "$args0" ;; 146 | (2) set -- "$args0" "$args1" ;; 147 | (3) set -- "$args0" "$args1" "$args2" ;; 148 | (4) set -- "$args0" "$args1" "$args2" "$args3" ;; 149 | (5) set -- "$args0" "$args1" "$args2" "$args3" "$args4" ;; 150 | (6) set -- "$args0" "$args1" "$args2" "$args3" "$args4" "$args5" ;; 151 | (7) set -- "$args0" "$args1" "$args2" "$args3" "$args4" "$args5" "$args6" ;; 152 | (8) set -- "$args0" "$args1" "$args2" "$args3" "$args4" "$args5" "$args6" "$args7" ;; 153 | (9) set -- "$args0" "$args1" "$args2" "$args3" "$args4" "$args5" "$args6" "$args7" "$args8" ;; 154 | esac 155 | fi 156 | 157 | # Escape application args 158 | save () { 159 | for i do printf %s\\n "$i" | sed "s/'/'\\\\''/g;1s/^/'/;\$s/\$/' \\\\/" ; done 160 | echo " " 161 | } 162 | APP_ARGS=$(save "$@") 163 | 164 | # Collect all arguments for the java command, following the shell quoting and substitution rules 165 | eval set -- $DEFAULT_JVM_OPTS $JAVA_OPTS $GRADLE_OPTS "\"-Dorg.gradle.appname=$APP_BASE_NAME\"" -classpath "\"$CLASSPATH\"" org.gradle.wrapper.GradleWrapperMain "$APP_ARGS" 166 | 167 | # by default we should be in the correct project dir, but when run from Finder on Mac, the cwd is wrong 168 | if [ "$(uname)" = "Darwin" ] && [ "$HOME" = "$PWD" ]; then 169 | cd "$(dirname "$0")" 170 | fi 171 | 172 | exec "$JAVACMD" "$@" 173 | -------------------------------------------------------------------------------- /gradlew.bat: -------------------------------------------------------------------------------- 1 | @if "%DEBUG%" == "" @echo off 2 | @rem ########################################################################## 3 | @rem 4 | @rem Gradle startup script for Windows 5 | @rem 6 | @rem ########################################################################## 7 | 8 | @rem Set local scope for the variables with windows NT shell 9 | if "%OS%"=="Windows_NT" setlocal 10 | 11 | set DIRNAME=%~dp0 12 | if "%DIRNAME%" == "" set DIRNAME=. 13 | set APP_BASE_NAME=%~n0 14 | set APP_HOME=%DIRNAME% 15 | 16 | @rem Add default JVM options here. You can also use JAVA_OPTS and GRADLE_OPTS to pass JVM options to this script. 17 | set DEFAULT_JVM_OPTS= 18 | 19 | @rem Find java.exe 20 | if defined JAVA_HOME goto findJavaFromJavaHome 21 | 22 | set JAVA_EXE=java.exe 23 | %JAVA_EXE% -version >NUL 2>&1 24 | if "%ERRORLEVEL%" == "0" goto init 25 | 26 | echo. 27 | echo ERROR: JAVA_HOME is not set and no 'java' command could be found in your PATH. 28 | echo. 29 | echo Please set the JAVA_HOME variable in your environment to match the 30 | echo location of your Java installation. 31 | 32 | goto fail 33 | 34 | :findJavaFromJavaHome 35 | set JAVA_HOME=%JAVA_HOME:"=% 36 | set JAVA_EXE=%JAVA_HOME%/bin/java.exe 37 | 38 | if exist "%JAVA_EXE%" goto init 39 | 40 | echo. 41 | echo ERROR: JAVA_HOME is set to an invalid directory: %JAVA_HOME% 42 | echo. 43 | echo Please set the JAVA_HOME variable in your environment to match the 44 | echo location of your Java installation. 45 | 46 | goto fail 47 | 48 | :init 49 | @rem Get command-line arguments, handling Windows variants 50 | 51 | if not "%OS%" == "Windows_NT" goto win9xME_args 52 | 53 | :win9xME_args 54 | @rem Slurp the command line arguments. 55 | set CMD_LINE_ARGS= 56 | set _SKIP=2 57 | 58 | :win9xME_args_slurp 59 | if "x%~1" == "x" goto execute 60 | 61 | set CMD_LINE_ARGS=%* 62 | 63 | :execute 64 | @rem Setup the command line 65 | 66 | set CLASSPATH=%APP_HOME%\gradle\wrapper\gradle-wrapper.jar 67 | 68 | @rem Execute Gradle 69 | "%JAVA_EXE%" %DEFAULT_JVM_OPTS% %JAVA_OPTS% %GRADLE_OPTS% "-Dorg.gradle.appname=%APP_BASE_NAME%" -classpath "%CLASSPATH%" org.gradle.wrapper.GradleWrapperMain %CMD_LINE_ARGS% 70 | 71 | :end 72 | @rem End local scope for the variables with windows NT shell 73 | if "%ERRORLEVEL%"=="0" goto mainEnd 74 | 75 | :fail 76 | rem Set variable GRADLE_EXIT_CONSOLE if you need the _script_ return code instead of 77 | rem the _cmd.exe /c_ return code! 78 | if not "" == "%GRADLE_EXIT_CONSOLE%" exit 1 79 | exit /b 1 80 | 81 | :mainEnd 82 | if "%OS%"=="Windows_NT" endlocal 83 | 84 | :omega 85 | -------------------------------------------------------------------------------- /settings.gradle.kts: -------------------------------------------------------------------------------- 1 | rootProject.name = "LibGDXGradlePlugin" 2 | 3 | -------------------------------------------------------------------------------- /src/main/kotlin/com/github/blueboxware/gdxplugin/GdxPlugin.kt: -------------------------------------------------------------------------------- 1 | package com.github.blueboxware.gdxplugin 2 | 3 | import com.badlogic.gdx.Version 4 | import com.badlogic.gdx.tools.texturepacker.TexturePacker 5 | import com.github.blueboxware.gdxplugin.tasks.BitmapFont 6 | import com.github.blueboxware.gdxplugin.tasks.DistanceField 7 | import com.github.blueboxware.gdxplugin.tasks.NinePatch 8 | import com.github.blueboxware.gdxplugin.tasks.PackTextures 9 | import org.gradle.api.* 10 | import org.gradle.api.logging.Logger 11 | import org.gradle.api.logging.Logging 12 | import org.gradle.language.base.plugins.LifecycleBasePlugin 13 | import org.gradle.util.GradleVersion 14 | 15 | /* 16 | * Copyright 2018 Blue Box Ware 17 | * 18 | * Licensed under the Apache License, Version 2.0 (the "License"); 19 | * you may not use this file except in compliance with the License. 20 | * You may obtain a copy of the License at 21 | * 22 | * http://www.apache.org/licenses/LICENSE-2.0 23 | * 24 | * Unless required by applicable law or agreed to in writing, software 25 | * distributed under the License is distributed on an "AS IS" BASIS, 26 | * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. 27 | * See the License for the specific language governing permissions and 28 | * limitations under the License. 29 | */ 30 | @Suppress("unused") 31 | class GdxPlugin: Plugin { 32 | 33 | override fun apply(project: Project) { 34 | 35 | if (GradleVersion.current() < GradleVersion.version("7.6")) { 36 | throw GradleException("The com.github.blueboxware.gdx plugin requires Gradle version 7.6 or higher") 37 | } 38 | 39 | val configCacheEnabled = project.gradle.startParameter.isConfigurationCacheRequested 40 | 41 | val allPacksTask= project.tasks.create(ALL_PACKS_TASK_NAME).apply { 42 | dependsOn(closure { _: Task -> 43 | project.tasks.filterIsInstance().toTypedArray() 44 | }) 45 | description = "Create or update all texture packs" 46 | group = TASK_GROUP 47 | } 48 | 49 | val allDistanceFieldsTask = project.tasks.create(ALL_DF_FIELDS_TASK_NAME).apply { 50 | dependsOn(closure { _: Task -> 51 | project.tasks.filterIsInstance().toTypedArray() 52 | }) 53 | description = "Create or update all distance fields" 54 | group = TASK_GROUP 55 | } 56 | 57 | val allFontsTask = project.tasks.create(ALL_BM_FONTS_TASK_NAME).apply { 58 | dependsOn(closure { _: Task -> 59 | project.tasks.filterIsInstance().toTypedArray() 60 | }) 61 | description = "Create or update all bitmap fonts" 62 | group = TASK_GROUP 63 | } 64 | 65 | val allNinePatchesTask = project.tasks.create(ALL_NINE_PATCHES_TASK_NAME).apply { 66 | dependsOn(closure { _: Task -> 67 | project.tasks.filterIsInstance().toTypedArray() 68 | }) 69 | description = "Create or update all nine patches" 70 | group = TASK_GROUP 71 | } 72 | 73 | val allAssetsTask = project.tasks.create(ALL_ASSETS_TASK_NAME).apply { 74 | dependsOn(allDistanceFieldsTask, allFontsTask, allPacksTask, allNinePatchesTask) 75 | description = "Create or update all assets (fonts, distance fields and texture packs)" 76 | group = TASK_GROUP 77 | } 78 | project.tasks.findByName(LifecycleBasePlugin.BUILD_TASK_NAME)?.dependsOn(allAssetsTask) 79 | 80 | val packTexturesTask = project.tasks.create("packTextures", PackTextures::class.java) 81 | packTexturesTask.packFileName = "pack.atlas" 82 | 83 | val bitmapFontsContainer = project.container(BitmapFont::class.java) { 84 | val name = "generate" + it.capitalize() + "Font" 85 | val task = project.tasks.create(name, BitmapFont::class.java).apply { 86 | description = "Generate $it bitmap font" 87 | defaultName = it 88 | this.configCacheEnabled = configCacheEnabled 89 | } 90 | task 91 | } 92 | project.extensions.add("bitmapFonts", bitmapFontsContainer) 93 | 94 | val ninePatchesContainer = project.container(NinePatch::class.java) { 95 | val name = "generate" + it.capitalize() + "NinePatch" 96 | val task = project.tasks.create(name, NinePatch::class.java).apply { 97 | description = "Generate $it nine patch" 98 | } 99 | task 100 | } 101 | project.extensions.add("ninePatch", ninePatchesContainer) 102 | 103 | val packTexturesTasksContainer = project.container(PackTextures::class.java) { 104 | val name = "pack" + it.capitalize() + "Textures" 105 | val task = project.tasks.create(name, PackTextures::class.java).apply { 106 | description = "Pack $it textures using libGDX's TexturePacker" 107 | packFileName = it 108 | } 109 | task 110 | } 111 | project.extensions.add("texturePacks", packTexturesTasksContainer) 112 | 113 | val distanceFieldContainer = project.container(DistanceField::class.java) { 114 | val name = "generate" + it.capitalize() + "DistanceField" 115 | val task = project.tasks.create(name, DistanceField::class.java).apply { 116 | description = "Generate $it distance field using libGDX's DistanceFieldGenerator" 117 | } 118 | task 119 | } 120 | project.extensions.add("distanceFields", distanceFieldContainer) 121 | 122 | val gdxVersionTask = project.tasks.create("gdxVersion", DefaultTask::class.java) 123 | with(gdxVersionTask) { 124 | description = "Show the GDX version used by gdxPlugin" 125 | group = TASK_GROUP 126 | doFirst { 127 | // Don't inline Version.VERSION 128 | val usedVersion = Version::class.java.getField("VERSION").get(null) as? String ?: "" 129 | val defaultVersion = Version.VERSION 130 | if (usedVersion == defaultVersion) { 131 | println(usedVersion) 132 | } else { 133 | println("$usedVersion (default: $defaultVersion)") 134 | } 135 | } 136 | } 137 | 138 | val gdxTexturePackerSettingsHelp = project.tasks.create("texturePackerSettingsHelp", DefaultTask::class.java) 139 | with(gdxTexturePackerSettingsHelp) { 140 | description = "Show the available TexturePacker settings and their defaults" 141 | group = TASK_GROUP 142 | doFirst { 143 | TexturePacker.Settings().let { defaultSettings -> 144 | println("TexturePacker settings and their defaults:") 145 | defaultSettings.javaClass.fields.forEach {field -> 146 | println("\t" + field.name + ": " + prettyPrint(field.get(defaultSettings))) 147 | } 148 | } 149 | } 150 | } 151 | } 152 | 153 | companion object { 154 | val LOGGER: Logger = Logging.getLogger(GdxPlugin::class.java) 155 | 156 | const val ALL_PACKS_TASK_NAME = "createAllTexturePacks" 157 | const val ALL_DF_FIELDS_TASK_NAME = "createAllDistanceFields" 158 | const val ALL_BM_FONTS_TASK_NAME = "createAllFonts" 159 | const val ALL_NINE_PATCHES_TASK_NAME = "createAllNinePatches" 160 | const val ALL_ASSETS_TASK_NAME = "createAllAssets" 161 | 162 | const val TASK_GROUP = "libGDX" 163 | } 164 | 165 | } 166 | -------------------------------------------------------------------------------- /src/main/kotlin/com/github/blueboxware/gdxplugin/Utils.kt: -------------------------------------------------------------------------------- 1 | package com.github.blueboxware.gdxplugin 2 | 3 | import groovy.lang.Closure 4 | import org.gradle.api.tasks.WorkResult 5 | import org.gradle.util.internal.ConfigureUtil 6 | import java.awt.Color 7 | import java.awt.image.BufferedImage 8 | import java.io.File 9 | import java.util.* 10 | import javax.imageio.ImageIO 11 | 12 | 13 | /* 14 | * Copyright 2018 Blue Box Ware 15 | * 16 | * Licensed under the Apache License, Version 2.0 (the "License"); 17 | * you may not use this file except in compliance with the License. 18 | * You may obtain a copy of the License at 19 | * 20 | * http://www.apache.org/licenses/LICENSE-2.0 21 | * 22 | * Unless required by applicable law or agreed to in writing, software 23 | * distributed under the License is distributed on an "AS IS" BASIS, 24 | * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. 25 | * See the License for the specific language governing permissions and 26 | * limitations under the License. 27 | */ 28 | internal val RGB_REGEX = Regex("""#?[\da-fA-F]{6}""") 29 | internal val RGBA_REGEX = Regex("""#?[\da-fA-F]{8}""") 30 | 31 | // Don't use Action(s), doesn't work. 32 | internal fun T.configure(closure: Closure): T { 33 | ConfigureUtil.configure(closure, this) 34 | return this 35 | } 36 | 37 | internal fun closure(f: () -> T): Closure = object : Closure(null) { 38 | override fun call(): T = f() 39 | } 40 | 41 | internal inline fun closure(crossinline f: (P) -> T): Closure = 42 | object : Closure(null) { 43 | override fun call(vararg args: Any?): T = f(args.firstOrNull() as P) 44 | } 45 | 46 | internal fun prettyPrint(value: Any?): String = when (value) { 47 | null -> "null" 48 | is String, is Enum<*> -> "\"" + value + "\"" 49 | else -> collectionToList(value)?.joinToString(prefix = "[", postfix = "]") { prettyPrint(it) } ?: value.toString() 50 | } 51 | 52 | internal fun collectionToList(value: Any): List<*>? = when (value) { 53 | is Collection<*> -> value.toList() 54 | is Array<*> -> value.toList() 55 | is IntArray -> value.toList() 56 | is FloatArray -> value.toList() 57 | is BooleanArray -> value.toList() 58 | is ByteArray -> value.toList() 59 | is CharArray -> value.toList() 60 | is ShortArray -> value.toList() 61 | is LongArray -> value.toList() 62 | is DoubleArray -> value.toList() 63 | else -> null 64 | } 65 | 66 | internal fun createSolidColorImage(outputFile: File, color: Color, width: Int, height: Int) { 67 | 68 | val bufferedImage = BufferedImage(width, height, BufferedImage.TYPE_INT_ARGB) 69 | val graphics = bufferedImage.createGraphics() 70 | graphics.paint = color 71 | graphics.fillRect(0, 0, width, height) 72 | ImageIO.write(bufferedImage, "png", outputFile) 73 | 74 | } 75 | 76 | internal fun String.capitalize(): String = 77 | replaceFirstChar { if (it.isLowerCase()) it.titlecase(Locale.getDefault()) else it.toString() } 78 | 79 | internal fun Char.titlecase(locale: Locale): String { 80 | val localizedUppercase = uppercase(locale) 81 | if (localizedUppercase.length > 1) { 82 | return if (this == '\u0149') localizedUppercase else localizedUppercase[0] + localizedUppercase.substring(1) 83 | .lowercase() 84 | } 85 | if (localizedUppercase != uppercase()) { 86 | return localizedUppercase 87 | } 88 | return titlecaseChar().toString() 89 | } 90 | 91 | internal fun Char.uppercase(locale: Locale): String = toString().uppercase(locale) 92 | 93 | internal val DID_WORK = WorkResult { true } 94 | 95 | internal val DID_NO_WORK = WorkResult { false } 96 | -------------------------------------------------------------------------------- /src/main/kotlin/com/github/blueboxware/gdxplugin/dsl/BitmapFontSettings.kt: -------------------------------------------------------------------------------- 1 | package com.github.blueboxware.gdxplugin.dsl 2 | 3 | import com.badlogic.gdx.tools.hiero.HieroSettings 4 | import com.badlogic.gdx.tools.hiero.unicodefont.UnicodeFont 5 | import com.badlogic.gdx.tools.hiero.unicodefont.effects.* 6 | import com.github.blueboxware.gdxplugin.RGB_REGEX 7 | import com.github.blueboxware.gdxplugin.configure 8 | import groovy.lang.Closure 9 | import org.gradle.api.GradleException 10 | import org.gradle.api.tasks.Input 11 | import org.gradle.api.tasks.Internal 12 | import java.awt.BasicStroke 13 | import java.awt.Color 14 | import java.awt.Stroke 15 | 16 | 17 | @Suppress("MemberVisibilityCanBePrivate") 18 | /* 19 | * Copyright 2018 Blue Box Ware 20 | * 21 | * Licensed under the Apache License, Version 2.0 (the "License"); 22 | * you may not use this file except in compliance with the License. 23 | * You may obtain a copy of the License at 24 | * 25 | * http://www.apache.org/licenses/LICENSE-2.0 26 | * 27 | * Unless required by applicable law or agreed to in writing, software 28 | * distributed under the License is distributed on an "AS IS" BASIS, 29 | * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. 30 | * See the License for the specific language governing permissions and 31 | * limitations under the License. 32 | */ 33 | class BitmapFontSettings { 34 | 35 | @Input 36 | var bold: Boolean = false 37 | 38 | @Input 39 | var italic: Boolean = false 40 | 41 | @Input 42 | var mono: Boolean = false 43 | 44 | @Input 45 | var gamma: Float = 1.8f 46 | 47 | @Input 48 | var paddingTop: Int = 1 49 | 50 | @Input 51 | var paddingBottom: Int = 1 52 | 53 | @Input 54 | var paddingLeft: Int = 1 55 | 56 | @Input 57 | var paddingRight: Int = 1 58 | 59 | @Input 60 | var paddingAdvanceX: Int = -2 61 | 62 | @Input 63 | var paddingAdvanceY: Int = -2 64 | 65 | @Input 66 | var glyphPageWidth: Int = 512 67 | 68 | @Input 69 | var glyphPageHeight: Int = 512 70 | 71 | @Input 72 | var renderType: UnicodeFont.RenderType = UnicodeFont.RenderType.Java 73 | 74 | @Internal 75 | var effects: List = listOf(ColorEffect(Color.WHITE)) 76 | 77 | @Input 78 | fun getEffectAsString(): String { 79 | val builder = StringBuilder() 80 | for (effect in effects) { 81 | builder.appendLine("#" + effect.javaClass.name) 82 | for (value in effect.values.filterIsInstance()) { 83 | builder.appendLine(value.name + "=" + value.string) 84 | } 85 | } 86 | return builder.toString() 87 | } 88 | 89 | fun color(string: String): Color { 90 | if (!string.matches(RGB_REGEX)) { 91 | throw GradleException("Invalid color specification: '$string' (should be 'rrggbb' or '#rrggbb')") 92 | } 93 | return string.removePrefix("#").let { EffectUtil.fromString(it) } 94 | } 95 | 96 | fun color(closure: Closure): ColorEffect = ColorEffect().configure(closure) 97 | 98 | fun color(closure: ColorEffect.() -> Unit): ColorEffect = ColorEffect().apply(closure) 99 | 100 | @Suppress("unused") 101 | fun distanceField(closure: Closure): DistanceFieldEffect = 102 | DistanceFieldEffect().configure(closure) 103 | 104 | @Suppress("unused") 105 | fun distanceField(closure: DistanceField.() -> Unit): DistanceFieldEffect = DistanceField().apply(closure).toGDX() 106 | 107 | @Suppress("unused") 108 | fun gradient(closure: Closure): GradientEffect = GradientEffect().configure(closure) 109 | 110 | @Suppress("unused") 111 | fun gradient(closure: GradientEffect.() -> Unit): GradientEffect = GradientEffect().apply(closure) 112 | 113 | @Suppress("unused") 114 | fun outline(closure: Closure): OutlineEffect = OutlineEffect().configure(closure) 115 | 116 | @Suppress("unused") 117 | fun outline(closure: Outline.() -> Unit): OutlineEffect = Outline().apply(closure).toGDX() 118 | 119 | @Suppress("unused") 120 | fun wobble(closure: Closure): OutlineWobbleEffect = OutlineWobbleEffect().configure(closure) 121 | 122 | @Suppress("unused") 123 | fun wobble(closure: Wobble.() -> Unit): OutlineWobbleEffect = Wobble().apply(closure).toGDX() 124 | 125 | @Suppress("unused") 126 | fun zigzag(closure: Closure): OutlineZigzagEffect = OutlineZigzagEffect().configure(closure) 127 | 128 | @Suppress("unused") 129 | fun zigzag(closure: ZigZag.() -> Unit): OutlineZigzagEffect = ZigZag().apply(closure).toGDX() 130 | 131 | @Suppress("unused") 132 | fun shadow(closure: Closure): ShadowEffect = ShadowEffect().configure(closure) 133 | 134 | @Suppress("unused") 135 | fun shadow(closure: ShadowEffect.() -> Unit): ShadowEffect = ShadowEffect().apply(closure) 136 | 137 | internal fun toHieroSettings(): HieroSettings { 138 | 139 | val hieroSettings = HieroSettings() 140 | hieroSettings.isBold = bold 141 | hieroSettings.isItalic = italic 142 | hieroSettings.isMono = mono 143 | hieroSettings.gamma = gamma 144 | hieroSettings.paddingTop = paddingTop 145 | hieroSettings.paddingBottom = paddingBottom 146 | hieroSettings.paddingLeft = paddingLeft 147 | hieroSettings.paddingRight = paddingRight 148 | hieroSettings.paddingAdvanceX = paddingAdvanceX 149 | hieroSettings.paddingAdvanceY = paddingAdvanceY 150 | hieroSettings.glyphPageWidth = glyphPageWidth 151 | hieroSettings.glyphPageHeight = glyphPageHeight 152 | hieroSettings.renderType = renderType.ordinal 153 | 154 | effects.forEach { 155 | hieroSettings.effects.add(it) 156 | } 157 | 158 | return hieroSettings 159 | 160 | } 161 | 162 | class Outline( 163 | var width: Float = 2f, 164 | var color: Color = Color.BLACK, 165 | var join: Int = BasicStroke.JOIN_BEVEL, 166 | var stroke: Stroke? = null 167 | ) { 168 | 169 | internal fun toGDX(): OutlineEffect = OutlineEffect().apply { 170 | color = this@Outline.color 171 | join = this@Outline.join 172 | stroke = this@Outline.stroke 173 | this.javaClass.getDeclaredField("width").let { 174 | it.isAccessible = true 175 | it.set(this, this@Outline.width) 176 | } 177 | } 178 | 179 | } 180 | 181 | class Wobble( 182 | var width: Float = 2f, var color: Color = Color.BLACK, var detail: Float = 1f, var amplitude: Float = 1f 183 | ) { 184 | 185 | internal fun toGDX(): OutlineWobbleEffect { 186 | val wobble = OutlineWobbleEffect() 187 | wobble.color = color 188 | wobble.javaClass.getDeclaredField("detail").let { 189 | it.isAccessible = true 190 | it.set(wobble, detail) 191 | } 192 | wobble.javaClass.getDeclaredField("amplitude").let { 193 | it.isAccessible = true 194 | it.set(wobble, amplitude) 195 | } 196 | wobble.javaClass.superclass.getDeclaredField("width").let { 197 | it.isAccessible = true 198 | it.set(wobble, width) 199 | } 200 | return wobble 201 | 202 | } 203 | 204 | } 205 | 206 | class ZigZag( 207 | var width: Float = 2f, 208 | var color: Color = Color.BLACK, 209 | var wavelength: Float = 3f, 210 | var amplitude: Float = 1f, 211 | var join: Int = BasicStroke.JOIN_BEVEL 212 | ) { 213 | 214 | internal fun toGDX(): OutlineZigzagEffect { 215 | val zigzag = OutlineZigzagEffect() 216 | zigzag.join = join 217 | zigzag.color = color 218 | zigzag.javaClass.getDeclaredField("wavelength").let { 219 | it.isAccessible = true 220 | it.set(zigzag, wavelength) 221 | } 222 | zigzag.javaClass.getDeclaredField("amplitude").let { 223 | it.isAccessible = true 224 | it.set(zigzag, amplitude) 225 | } 226 | zigzag.javaClass.superclass.getDeclaredField("width").let { 227 | it.isAccessible = true 228 | it.set(zigzag, width) 229 | } 230 | return zigzag 231 | 232 | } 233 | 234 | } 235 | 236 | class DistanceField( 237 | var color: Color = Color.WHITE, var scale: Int = 1, var spread: Float = 1f 238 | ) { 239 | 240 | internal fun toGDX(): DistanceFieldEffect { 241 | val df = DistanceFieldEffect() 242 | df.javaClass.getDeclaredField("color").let { 243 | it.isAccessible = true 244 | it.set(df, color) 245 | } 246 | df.javaClass.getDeclaredField("scale").let { 247 | it.isAccessible = true 248 | it.set(df, scale) 249 | } 250 | df.javaClass.getDeclaredField("spread").let { 251 | it.isAccessible = true 252 | it.set(df, spread) 253 | } 254 | return df 255 | } 256 | 257 | } 258 | 259 | @Suppress("unused", "PropertyName") 260 | @get:[Internal] 261 | val Java = UnicodeFont.RenderType.Java 262 | 263 | @Suppress("unused", "PropertyName") 264 | @get:[Internal] 265 | val Native = UnicodeFont.RenderType.Native 266 | 267 | @Suppress("unused", "PropertyName") 268 | @get:[Internal] 269 | val FreeType = UnicodeFont.RenderType.FreeType 270 | 271 | @Suppress("unused", "PropertyName") 272 | @get:[Internal] 273 | val JoinBevel = BasicStroke.JOIN_BEVEL 274 | 275 | @Suppress("unused", "PropertyName") 276 | @get:[Internal] 277 | val JoinMiter = BasicStroke.JOIN_MITER 278 | 279 | @Suppress("unused", "PropertyName") 280 | @get:[Internal] 281 | val JoinRound = BasicStroke.JOIN_ROUND 282 | 283 | } 284 | -------------------------------------------------------------------------------- /src/main/kotlin/com/github/blueboxware/gdxplugin/dsl/Constants.kt: -------------------------------------------------------------------------------- 1 | @file:Suppress("unused") 2 | @file:JvmName("Constants") 3 | 4 | package com.github.blueboxware.gdxplugin.dsl 5 | 6 | import com.badlogic.gdx.graphics.Pixmap 7 | import com.badlogic.gdx.graphics.Texture 8 | import com.badlogic.gdx.tools.texturepacker.TexturePacker 9 | 10 | /* 11 | * Copyright 2018 Blue Box Ware 12 | * 13 | * Licensed under the Apache License, Version 2.0 (the "License"); 14 | * you may not use this file except in compliance with the License. 15 | * You may obtain a copy of the License at 16 | * 17 | * http://www.apache.org/licenses/LICENSE-2.0 18 | * 19 | * Unless required by applicable law or agreed to in writing, software 20 | * distributed under the License is distributed on an "AS IS" BASIS, 21 | * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. 22 | * See the License for the specific language governing permissions and 23 | * limitations under the License. 24 | */ 25 | val Nearest = Texture.TextureFilter.Nearest 26 | val Linear = Texture.TextureFilter.Linear 27 | val MipMap = Texture.TextureFilter.MipMap 28 | val MipMapNearestNearest = Texture.TextureFilter.MipMapNearestNearest 29 | val MipMapLinearNearest = Texture.TextureFilter.MipMapLinearNearest 30 | val MipMapNearestLinear = Texture.TextureFilter.MipMapNearestLinear 31 | val MipMapLinearLinear = Texture.TextureFilter.MipMapLinearLinear 32 | 33 | val MirroredRepeat = Texture.TextureWrap.MirroredRepeat 34 | val ClampToEdge = Texture.TextureWrap.ClampToEdge 35 | val Repeat = Texture.TextureWrap.Repeat 36 | 37 | val Alpha = Pixmap.Format.Alpha 38 | val Intensity = Pixmap.Format.Intensity 39 | val LuminanceAlpha = Pixmap.Format.LuminanceAlpha 40 | val RGB565 = Pixmap.Format.RGB565 41 | val RGBA4444 = Pixmap.Format.RGBA4444 42 | val RGB888 = Pixmap.Format.RGB888 43 | val RGBA8888 = Pixmap.Format.RGBA8888 44 | 45 | object Resampling { 46 | val Nearest = TexturePacker.Resampling.nearest 47 | val Bilinear = TexturePacker.Resampling.bilinear 48 | val Bicubic = TexturePacker.Resampling.bicubic 49 | } -------------------------------------------------------------------------------- /src/main/kotlin/com/github/blueboxware/gdxplugin/dsl/SolidColorSpec.kt: -------------------------------------------------------------------------------- 1 | package com.github.blueboxware.gdxplugin.dsl 2 | 3 | import com.github.blueboxware.gdxplugin.RGBA_REGEX 4 | import com.github.blueboxware.gdxplugin.RGB_REGEX 5 | import org.gradle.api.GradleException 6 | import org.gradle.api.tasks.Input 7 | import java.awt.Color 8 | 9 | 10 | /* 11 | * Copyright 2018 Blue Box Ware 12 | * 13 | * Licensed under the Apache License, Version 2.0 (the "License"); 14 | * you may not use this file except in compliance with the License. 15 | * You may obtain a copy of the License at 16 | * 17 | * http://www.apache.org/licenses/LICENSE-2.0 18 | * 19 | * Unless required by applicable law or agreed to in writing, software 20 | * distributed under the License is distributed on an "AS IS" BASIS, 21 | * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. 22 | * See the License for the specific language governing permissions and 23 | * limitations under the License. 24 | */ 25 | class SolidColorSpec { 26 | 27 | @Input 28 | var name: String? = null 29 | 30 | var color: Color = Color.WHITE 31 | 32 | var width: Int = 1 33 | 34 | var height: Int = 1 35 | 36 | fun color(string: String): Color { 37 | 38 | if (!string.matches(RGB_REGEX) && !string.matches(RGBA_REGEX)) { 39 | throw GradleException("Invalid color specification: '$string' (should be 'rrggbb', 'rrggbbaa', '#rrggbb' or '#rrggbbaa')") 40 | } 41 | 42 | return string.removePrefix("#").let {str -> 43 | try { 44 | val r = Integer.valueOf(str.substring(0, 2), 16) 45 | val g = Integer.valueOf(str.substring(2, 4), 16) 46 | val b = Integer.valueOf(str.substring(4, 6), 16) 47 | val a = if (str.length == 8) Integer.valueOf(str.substring(6, 8), 16) else 255 48 | 49 | Color(r / 255f, g / 255f, b / 255f, a / 255f) 50 | } catch (e: NumberFormatException) { 51 | throw GradleException("Invalid color specification: '$string'") 52 | } 53 | } 54 | 55 | } 56 | 57 | fun asString(): String = "$name:$color:$width:$height" 58 | 59 | override fun toString(): String = "name=$name, color=$color, width=$width, height=$height" 60 | 61 | } 62 | -------------------------------------------------------------------------------- /src/main/kotlin/com/github/blueboxware/gdxplugin/dsl/Utils.kt: -------------------------------------------------------------------------------- 1 | @file:JvmName("Utils") 2 | @file:Suppress("unused") 3 | 4 | package com.github.blueboxware.gdxplugin.dsl 5 | 6 | import com.badlogic.gdx.tools.texturepacker.TexturePacker 7 | import com.github.blueboxware.gdxplugin.configure 8 | import groovy.lang.Closure 9 | 10 | /* 11 | * Copyright 2018 Blue Box Ware 12 | * 13 | * Licensed under the Apache License, Version 2.0 (the "License"); 14 | * you may not use this file except in compliance with the License. 15 | * You may obtain a copy of the License at 16 | * 17 | * http://www.apache.org/licenses/LICENSE-2.0 18 | * 19 | * Unless required by applicable law or agreed to in writing, software 20 | * distributed under the License is distributed on an "AS IS" BASIS, 21 | * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. 22 | * See the License for the specific language governing permissions and 23 | * limitations under the License. 24 | */ 25 | @JvmOverloads 26 | fun packSettings(baseSettings: TexturePacker.Settings? = null, closure: Closure): TexturePacker.Settings { 27 | val settings = TexturePacker.Settings() 28 | baseSettings?.let { settings.set(it) } 29 | settings.configure(closure) 30 | return settings 31 | } 32 | 33 | @JvmOverloads 34 | fun packSettings(baseSettings: TexturePacker.Settings? = null, closure: TexturePacker.Settings.() -> Unit): TexturePacker.Settings { 35 | val settings = TexturePacker.Settings() 36 | baseSettings?.let { settings.set(it) } 37 | settings.apply(closure) 38 | return settings 39 | } 40 | 41 | -------------------------------------------------------------------------------- /src/main/kotlin/com/github/blueboxware/gdxplugin/tasks/BitmapFont.kt: -------------------------------------------------------------------------------- 1 | package com.github.blueboxware.gdxplugin.tasks 2 | 3 | import com.github.blueboxware.BuildConfig 4 | import com.github.blueboxware.gdxplugin.GdxPlugin 5 | import com.github.blueboxware.gdxplugin.configure 6 | import com.github.blueboxware.gdxplugin.dsl.BitmapFontSettings 7 | import groovy.lang.Closure 8 | import org.gradle.api.DefaultTask 9 | import org.gradle.api.GradleException 10 | import org.gradle.api.internal.file.FileOperations 11 | import org.gradle.api.internal.initialization.ScriptHandlerInternal 12 | import org.gradle.api.logging.LogLevel 13 | import org.gradle.api.tasks.* 14 | import org.gradle.process.ExecOperations 15 | import java.io.File 16 | import javax.inject.Inject 17 | 18 | 19 | /* 20 | * Copyright 2018 Blue Box Ware 21 | * 22 | * Licensed under the Apache License, Version 2.0 (the "License"); 23 | * you may not use this file except in compliance with the License. 24 | * You may obtain a copy of the License at 25 | * 26 | * http://www.apache.org/licenses/LICENSE-2.0 27 | * 28 | * Unless required by applicable law or agreed to in writing, software 29 | * distributed under the License is distributed on an "AS IS" BASIS, 30 | * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. 31 | * See the License for the specific language governing permissions and 32 | * limitations under the License. 33 | */ 34 | @Suppress("MemberVisibilityCanBePrivate") 35 | abstract class BitmapFont @Inject constructor(private val execOperations: ExecOperations, private val fileOperations: FileOperations): DefaultTask() { 36 | 37 | @Suppress("PropertyName") 38 | @Internal 39 | val NEHE = "ABCDEFGHIJKLMNOPQRSTUVWXYZ\nabcdefghijklmnopqrstuvwxyz1234567890\"!`?'.,;:()[]{}<>|/@\\^$-%+=#_&~*\u007F" 40 | 41 | @Nested 42 | var settings: BitmapFontSettings = BitmapFontSettings() 43 | 44 | @Input 45 | var inputFont: Any = "Arial" 46 | 47 | @Inject 48 | abstract fun getBuildScript(): ScriptHandlerInternal 49 | 50 | @Internal 51 | var configCacheEnabled: Boolean = false 52 | 53 | @Internal 54 | var outputFile: Any? = null 55 | set(value) { 56 | field = when (value) { 57 | is String -> fileOperations.file(value) 58 | is File -> value 59 | else -> throw GradleException("outputFile: String or File expected") 60 | } 61 | } 62 | 63 | @Input 64 | var characters: String = NEHE 65 | 66 | @Input 67 | @Optional 68 | var defaultName: String? = null 69 | 70 | private var outputFonts: MutableList = mutableListOf() 71 | 72 | init { 73 | description = "Create a bitmap font using Hiero" 74 | group = GdxPlugin.TASK_GROUP 75 | 76 | logging.captureStandardOutput(LogLevel.LIFECYCLE) 77 | logging.captureStandardError(LogLevel.ERROR) 78 | } 79 | 80 | @TaskAction 81 | fun generate() { 82 | 83 | if (configCacheEnabled) { 84 | throw GradleException("BitmapFont tasks are not compatible with Gradle's configuration cache.") 85 | } 86 | 87 | if (outputFonts.isEmpty()) { 88 | throw GradleException("No output size(s) specified") 89 | } 90 | 91 | val tmpSettingsFile = File(temporaryDir, "font.settings") 92 | settings.toHieroSettings().apply { 93 | glyphText = characters 94 | when (inputFont) { 95 | is File -> { 96 | font2File = (inputFont as File).absolutePath 97 | isFont2Active = true 98 | } 99 | is String -> fontName = inputFont as String 100 | else -> throw GradleException("inputFont should be either a String (name of a system font) or a file (a TTF file)") 101 | } 102 | }.save(tmpSettingsFile) 103 | 104 | val cpConfiguration = getBuildScript().configurations.findByName("classpath")?.copy() ?: throw GradleException("Could not find classpath configuration of buildscript") 105 | val nativesDepedency = project.dependencies.create("com.badlogicgames.gdx:gdx-platform:${BuildConfig.GDX_VERSION}:natives-desktop") 106 | val ftNativesDependency = project.dependencies.create("com.badlogicgames.gdx:gdx-freetype-platform:${BuildConfig.GDX_VERSION}:natives-desktop") 107 | cpConfiguration.dependencies.add(nativesDepedency) 108 | cpConfiguration.dependencies.add(ftNativesDependency) 109 | 110 | execOperations.javaexec { javaExecSpec -> 111 | javaExecSpec.mainClass.set("com.github.blueboxware.gdxplugin.utils.FontGenerator") 112 | javaExecSpec.classpath = cpConfiguration 113 | javaExecSpec.args( 114 | listOf(tmpSettingsFile.absolutePath) + 115 | getActualOutputFontSpecs() 116 | .map { it.fontSize.toString() + ":" + (it.file?.absolutePath ?: throw AssertionError()) } 117 | ) 118 | } 119 | 120 | } 121 | 122 | private fun getActualOutputFontSpecs(): List { 123 | val baseName = (outputFile as? File)?.absolutePath?.removeSuffix(".fnt") ?: defaultName ?: name 124 | return outputFonts.map { 125 | val file = it.file ?: if (outputFonts.size > 1) { 126 | File(baseName + it.fontSize + "px.fnt") 127 | } else { 128 | File("$baseName.fnt") 129 | } 130 | OutputFontSpec(it.fontSize, file) 131 | } 132 | } 133 | 134 | @OutputFiles 135 | fun getActualOutputFiles(): List = getActualOutputFontSpecs().mapNotNull { it.file } 136 | 137 | @InputFile 138 | @Optional 139 | fun getActualInputFile() = inputFont as? File 140 | 141 | @Input 142 | fun getInputSizes() = outputFonts.map { it.fontSize }.joinToString() 143 | 144 | fun settings(closure: Closure) { 145 | settings.configure(closure) 146 | } 147 | 148 | fun settings(closure: BitmapFontSettings.() -> Unit) { 149 | settings.apply(closure) 150 | } 151 | 152 | data class OutputFontSpec(var fontSize: Int, var file: File? = null) 153 | 154 | @Suppress("unused") 155 | fun setSize(vararg sizes:Int) = sizes(*sizes) 156 | 157 | @Suppress("unused") 158 | fun setSizes(vararg sizes: Int) = sizes(*sizes) 159 | 160 | fun size(vararg sizes: Int) = sizes.forEach { outputFonts.add(OutputFontSpec(it)) } 161 | 162 | fun size(size: Int, filename: String) = 163 | outputFonts.add(OutputFontSpec(size, fileOperations.file(filename.removeSuffix(".fnt") + ".fnt"))) 164 | 165 | fun size(size: Int, file: File) = 166 | if (file.extension != "fnt") { 167 | outputFonts.add(OutputFontSpec(size, File(file.absolutePath + ".fnt"))) 168 | } else { 169 | outputFonts.add(OutputFontSpec(size, file)) 170 | } 171 | 172 | fun sizes(vararg sizes: Int) = size(*sizes) 173 | 174 | @Suppress("unused", "PropertyName") 175 | @Internal 176 | val COMMON = NEHE 177 | 178 | @Suppress("unused", "PropertyName") 179 | @Internal 180 | val ASCII = CharRange(32.toChar(), 255.toChar()).joinTo(StringBuilder(), separator = "").toString() 181 | 182 | @Suppress("unused", "PropertyName") 183 | @Internal 184 | val EXTENDED = listOf(0, 33, 34, 35, 36, 37, 38, 39, 40, 41, 42, 43, 44, 45, 46, 47, 48, 49, 50, 51, 52, 53, 54, 55, 56, 185 | 57, 58, 59, 60, 61, 62, 63, 64, 65, 66, 67, 68, 69, 70, 71, 72, 73, 74, 75, 76, 77, 78, 79, 80, 81, 82, 83, 84, 85, 86, 186 | 87, 88, 89, 90, 91, 92, 93, 94, 95, 96, 97, 98, 99, 100, 101, 102, 103, 104, 105, 106, 107, 108, 109, 110, 111, 112, 113, 187 | 114, 115, 116, 117, 118, 119, 120, 121, 122, 123, 124, 125, 126, 160, 161, 162, 163, 164, 165, 166, 167, 168, 169, 170, 188 | 171, 172, 173, 174, 175, 176, 177, 178, 179, 180, 181, 182, 183, 184, 185, 186, 187, 188, 189, 190, 191, 192, 193, 194, 189 | 195, 196, 197, 198, 199, 200, 201, 202, 203, 204, 205, 206, 207, 208, 209, 210, 211, 212, 213, 214, 215, 216, 217, 218, 190 | 219, 220, 221, 222, 223, 224, 225, 226, 227, 228, 229, 230, 231, 232, 233, 234, 235, 236, 237, 238, 239, 240, 241, 242, 191 | 243, 244, 245, 246, 247, 248, 249, 250, 251, 252, 253, 254, 255, 256, 257, 258, 259, 260, 261, 262, 263, 264, 265, 266, 192 | 267, 268, 269, 270, 271, 272, 273, 274, 275, 276, 277, 278, 279, 280, 281, 282, 283, 284, 285, 286, 287, 288, 289, 290, 193 | 291, 292, 293, 294, 295, 296, 297, 298, 299, 300, 301, 302, 303, 304, 305, 306, 307, 308, 309, 310, 311, 312, 313, 314, 194 | 315, 316, 317, 318, 319, 320, 321, 322, 323, 324, 325, 326, 327, 328, 329, 330, 331, 332, 333, 334, 335, 336, 337, 338, 195 | 339, 340, 341, 342, 343, 344, 345, 346, 347, 348, 349, 350, 351, 352, 353, 354, 355, 356, 357, 358, 359, 360, 361, 362, 196 | 363, 364, 365, 366, 367, 368, 369, 370, 371, 372, 373, 374, 375, 376, 377, 378, 379, 380, 381, 382, 383, 884, 885, 890, 197 | 891, 892, 893, 894, 900, 901, 902, 903, 904, 905, 906, 908, 910, 911, 912, 913, 914, 915, 916, 917, 918, 919, 920, 921, 198 | 922, 923, 924, 925, 926, 927, 928, 929, 931, 932, 933, 934, 935, 936, 937, 938, 939, 940, 941, 942, 943, 944, 945, 946, 199 | 947, 948, 949, 950, 951, 952, 953, 954, 955, 956, 957, 958, 959, 960, 961, 962, 963, 964, 965, 966, 967, 968, 969, 970, 200 | 971, 972, 973, 974, 976, 977, 978, 979, 980, 981, 982, 983, 984, 985, 986, 987, 988, 989, 990, 991, 992, 993, 994, 995, 201 | 996, 997, 998, 999, 1000, 1001, 1002, 1003, 1004, 1005, 1006, 1007, 1008, 1009, 1010, 1011, 1012, 1013, 1014, 1015, 1016, 202 | 1017, 1018, 1019, 1020, 1021, 1022, 1023, 1024, 1025, 1026, 1027, 1028, 1029, 1030, 1031, 1032, 1033, 1034, 1035, 1036, 203 | 1037, 1038, 1039, 1040, 1041, 1042, 1043, 1044, 1045, 1046, 1047, 1048, 1049, 1050, 1051, 1052, 1053, 1054, 1055, 1056, 204 | 1057, 1058, 1059, 1060, 1061, 1062, 1063, 1064, 1065, 1066, 1067, 1068, 1069, 1070, 1071, 1072, 1073, 1074, 1075, 1076, 205 | 1077, 1078, 1079, 1080, 1081, 1082, 1083, 1084, 1085, 1086, 1087, 1088, 1089, 1090, 1091, 1092, 1093, 1094, 1095, 1096, 206 | 1097, 1098, 1099, 1100, 1101, 1102, 1103, 1104, 1105, 1106, 1107, 1108, 1109, 1110, 1111, 1112, 1113, 1114, 1115, 1116, 207 | 1117, 1118, 1119, 1120, 1121, 1122, 1123, 1124, 1125, 1126, 1127, 1128, 1129, 1130, 1131, 1132, 1133, 1134, 1135, 1136, 208 | 1137, 1138, 1139, 1140, 1141, 1142, 1143, 1144, 1145, 1146, 1147, 1148, 1149, 1150, 1151, 1152, 1153, 1154, 1155, 1156, 209 | 1157, 1158, 1159, 1160, 1161, 1162, 1163, 1164, 1165, 1166, 1167, 1168, 1169, 1170, 1171, 1172, 1173, 1174, 1175, 1176, 210 | 1177, 1178, 1179, 1180, 1181, 1182, 1183, 1184, 1185, 1186, 1187, 1188, 1189, 1190, 1191, 1192, 1193, 1194, 1195, 1196, 211 | 1197, 1198, 1199, 1200, 1201, 1202, 1203, 1204, 1205, 1206, 1207, 1208, 1209, 1210, 1211, 1212, 1213, 1214, 1215, 1216, 212 | 1217, 1218, 1219, 1220, 1221, 1222, 1223, 1224, 1225, 1226, 1227, 1228, 1229, 1230, 1231, 1232, 1233, 1234, 1235, 1236, 213 | 1237, 1238, 1239, 1240, 1241, 1242, 1243, 1244, 1245, 1246, 1247, 1248, 1249, 1250, 1251, 1252, 1253, 1254, 1255, 1256, 214 | 1257, 1258, 1259, 1260, 1261, 1262, 1263, 1264, 1265, 1266, 1267, 1268, 1269, 1270, 1271, 1272, 1273, 1274, 1275, 1276, 215 | 1277, 1278, 1279, 1280, 1281, 1282, 1283, 1284, 1285, 1286, 1287, 1288, 1289, 1290, 1291, 1292, 1293, 1294, 1295, 1296, 216 | 1297, 1298, 1299, 1300, 1301, 1302, 1303, 1304, 1305, 1306, 1307, 1308, 1309, 1310, 1311, 1312, 1313, 1314, 1315, 1316, 217 | 1317, 1318, 1319, 8192, 8193, 8194, 8195, 8196, 8197, 8198, 8199, 8200, 8201, 8202, 8203, 8204, 8205, 8206, 8207, 8210, 218 | 8211, 8212, 8213, 8214, 8215, 8216, 8217, 8218, 8219, 8220, 8221, 8222, 8223, 8224, 8225, 8226, 8230, 8234, 8235, 8236, 219 | 8237, 8238, 8239, 8240, 8242, 8243, 8244, 8249, 8250, 8252, 8254, 8260, 8286, 8298, 8299, 8300, 8301, 8302, 8303, 8352, 220 | 8353, 8354, 8355, 8356, 8357, 8358, 8359, 8360, 8361, 8363, 8364, 8365, 8366, 8367, 8368, 8369, 8370, 8371, 8372, 8373, 221 | 8377, 8378, 11360, 11361, 11362, 11363, 11364, 11365, 11366, 11367, 11368, 11369, 11370, 11371, 11372, 11373, 11377, 222 | 11378, 11379, 11380, 11381, 11382, 11383).map { it.toChar() }.joinTo(StringBuilder(), separator = "").toString() 223 | 224 | } 225 | -------------------------------------------------------------------------------- /src/main/kotlin/com/github/blueboxware/gdxplugin/tasks/DistanceField.kt: -------------------------------------------------------------------------------- 1 | package com.github.blueboxware.gdxplugin.tasks 2 | 3 | import com.badlogic.gdx.tools.distancefield.DistanceFieldGenerator 4 | import com.github.blueboxware.gdxplugin.GdxPlugin 5 | import org.apache.commons.io.FilenameUtils 6 | import org.gradle.api.DefaultTask 7 | import org.gradle.api.GradleException 8 | import org.gradle.api.InvalidUserDataException 9 | import org.gradle.api.logging.LogLevel 10 | import org.gradle.api.tasks.* 11 | import java.awt.Color 12 | import java.io.File 13 | import java.io.FileNotFoundException 14 | import javax.imageio.IIOException 15 | import javax.imageio.ImageIO 16 | 17 | 18 | /* 19 | * Copyright 2018 Blue Box Ware 20 | * 21 | * Licensed under the Apache License, Version 2.0 (the "License"); 22 | * you may not use this file except in compliance with the License. 23 | * You may obtain a copy of the License at 24 | * 25 | * http://www.apache.org/licenses/LICENSE-2.0 26 | * 27 | * Unless required by applicable law or agreed to in writing, software 28 | * distributed under the License is distributed on an "AS IS" BASIS, 29 | * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. 30 | * See the License for the specific language governing permissions and 31 | * limitations under the License. 32 | */ 33 | @Suppress("MemberVisibilityCanBePrivate") 34 | open class DistanceField: DefaultTask() { 35 | 36 | var color: String = "ffffff" 37 | @Input get 38 | 39 | var outputFormat: String? = null 40 | @Input @Optional get 41 | 42 | var downscale: Int = 1 43 | @Input get 44 | 45 | var spread: Float = 1f 46 | @Input get 47 | 48 | var inputFile: File? = null 49 | @InputFile @Optional get 50 | 51 | @Internal 52 | var outputFile: File? = null 53 | 54 | init { 55 | description = "Create a Distance Field from an images using libGDX's DistanceFieldGenerator" 56 | group = GdxPlugin.TASK_GROUP 57 | 58 | logging.captureStandardOutput(LogLevel.LIFECYCLE) 59 | logging.captureStandardError(LogLevel.ERROR) 60 | } 61 | 62 | @TaskAction 63 | fun generate() { 64 | 65 | if (inputFile == null || inputFile?.isFile != true) { 66 | throw InvalidUserDataException("Please specify the input image using the inputFile parameter") 67 | } 68 | 69 | inputFile?.let { realInputFile -> 70 | 71 | if (!realInputFile.exists()) { 72 | throw FileNotFoundException("File does not exist: '${realInputFile.absolutePath}'") 73 | } 74 | 75 | val realOutputFormat = getActualOutputFormat() 76 | 77 | getActualOutputFile()?.let { realOutputFile -> 78 | 79 | if (!ImageIO.getImageWritersByFormatName(realOutputFormat).hasNext()) { 80 | throw InvalidUserDataException("Invalid output format: '$realOutputFormat'") 81 | } 82 | 83 | ImageIO.read(realInputFile)?.let { inputImage -> 84 | val generator = DistanceFieldGenerator().apply { 85 | color = Color(Integer.parseInt(this@DistanceField.color.removePrefix("#"), 16)) 86 | spread = this@DistanceField.spread 87 | downscale = this@DistanceField.downscale 88 | } 89 | 90 | generator.generateDistanceField(inputImage)?.let { outputImage -> 91 | var jvm = "Unknown JDK" 92 | try { 93 | jvm = System.getProperty("java.vm.name") 94 | } catch (e: Exception) { 95 | // Nothing 96 | } 97 | val type = if (realOutputFormat == "jpg") "JPG" else inputImage.type.toString() 98 | try { 99 | ImageIO.write(outputImage, realOutputFormat, realOutputFile).let { 100 | if (!it) { 101 | throw GradleException("$jvm does not have a writer for image type $type") 102 | } 103 | } 104 | } catch (e: IIOException) { 105 | if (realOutputFormat == "jpg" && outputImage.colorModel.hasAlpha()) { 106 | 107 | throw GradleException("$jvm does not support creating jpegs with alpha.") 108 | } 109 | } 110 | } 111 | } 112 | 113 | } 114 | 115 | } 116 | 117 | } 118 | 119 | private fun getActualOutputFormat(): String = outputFormat?.removePrefix(".") 120 | ?: outputFile?.let { FilenameUtils.getExtension(it.absolutePath) } 121 | ?: "png" 122 | 123 | @OutputFile 124 | @Optional 125 | internal fun getActualOutputFile(): File? = outputFile ?: run { 126 | inputFile?.let { inputFile -> 127 | val baseName = FilenameUtils.removeExtension(inputFile.absolutePath) + "-df" 128 | val extension = getActualOutputFormat() 129 | File("$baseName.$extension") 130 | } 131 | } 132 | 133 | } 134 | -------------------------------------------------------------------------------- /src/main/kotlin/com/github/blueboxware/gdxplugin/tasks/NinePatch.kt: -------------------------------------------------------------------------------- 1 | package com.github.blueboxware.gdxplugin.tasks 2 | 3 | import com.github.blueboxware.gdxplugin.GdxPlugin 4 | import com.github.blueboxware.gdxplugin.capitalize 5 | import org.apache.commons.io.FilenameUtils 6 | import org.gradle.api.DefaultTask 7 | import org.gradle.api.GradleException 8 | import org.gradle.api.internal.file.FileOperations 9 | import org.gradle.api.tasks.* 10 | import java.awt.Color 11 | import java.awt.RenderingHints 12 | import java.awt.image.BufferedImage 13 | import java.awt.image.ConvolveOp 14 | import java.awt.image.Kernel 15 | import java.io.File 16 | import javax.imageio.ImageIO 17 | import javax.inject.Inject 18 | import kotlin.math.log10 19 | import kotlin.math.pow 20 | import kotlin.math.sqrt 21 | 22 | 23 | /* 24 | * Copyright 2018 Blue Box Ware 25 | * 26 | * Licensed under the Apache License, Version 2.0 (the "License"); 27 | * you may not use this file except in compliance with the License. 28 | * You may obtain a copy of the License at 29 | * 30 | * http://www.apache.org/licenses/LICENSE-2.0 31 | * 32 | * Unless required by applicable law or agreed to in writing, software 33 | * distributed under the License is distributed on an "AS IS" BASIS, 34 | * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. 35 | * See the License for the specific language governing permissions and 36 | * limitations under the License. 37 | */ 38 | open class NinePatch @Inject constructor(private val fileOperations: FileOperations): DefaultTask() { 39 | 40 | @Input 41 | @Optional 42 | var left: Int? = null 43 | 44 | @Input 45 | @Optional 46 | var right: Int? = null 47 | 48 | @Input 49 | @Optional 50 | var top: Int? = null 51 | 52 | @Input 53 | @Optional 54 | var bottom: Int? = null 55 | 56 | @Input 57 | @Optional 58 | var paddingLeft: Int? = null 59 | 60 | @Input 61 | @Optional 62 | var paddingRight: Int? = null 63 | 64 | @Input 65 | @Optional 66 | var paddingTop: Int? = null 67 | 68 | @Input 69 | @Optional 70 | var paddingBottom: Int? = null 71 | 72 | @InputFile 73 | var image: File? = null 74 | 75 | @Internal 76 | var output: File? = null 77 | 78 | @Input 79 | var auto: Boolean = false 80 | 81 | @Input 82 | var edgeDetect: Boolean = false 83 | 84 | @Input 85 | var fuzziness: Float = 0f 86 | 87 | @Input 88 | @Optional 89 | var centerX: Int? = null 90 | 91 | @Input 92 | @Optional 93 | var centerY: Int? = null 94 | 95 | init { 96 | description = "Create a nine patch" 97 | group = GdxPlugin.TASK_GROUP 98 | } 99 | 100 | @OutputFile 101 | fun getActualOutputFile(): File = output ?: run { 102 | image?.let { inputFile -> 103 | val baseName = FilenameUtils.removeExtension(inputFile.absolutePath) 104 | fileOperations.file("$baseName.9.png") 105 | } ?: throw GradleException("Please specify an input image") 106 | } 107 | 108 | @TaskAction 109 | fun generate() { 110 | 111 | image?.let { actualImage -> 112 | ImageIO.read(actualImage)?.let { srcImage -> 113 | val width = srcImage.width 114 | val height = srcImage.height 115 | 116 | if (auto) { 117 | if (edgeDetect) { 118 | guess(edgeDetect(srcImage)) 119 | } else { 120 | guess(srcImage) 121 | } 122 | } 123 | 124 | val top = top ?: 0 125 | val bottom = bottom ?: 0 126 | val right = right ?: 0 127 | val left = left ?: 0 128 | 129 | checkArg(left >= width, "left offset", "width", width) 130 | checkArg(right >= width, "right offset", "width", width) 131 | checkArg(top >= height, "top offset", "height", height) 132 | checkArg(bottom >= height, "bottom offset", "height", height) 133 | 134 | checkArg((paddingLeft ?: 0) >= width, "left padding", "width", width) 135 | checkArg((paddingRight ?: 0) >= width, "right padding", "width", width) 136 | checkArg((paddingTop ?: 0) >= height, "top padding", "height", height) 137 | checkArg((paddingBottom ?: 0) >= height, "bottom padding", "height", height) 138 | 139 | BufferedImage(width + 2, height + 2, BufferedImage.TYPE_INT_ARGB).let {dstImage -> 140 | dstImage.createGraphics().let { graphics -> 141 | graphics.drawImage(srcImage, 1, 1, null) 142 | graphics.color = Color(0, 0, 0, 0) 143 | graphics.drawRect(0, 0, width + 2, height + 2) 144 | graphics.color = Color.BLACK 145 | graphics.drawLine(left + 1, 0, width - right, 0) 146 | graphics.drawLine(0, top + 1, 0, height - bottom ) 147 | if (paddingLeft != null || paddingRight != null || paddingTop != null || paddingBottom != null) { 148 | graphics.drawLine((paddingLeft ?: left) + 1, height + 1, width - (paddingRight ?: right) , height + 1) 149 | graphics.drawLine(width + 1, (paddingTop ?: top) + 1, width + 1, height - (paddingBottom ?: bottom)) 150 | } 151 | ImageIO.write(dstImage, "png", getActualOutputFile()) 152 | } 153 | } 154 | } 155 | } 156 | 157 | } 158 | 159 | private fun checkArg(cond: Boolean, arg: String, maxArg: String, maxValue: Int) { 160 | if (cond) { 161 | throw GradleException(arg.capitalize() + " must be smaller than image $maxArg (image $maxArg: $maxValue)") 162 | } 163 | } 164 | 165 | private fun guess(image: BufferedImage) { 166 | 167 | val fuzziness = fuzziness.coerceIn(0f, 100f) 168 | 169 | val centerX = centerX ?: left ?: right?.let { image.width - it - 1 } ?: (image.width / 2) 170 | val centerY = centerY ?: top ?: bottom?.let { image.height - it - 1 } ?: (image.height / 2) 171 | 172 | if (left == null) { 173 | var old: IntArray? = null 174 | for (x in centerX downTo 0) { 175 | val new = image.getColumn(x) 176 | if (old != null && diff(old, new) > fuzziness) { 177 | left = x + 1 178 | break 179 | } 180 | old = new 181 | } 182 | } 183 | if (right == null) { 184 | var old: IntArray? = null 185 | for (x in centerX until image.width) { 186 | val new = image.getColumn(x) 187 | if (old != null && diff(old, new) > fuzziness) { 188 | right = image.width - x 189 | break 190 | } 191 | old = new 192 | } 193 | } 194 | if (top == null) { 195 | var old: IntArray? = null 196 | for (y in centerY downTo 0) { 197 | val new = image.getRow(y) 198 | if (old != null && diff(old, new) > fuzziness) { 199 | top = y + 1 200 | break 201 | } 202 | old = new 203 | } 204 | } 205 | if (bottom == null) { 206 | var old: IntArray? = null 207 | for (y in centerY until image.height) { 208 | val new = image.getRow(y) 209 | if (old != null && diff(old, new) > fuzziness) { 210 | bottom = image.height - y 211 | break 212 | } 213 | old = new 214 | } 215 | } 216 | 217 | } 218 | 219 | private fun BufferedImage.getColumn(x: Int): IntArray = 220 | (0 until height).map { getRGB(x, it) }.toIntArray() 221 | 222 | private fun BufferedImage.getRow(y: Int): IntArray = 223 | (0 until width).map { getRGB(it, y) }.toIntArray() 224 | 225 | private fun diff(a: IntArray, b: IntArray): Float = 226 | log10((((a.indices).map { colorDiff(a[it], b[it]) }).sum() / a.size)) / 0.0292724f 227 | 228 | private fun colorDiff(c1: Int, c2: Int): Float { 229 | val a1 = (c1 shr 24 and 0xFF).toFloat() 230 | val r1 = (c1 shr 16 and 0xFF).toFloat() 231 | val g1 = (c1 shr 8 and 0xFF).toFloat() 232 | val b1 = (c1 shr 0 and 0xFF).toFloat() 233 | 234 | val a2 = (c2 shr 24 and 0xFF).toFloat() 235 | val r2 = (c2 shr 16 and 0xFF).toFloat() 236 | val g2 = (c2 shr 8 and 0xFF).toFloat() 237 | val b2 = (c2 shr 0 and 0xFF).toFloat() 238 | 239 | if (a1 == 0f && a2 == 0f) { 240 | return 0f 241 | } 242 | 243 | return sqrt(2 * (a2 - a1).pow(2) + 2 * (r2 - r1).pow(2) + 4 * (g2 - g1).pow(2) + 3 * (b2 - b1).pow(2)) 244 | } 245 | 246 | private fun edgeDetect(image: BufferedImage, debug: Boolean = false): BufferedImage { 247 | 248 | val kernel = arrayOf( 249 | 0f, -1f, 0f, 250 | -1f, 4f, -1f, 251 | 0f, -1f, 0f 252 | ).toFloatArray() 253 | val convolveOp = ConvolveOp( 254 | Kernel(3, 3, kernel), 255 | ConvolveOp.EDGE_NO_OP, 256 | RenderingHints(RenderingHints.KEY_RENDERING, RenderingHints.VALUE_RENDER_QUALITY) 257 | ) 258 | 259 | val r = convolveOp.filter(image, null) 260 | 261 | if (debug) { 262 | ImageIO.write(r, "png", File(temporaryDir, "edge.png")) 263 | } 264 | 265 | return r 266 | 267 | } 268 | 269 | } 270 | -------------------------------------------------------------------------------- /src/main/kotlin/com/github/blueboxware/gdxplugin/tasks/PackTextures.kt: -------------------------------------------------------------------------------- 1 | package com.github.blueboxware.gdxplugin.tasks 2 | 3 | import com.badlogic.gdx.tools.texturepacker.TexturePacker 4 | import com.badlogic.gdx.utils.Json 5 | import com.github.blueboxware.gdxplugin.* 6 | import com.github.blueboxware.gdxplugin.dsl.SolidColorSpec 7 | import groovy.lang.Closure 8 | import org.gradle.api.GradleException 9 | import org.gradle.api.internal.file.copy.CopyAction 10 | import org.gradle.api.internal.file.copy.DestinationRootCopySpec 11 | import org.gradle.api.internal.file.copy.FileCopyAction 12 | import org.gradle.api.logging.LogLevel 13 | import org.gradle.api.tasks.* 14 | import java.io.File 15 | import java.io.FileReader 16 | 17 | 18 | /* 19 | * Copyright 2018 Blue Box Ware 20 | * 21 | * Licensed under the Apache License, Version 2.0 (the "License"); 22 | * you may not use this file except in compliance with the License. 23 | * You may obtain a copy of the License at 24 | * 25 | * http://www.apache.org/licenses/LICENSE-2.0 26 | * 27 | * Unless required by applicable law or agreed to in writing, software 28 | * distributed under the License is distributed on an "AS IS" BASIS, 29 | * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. 30 | * See the License for the specific language governing permissions and 31 | * limitations under the License. 32 | */ 33 | @Suppress("MemberVisibilityCanBePrivate") 34 | open class PackTextures : AbstractCopyTask() { 35 | 36 | var packFileName: String = name 37 | @Input @Optional get 38 | 39 | var settingsFile: File? = null 40 | @InputFile @Optional get 41 | 42 | var usePackJson: Boolean? = false 43 | @Input @Optional get 44 | 45 | var settings: TexturePacker.Settings = TexturePacker.Settings() 46 | @Nested @Optional get 47 | 48 | private val solidSpecs: MutableList = mutableListOf() 49 | 50 | private val dummy = File(temporaryDir, "dummy") 51 | 52 | init { 53 | description = "Pack textures using libGDX's TexturePacker" 54 | group = GdxPlugin.TASK_GROUP 55 | 56 | logging.captureStandardOutput(LogLevel.LIFECYCLE) 57 | logging.captureStandardError(LogLevel.ERROR) 58 | 59 | // Gradle < 3.5 doesn't like collections as properties 60 | // https://github.com/gradle/gradle/commits/master/subprojects/core/src/main/java/org/gradle/api/internal/changedetection/state/InputPropertiesSerializer.java 61 | TexturePacker.Settings::class.java.fields.filter { it.name !in SETTINGS_TO_IGNORE }.associate { 62 | it.name to closure { -> 63 | it.get(settings).let { value -> 64 | // Gradle < 3.5 doesn't like collections as properties 65 | // https://github.com/gradle/gradle/commits/master/subprojects/core/src/main/java/org/gradle/api/internal/changedetection/state/InputPropertiesSerializer.java 66 | collectionToList(value)?.joinToString() ?: value 67 | } 68 | } 69 | }.let { 70 | inputs.properties(it) 71 | } 72 | 73 | outputs.files(closure { -> 74 | val baseName = packFileName.removeSuffix(settings.atlasExtension) 75 | settings.scale.mapIndexed { index, _ -> 76 | File(getDestinationDir(), settings.getScaledPackFileName(baseName, index) + settings.atlasExtension) 77 | } 78 | }) 79 | 80 | // Make task run even if there are no input files 81 | dummy.createNewFile() 82 | @Suppress("LeakingThis") from(temporaryDir) { 83 | it.include(dummy.name) 84 | } 85 | @Suppress("LeakingThis") into(dummy) 86 | 87 | } 88 | 89 | fun settings(closure: Closure): TexturePacker.Settings = settings.configure(closure) 90 | 91 | fun settings(closure: TexturePacker.Settings.() -> Unit): TexturePacker.Settings = settings.apply(closure) 92 | 93 | @Suppress("unused") 94 | fun solid(closure: Closure): Boolean = solidSpecs.add(SolidColorSpec().configure(closure)) 95 | 96 | @Suppress("unused") 97 | fun solid(closure: SolidColorSpec.() -> Unit): Boolean = solidSpecs.add(SolidColorSpec().apply(closure)) 98 | 99 | @Input 100 | internal fun getSolidColorSpecs(): String = solidSpecs.joinToString { it.asString() } 101 | 102 | override fun createCopyAction(): CopyAction = CopyAction { stream -> 103 | 104 | if (solidSpecs.isEmpty()) { 105 | if (inputs.files.filter { it.absolutePath != dummy.absolutePath }.isEmpty) { 106 | return@CopyAction DID_NO_WORK 107 | } 108 | } 109 | 110 | getDestinationDir()?.let { destinationDir -> 111 | 112 | temporaryDir.deleteRecursively() 113 | 114 | if (usePackJson != true) { 115 | exclude("**/pack.json") 116 | } 117 | 118 | val fileCopyAction = FileCopyAction(fileLookup.getFileResolver(temporaryDir)) 119 | val copyDidWork = fileCopyAction.execute(stream) 120 | 121 | createSolidTextures(temporaryDir) 122 | 123 | settingsFile?.let { 124 | settings = Json().fromJson(TexturePacker.Settings::class.java, FileReader(it)) 125 | } 126 | 127 | val outputFileName = packFileName + (settings.atlasExtension ?: ".atlas") 128 | TexturePacker.process(settings, temporaryDir.absolutePath, destinationDir.absolutePath, outputFileName) 129 | 130 | if (copyDidWork.didWork || solidSpecs.isNotEmpty()) { 131 | return@CopyAction DID_WORK 132 | } else { 133 | return@CopyAction DID_NO_WORK 134 | } 135 | } ?: throw GradleException("Missing 'into' parameter") 136 | 137 | } 138 | 139 | @Internal 140 | fun getDestinationDir(): File? = rootSpec.destinationDir.takeIf { it.absolutePath != dummy.absolutePath } 141 | 142 | override fun createRootSpec(): DestinationRootCopySpec = 143 | instantiator.newInstance(DestinationRootCopySpec::class.java, fileResolver, super.createRootSpec()) 144 | 145 | override fun getRootSpec(): DestinationRootCopySpec = super.getRootSpec() as DestinationRootCopySpec 146 | 147 | private fun createSolidTextures(targetDir: File) { 148 | 149 | solidSpecs.forEach { solidSpec -> 150 | 151 | if (solidSpec.name == null) { 152 | throw GradleException("No name specified for solid color texture specification ($solidSpec)") 153 | } 154 | 155 | val outputFile = File(targetDir, solidSpec.name + ".png") 156 | 157 | createSolidColorImage(outputFile, solidSpec.color, solidSpec.width, solidSpec.height) 158 | } 159 | 160 | } 161 | 162 | companion object { 163 | 164 | private val SETTINGS_TO_IGNORE = listOf("fast", "silent", "limitMemory", "ignore") 165 | 166 | @JvmStatic 167 | @JvmOverloads 168 | @Deprecated("Use packSettings() from utils.Utils") 169 | fun createSettings( 170 | baseSettings: TexturePacker.Settings? = null, 171 | closure: Closure 172 | ): TexturePacker.Settings { 173 | val settings = TexturePacker.Settings() 174 | baseSettings?.let { settings.set(it) } 175 | settings.configure(closure) 176 | return settings 177 | } 178 | 179 | @JvmStatic 180 | @JvmOverloads 181 | @Deprecated("Use packSettings() from utils.Utils") 182 | fun createSettings( 183 | baseSettings: TexturePacker.Settings? = null, 184 | closure: TexturePacker.Settings.() -> Unit 185 | ): TexturePacker.Settings { 186 | val settings = TexturePacker.Settings() 187 | baseSettings?.let { settings.set(it) } 188 | settings.apply(closure) 189 | return settings 190 | } 191 | 192 | } 193 | 194 | } 195 | -------------------------------------------------------------------------------- /src/main/kotlin/com/github/blueboxware/gdxplugin/utils/FontGenerator.kt: -------------------------------------------------------------------------------- 1 | package com.github.blueboxware.gdxplugin.utils 2 | 3 | import com.badlogic.gdx.ApplicationAdapter 4 | import com.badlogic.gdx.Gdx 5 | import com.badlogic.gdx.backends.lwjgl3.Lwjgl3Application 6 | import com.badlogic.gdx.backends.lwjgl3.Lwjgl3ApplicationConfiguration 7 | import com.badlogic.gdx.tools.hiero.BMFontUtil 8 | import com.badlogic.gdx.tools.hiero.HieroSettings 9 | import com.badlogic.gdx.tools.hiero.unicodefont.UnicodeFont 10 | import com.badlogic.gdx.tools.hiero.unicodefont.effects.ConfigurableEffect 11 | import java.awt.Font 12 | import java.io.File 13 | import java.lang.Thread.sleep 14 | import kotlin.system.exitProcess 15 | 16 | /* 17 | * Copyright 2018 Blue Box Ware 18 | * 19 | * Licensed under the Apache License, Version 2.0 (the "License"); 20 | * you may not use this file except in compliance with the License. 21 | * You may obtain a copy of the License at 22 | * 23 | * http://www.apache.org/licenses/LICENSE-2.0 24 | * 25 | * Unless required by applicable law or agreed to in writing, software 26 | * distributed under the License is distributed on an "AS IS" BASIS, 27 | * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. 28 | * See the License for the specific language governing permissions and 29 | * limitations under the License. 30 | */ 31 | internal class FontGenerator( 32 | private val settingsFile: String, 33 | private val outputSpecs: List> 34 | ): ApplicationAdapter() { 35 | 36 | override fun create() { 37 | Gdx.graphics.isContinuousRendering = true 38 | } 39 | 40 | override fun render() { 41 | 42 | try { 43 | 44 | for ((size, outputFileName) in outputSpecs) { 45 | 46 | val hieroSettings = HieroSettings(settingsFile) 47 | val bold = hieroSettings.isBold 48 | val italic = hieroSettings.isItalic 49 | 50 | val unicodeFont = if (hieroSettings.isFont2Active) { 51 | val fontFile = hieroSettings.font2File 52 | UnicodeFont(fontFile, size, bold, italic) 53 | } else { 54 | val fontName = hieroSettings.fontName 55 | val font = Font.decode(fontName) 56 | UnicodeFont(font, size, bold, italic) 57 | } 58 | 59 | unicodeFont.mono = hieroSettings.isMono 60 | unicodeFont.gamma = hieroSettings.gamma 61 | unicodeFont.paddingTop = hieroSettings.paddingTop 62 | unicodeFont.paddingBottom = hieroSettings.paddingBottom 63 | unicodeFont.paddingLeft = hieroSettings.paddingLeft 64 | unicodeFont.paddingRight = hieroSettings.paddingRight 65 | unicodeFont.paddingAdvanceX = hieroSettings.paddingAdvanceX 66 | unicodeFont.paddingAdvanceY = hieroSettings.paddingAdvanceY 67 | unicodeFont.glyphPageWidth = hieroSettings.glyphPageWidth 68 | unicodeFont.glyphPageHeight = hieroSettings.glyphPageHeight 69 | unicodeFont.renderType = UnicodeFont.RenderType.values()[hieroSettings.renderType] 70 | 71 | for (effect in hieroSettings.effects) { 72 | val configurableEffect = effect as ConfigurableEffect 73 | unicodeFont.effects.add(configurableEffect) 74 | } 75 | 76 | unicodeFont.addGlyphs(hieroSettings.glyphText) 77 | 78 | val bmFont = BMFontUtil(unicodeFont) 79 | bmFont.save(File(outputFileName)) 80 | 81 | } 82 | } catch (e: Exception) { 83 | println(e.message) 84 | System.err.println("Could not create bitmap font: " + e.message) 85 | e.printStackTrace() 86 | } finally { 87 | Gdx.app.exit() 88 | } 89 | 90 | } 91 | 92 | companion object { 93 | 94 | @JvmStatic 95 | fun main(args : Array) { 96 | val settingsFile = args[0] 97 | val outputSpecs = args.drop(1).map { 98 | val splitted = it.split(':', limit = 2) 99 | Pair(splitted[0].toInt(), splitted[1]) 100 | } 101 | 102 | val fontCreator = FontGenerator(settingsFile, outputSpecs) 103 | val config = Lwjgl3ApplicationConfiguration().apply { 104 | disableAudio(true) 105 | setWindowSizeLimits(1, 1, 1, 1) 106 | } 107 | val app = Lwjgl3Application(fontCreator, config) 108 | Gdx.graphics.requestRendering() 109 | app.exit() 110 | exitProcess(0) 111 | } 112 | 113 | } 114 | 115 | } 116 | -------------------------------------------------------------------------------- /src/test/kotlin/ProjectFixture.kt: -------------------------------------------------------------------------------- 1 | import com.badlogic.gdx.files.FileHandle 2 | import com.badlogic.gdx.graphics.g2d.BitmapFont 3 | import org.apache.commons.io.FileUtils 4 | import org.gradle.api.Project 5 | import org.gradle.api.file.CopySpec 6 | import org.gradle.internal.impldep.org.junit.Assert.* 7 | import org.gradle.testfixtures.ProjectBuilder 8 | import org.gradle.testkit.runner.BuildResult 9 | import org.gradle.testkit.runner.GradleRunner 10 | import org.gradle.testkit.runner.TaskOutcome 11 | import java.io.File 12 | import javax.imageio.ImageIO 13 | 14 | /* 15 | * Copyright 2018 Blue Box Ware 16 | * 17 | * Licensed under the Apache License, Version 2.0 (the "License"); 18 | * you may not use this file except in compliance with the License. 19 | * You may obtain a copy of the License at 20 | * 21 | * http://www.apache.org/licenses/LICENSE-2.0 22 | * 23 | * Unless required by applicable law or agreed to in writing, software 24 | * distributed under the License is distributed on an "AS IS" BASIS, 25 | * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. 26 | * See the License for the specific language governing permissions and 27 | * limitations under the License. 28 | */ 29 | internal class ProjectFixture( 30 | private val tempDir: File, private val useKotlin: Boolean = false, addClassPath: Boolean = false 31 | ) { 32 | 33 | companion object { 34 | const val TEST_RELEASED = false 35 | const val gradleVersion: String = "8.4" 36 | const val useConfigurationCache = false 37 | 38 | internal fun getVersion() = if (TEST_RELEASED) getReleasedVersion() else getCurrentVersion() 39 | } 40 | 41 | val testDataDir = File("src/test/testData") 42 | 43 | private var buildFile: File = if (useKotlin) tempDir["build.gradle.kts"] else tempDir["build.gradle"] 44 | 45 | var project: Project = ProjectBuilder.builder().withProjectDir(tempDir).build() 46 | 47 | var input: File = tempDir["in"] 48 | var output: File = tempDir["out"] 49 | var expected: File = testDataDir["results"] 50 | 51 | private var latestBuildResult: BuildResult? = null 52 | private var latestTask: String? = null 53 | 54 | private val buildFileHeader = if (useKotlin) "" else """ 55 | ${ 56 | if (addClassPath && !TEST_RELEASED) """ 57 | buildscript { 58 | repositories { 59 | mavenLocal() 60 | mavenCentral() 61 | } 62 | dependencies { 63 | classpath "com.github.blueboxware:LibGDXGradlePlugin:${getVersion()}" 64 | } 65 | } 66 | """ else "" 67 | } 68 | 69 | plugins { 70 | id 'com.github.blueboxware.gdx' version '${getVersion()}' 71 | } 72 | """ 73 | 74 | init { 75 | if (useKotlin && !TEST_RELEASED) { 76 | 77 | tempDir["settings.gradle.kts"].writeText( 78 | """ 79 | pluginManagement { 80 | repositories { 81 | mavenLocal() 82 | mavenCentral() 83 | } 84 | } 85 | """.trimIndent() 86 | ) 87 | } 88 | } 89 | 90 | fun copyFiles(f: CopySpec.() -> Unit) { 91 | project.copy { 92 | it.f() 93 | it.exclude(expected.name) 94 | it.exclude("readme") 95 | it.into(input) 96 | } 97 | } 98 | 99 | fun addFile(fileName: String) { 100 | project.copy { copySpec -> 101 | copySpec.from(testDataDir.absolutePath) { 102 | it.include(fileName) 103 | } 104 | copySpec.into(input) 105 | } 106 | } 107 | 108 | fun buildFile(contents: String, includeHeader: Boolean = true) { 109 | buildFile.writeText((if (includeHeader) buildFileHeader else "") + contents) 110 | } 111 | 112 | fun getBuildFile() = buildFile.readText().removePrefix(buildFileHeader) 113 | 114 | fun build(taskName: String? = null, vararg extraArguments: String, shouldFail: Boolean = false): BuildResult { 115 | val args = extraArguments.toMutableList() 116 | taskName?.let { args.add(taskName) } 117 | latestTask = taskName 118 | val runner = GradleRunner.create().apply { 119 | // https://github.com/gradle/kotlin-dsl/issues/492 120 | if (!useKotlin && !TEST_RELEASED) { 121 | withPluginClasspath() 122 | } 123 | }.withProjectDir(tempDir).withGradleVersion(gradleVersion) 124 | .withArguments( 125 | "-b${buildFile.name}", 126 | "--stacktrace", 127 | "--warning-mode", 128 | "all", 129 | if (useConfigurationCache) "--configuration-cache" else "--no-configuration-cache", 130 | *args.toTypedArray() 131 | ) 132 | .withDebug(!useConfigurationCache) 133 | latestBuildResult = if (shouldFail) { 134 | runner.buildAndFail() 135 | } else { 136 | runner.build() 137 | } 138 | return latestBuildResult ?: throw AssertionError("No") 139 | } 140 | 141 | fun assertBuildOutputContains(vararg strings: String) = 142 | latestBuildResult?.output?.let { output -> assertTrue(output, strings.any { output.contains(it) }) } 143 | ?: throw AssertionError("No build output") 144 | 145 | fun assertBuildSuccess(task: String = latestTask ?: throw AssertionError()) = 146 | assertEquals(TaskOutcome.SUCCESS, latestBuildResult?.task(task.prefixIfNecessary(":"))?.outcome) 147 | 148 | fun assertBuildFailure(errorText: String? = null, task: String = latestTask ?: throw AssertionError()) { 149 | assertEquals(TaskOutcome.FAILED, latestBuildResult?.task(task.prefixIfNecessary(":"))?.outcome) 150 | errorText?.let { 151 | assertBuildOutputContains(it) 152 | } 153 | } 154 | 155 | fun assertBuildUpToDate(task: String = latestTask ?: throw AssertionError()) = 156 | if (useConfigurationCache) { 157 | assert(latestBuildResult?.output?.contains("Reusing configuration cache.") == true) 158 | } else { 159 | assertEquals(TaskOutcome.UP_TO_DATE, latestBuildResult?.task(task.prefixIfNecessary(":"))?.outcome) 160 | } 161 | 162 | fun assertFileEquals(expectedFileName: String, actualFileName: String) = 163 | assertFileEquals(expected[expectedFileName], output[actualFileName]) 164 | 165 | private fun runExternalCommand(vararg args: String): Pair { 166 | val cmd = Runtime.getRuntime().exec(args) 167 | val result = cmd.waitFor() 168 | return Pair(cmd.inputStream?.reader()?.readText() ?: "", result) 169 | } 170 | 171 | private fun assertFileEquals(expectedFile: File, actualFile: File, showFullContents: Boolean = false) { 172 | if (!expectedFile.exists()) { 173 | expectedFile.createNewFile() 174 | expectedFile.writeText(actualFile.readText()) 175 | } else { 176 | val (diff, result) = runExternalCommand("diff", "-d", expectedFile.absolutePath, actualFile.absolutePath) 177 | val (_, whitespaceOnly) = runExternalCommand( 178 | "diff", 179 | "-w", 180 | expectedFile.absolutePath, 181 | actualFile.absolutePath 182 | ) 183 | 184 | if (result == 1 || expectedFile.readText() != actualFile.readText()) { 185 | 186 | var msg = "Actual file '${actualFile.name}' differs from expected file '${expectedFile.name}':\n" 187 | if (whitespaceOnly == 0) { 188 | msg += "Whitespace only.\n" 189 | } 190 | msg += "=== DIFF =====================================================================================\n" 191 | msg += diff 192 | 193 | if (showFullContents) { 194 | msg += "=== ACTUAL ===================================================================================\n" 195 | msg += actualFile.readText() 196 | msg += "\n\n" 197 | 198 | msg += "=== EXPECTED =================================================================================\n" 199 | msg += expectedFile.readText() 200 | msg += "\n\n" 201 | } 202 | msg += "==============================================================================================\n" 203 | fail(msg) 204 | } 205 | } 206 | } 207 | 208 | fun assertFileEqualsBinary(expectedFileName: String, actualFileName: String) { 209 | assertFileEqualsBinary(expected[expectedFileName], output[actualFileName]) 210 | } 211 | 212 | fun assertFileEqualsBinary(expectedFile: File, actualFile: File) { 213 | checkFilesExist(expectedFile, actualFile) 214 | assertTrue( 215 | "Actual output file '${actualFile.name}' differs from expected output file '${expectedFile.name}", 216 | FileUtils.contentEquals(expectedFile, actualFile) 217 | ) 218 | } 219 | 220 | fun assertFontEquals(expectedFile: String, actualFile: String, checkTextures: Boolean = true) { 221 | assertFontEquals(expected[expectedFile], output[actualFile], checkTextures) 222 | } 223 | 224 | fun assertNinePatchEquals( 225 | expectedSplits: List, expectedPads: List?, expectedImageFile: File, actualImageFile: File 226 | ) { 227 | getRect(actualImageFile).let { 228 | assertEquals(expectedSplits, it.splits.toList()) 229 | if (expectedPads != null) { 230 | assertEquals(expectedPads, it.pads.toList()) 231 | } 232 | val expectedImage = ImageIO.read(expectedImageFile) 233 | val actualImage = it.getImage(null) 234 | assertEquals(expectedImage.width, actualImage.width) 235 | assertEquals(expectedImage.height, actualImage.height) 236 | for (x in 0 until expectedImage.width) { 237 | for (y in 0 until expectedImage.height) { 238 | if (expectedImage.getRGB(x, y) != actualImage.getRGB(x, y)) { 239 | throw AssertionError("Expected image and actual image differ at $x, $y") 240 | } 241 | } 242 | } 243 | } 244 | } 245 | 246 | private fun assertFontEquals(expectedFile: File, actualFile: File, checkTextures: Boolean = true) { 247 | val expectedData = BitmapFont.BitmapFontData(FileHandle(expectedFile), false) 248 | val actualData = BitmapFont.BitmapFontData(FileHandle(actualFile), false) 249 | 250 | assertEquals(expectedData.padTop, actualData.padTop) 251 | assertEquals(expectedData.padBottom, actualData.padBottom) 252 | assertEquals(expectedData.padLeft, actualData.padLeft) 253 | assertEquals(expectedData.padRight, actualData.padRight) 254 | assertEquals(expectedData.lineHeight, actualData.lineHeight) 255 | assertEquals(expectedData.capHeight, actualData.capHeight) 256 | 257 | val expectedGlyphs = expectedData.glyphs.flatMap { it?.toList() ?: listOf() }.filterNotNull() 258 | val actualGlyphs = actualData.glyphs.flatMap { it?.toList() ?: listOf() }.filterNotNull() 259 | assertArrayEquals( 260 | expectedGlyphs.map { it.id }.sorted().toTypedArray(), 261 | actualGlyphs.map { it.id }.sorted().toTypedArray() 262 | ) 263 | 264 | val expImages = expectedData.getImagePaths().map { ImageIO.read(File(it)) } 265 | val actualImages = actualData.getImagePaths().map { ImageIO.read(File(it)) } 266 | 267 | expectedGlyphs.forEach { expGlyph -> 268 | val id = expGlyph.id 269 | val actGlyph = actualData.getGlyph(id.toChar()) 270 | assertEquals("width of $id", expGlyph.width, actGlyph.width) 271 | assertEquals("height of $id", expGlyph.height, actGlyph.height) 272 | assertEquals("xoffset of $id", expGlyph.xoffset, actGlyph.xoffset) 273 | assertEquals("yoffset of $id", expGlyph.yoffset, actGlyph.yoffset) 274 | assertEquals("xadvance of $id", expGlyph.xadvance, actGlyph.xadvance) 275 | assertArrayEquals("kerning of $id", expGlyph.kerning, actGlyph.kerning) 276 | 277 | if (checkTextures) { 278 | for (x in 0 until expGlyph.width) { 279 | for (y in 0 until expGlyph.height) { 280 | if (expImages[expGlyph.page].getRGB(x, y) != actualImages[actGlyph.page].getRGB(x, y)) { 281 | throw AssertionError("Texture for ${expGlyph.id} differs") 282 | } 283 | } 284 | } 285 | } 286 | 287 | } 288 | } 289 | 290 | fun assertFilesExist(vararg fileNames: String) { 291 | fileNames.forEach { 292 | assertTrue("File '$it' doesn't exist", output[it].exists()) 293 | } 294 | } 295 | 296 | private fun checkFilesExist(expectedFile: File, actualFile: File) { 297 | assertTrue("File with expected results doesn't exist ('${expectedFile.absolutePath}')", expectedFile.exists()) 298 | assertTrue("File with actual results doesn't exist ('${actualFile.absolutePath}')", actualFile.exists()) 299 | } 300 | 301 | 302 | } 303 | -------------------------------------------------------------------------------- /src/test/kotlin/TestBitmapFontTask.kt: -------------------------------------------------------------------------------- 1 | import com.github.blueboxware.gdxplugin.GdxPlugin 2 | import io.kotest.core.annotation.EnabledIf 3 | import io.kotest.core.spec.style.BehaviorSpec 4 | import io.kotest.engine.spec.tempdir 5 | 6 | /* 7 | * Copyright 2021 Blue Box Ware 8 | * 9 | * Licensed under the Apache License, Version 2.0 (the "License"); 10 | * you may not use this file except in compliance with the License. 11 | * You may obtain a copy of the License at 12 | * 13 | * http://www.apache.org/licenses/LICENSE-2.0 14 | * 15 | * Unless required by applicable law or agreed to in writing, software 16 | * distributed under the License is distributed on an "AS IS" BASIS, 17 | * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. 18 | * See the License for the specific language governing permissions and 19 | * limitations under the License. 20 | */ 21 | @EnabledIf(NoConfigurationCache::class) 22 | internal object TestBitmapFontTask: BehaviorSpec({ 23 | 24 | lateinit var fixture: ProjectFixture 25 | 26 | beforeContainer { 27 | fixture = ProjectFixture(tempdir(), addClassPath = true) 28 | fixture.addFile("etc/roboto.ttf") 29 | } 30 | 31 | given("a bitmap font task container") { 32 | 33 | beforeContainer { 34 | 35 | fixture.buildFile(""" 36 | 37 | bitmapFonts { 38 | 39 | normal { 40 | 41 | inputFont = file('in/etc/roboto.ttf') 42 | 43 | outputFile = file('out/roboto.fnt') 44 | 45 | size 16 46 | sizes 32, 64 47 | 48 | size 16, "out/custom16.fnt" 49 | size 32, file("out/custom32") 50 | 51 | settings { 52 | renderType = FreeType 53 | } 54 | 55 | } 56 | 57 | arial { 58 | 59 | inputFont = 'Arial Black' 60 | 61 | outputFile = 'out/arial' 62 | 63 | size = 12 64 | sizes = [16, 64] 65 | 66 | characters = "abcdef" 67 | 68 | settings { 69 | 70 | bold = true 71 | italic = false 72 | gamma = 2 73 | paddingTop = 1 74 | paddingBottom = 2 75 | paddingLeft = 3 76 | paddingRight = 4 77 | paddingAdvanceX = 2 78 | paddingAdvanceY = 3 79 | glyphPageWidth = 64 80 | glyphPageHeight = 128 81 | 82 | effects = [ 83 | color { 84 | color = color('0000ff') 85 | }, 86 | shadow { 87 | color = color("#ff0000") 88 | xDistance = 4 89 | } 90 | ] 91 | 92 | } 93 | 94 | } 95 | 96 | } 97 | """) 98 | 99 | } 100 | 101 | `when`("listing tasks") { 102 | 103 | fixture.build("tasks") 104 | 105 | then("should contain the expected tasks") { 106 | fixture.assertBuildOutputContains("generateNormalFont") 107 | fixture.assertBuildOutputContains("generateArialFont") 108 | fixture.assertBuildOutputContains(GdxPlugin.ALL_BM_FONTS_TASK_NAME) 109 | fixture.assertBuildOutputContains(GdxPlugin.ALL_ASSETS_TASK_NAME) 110 | } 111 | 112 | } 113 | 114 | `when`("building") { 115 | 116 | fixture.build("createAllFonts") 117 | 118 | then("should create the correct files") { 119 | 120 | fixture.assertFilesExist( 121 | "roboto16px.fnt", 122 | "roboto16px.png", 123 | "roboto32px.fnt", 124 | "roboto32px.png", 125 | "roboto64px.fnt", 126 | "roboto64px.png", 127 | "arial12px.fnt", 128 | "arial12px.png", 129 | "arial16px.fnt", 130 | "arial16px.png", 131 | "arial64px.fnt", 132 | "arial64px1.png", 133 | "arial64px2.png", 134 | "arial64px3.png", 135 | "custom16.fnt", 136 | "custom16.png", 137 | "custom32.fnt", 138 | "custom32.png" 139 | ) 140 | 141 | } 142 | 143 | then("should create the correct first font") { 144 | 145 | fixture.assertFontEquals("bitmapFont/roboto32px.fnt", "roboto32px.fnt") 146 | 147 | } 148 | 149 | then("should create the correct second font") { 150 | 151 | fixture.assertFontEquals("bitmapFont/arial16px.fnt", "arial16px.fnt") 152 | 153 | } 154 | 155 | } 156 | 157 | `when`("building twice") { 158 | 159 | fixture.build("generateArialFont") 160 | fixture.build("generateArialFont") 161 | 162 | then("should be up-to-date the second time") { 163 | fixture.assertBuildUpToDate() 164 | } 165 | 166 | } 167 | 168 | `when`("building twice and removing one of the .fnt files after the first build") { 169 | 170 | fixture.build("generateNormalFont") 171 | fixture.output["custom32.fnt"].delete() 172 | fixture.build("generateNormalFont") 173 | 174 | then("should build again") { 175 | fixture.assertBuildSuccess() 176 | } 177 | 178 | } 179 | 180 | `when`("building twice and changing one of the sizes after the first build") { 181 | 182 | fixture.build("generateNormalFont") 183 | fixture.buildFile(fixture.getBuildFile().replace("64", "48")) 184 | fixture.build("generateNormalFont") 185 | 186 | then("should build again") { 187 | fixture.assertBuildSuccess() 188 | } 189 | 190 | } 191 | 192 | `when`("building twice and changing one of the output files after the first build") { 193 | 194 | fixture.build("generateNormalFont") 195 | fixture.buildFile(fixture.getBuildFile().replace("custom32", "23motsuc")) 196 | fixture.build("generateNormalFont") 197 | 198 | then("should build again") { 199 | fixture.assertBuildSuccess() 200 | } 201 | 202 | } 203 | 204 | } 205 | 206 | given("a font with outline and shadow effects") { 207 | 208 | beforeContainer { 209 | 210 | fixture.buildFile(""" 211 | 212 | bitmapFonts { 213 | 214 | normal { 215 | 216 | inputFont = file('in/etc/roboto.ttf') 217 | 218 | outputFile = file('out/outlineAndShadow.fnt') 219 | 220 | size 56 221 | 222 | settings { 223 | effects = [ 224 | color { 225 | color = color("ffff00"); 226 | }, 227 | outline { 228 | width = 3 229 | color = color("00ff00") 230 | join = JoinRound 231 | }, 232 | shadow { 233 | color = color("aaaaaa") 234 | opacity = 0.4 235 | xDistance = 4 236 | yDistance = 5 237 | blurKernelSize = 2 238 | blurPasses = 2 239 | } 240 | ] 241 | } 242 | } 243 | } 244 | 245 | """) 246 | 247 | } 248 | 249 | `when`("building") { 250 | 251 | fixture.build("createAllFonts") 252 | 253 | then("should create the correct font files") { 254 | fixture.assertFontEquals("bitmapFont/outlineAndShadow.fnt", "outlineAndShadow.fnt") 255 | } 256 | 257 | } 258 | 259 | } 260 | 261 | given("a font with a distance field effect") { 262 | 263 | beforeContainer { 264 | 265 | fixture.buildFile(""" 266 | 267 | bitmapFonts { 268 | 269 | normal { 270 | 271 | inputFont = file('in/etc/roboto.ttf') 272 | 273 | outputFile = file('out/distanceField.fnt') 274 | 275 | size 32 276 | 277 | settings { 278 | effects = [ 279 | distanceField { 280 | color = color("ff0000") 281 | scale = 32 282 | spread = 4 283 | } 284 | ] 285 | } 286 | } 287 | } 288 | 289 | """) 290 | 291 | } 292 | 293 | `when`("building") { 294 | 295 | fixture.build("createAllFonts") 296 | 297 | then("should create the correct font files") { 298 | fixture.assertFontEquals("bitmapFont/distanceField.fnt", "distanceField.fnt") 299 | } 300 | 301 | } 302 | 303 | } 304 | 305 | given("a font with a gradient effect") { 306 | 307 | beforeContainer { 308 | 309 | fixture.buildFile(""" 310 | 311 | bitmapFonts { 312 | 313 | normal { 314 | 315 | inputFont = file('in/etc/roboto.ttf') 316 | 317 | outputFile = file('out/gradient.fnt') 318 | 319 | size 32 320 | 321 | settings { 322 | effects = [ 323 | gradient { 324 | topColor = color("#00AAAA") 325 | bottomColor = color("ff0000") 326 | offset = 4 327 | scale = 2 328 | cyclic = true 329 | } 330 | ] 331 | } 332 | } 333 | } 334 | 335 | """) 336 | 337 | } 338 | 339 | `when`("building") { 340 | 341 | fixture.build("createAllFonts") 342 | 343 | then("should create the correct font files") { 344 | fixture.assertFontEquals("bitmapFont/gradient.fnt", "gradient.fnt") 345 | } 346 | 347 | } 348 | 349 | `when`("building twice and changing the effect in between") { 350 | 351 | fixture.build("generateNormalFont") 352 | fixture.buildFile(fixture.getBuildFile().replace("true", "false")) 353 | fixture.build("generateNormalFont") 354 | 355 | then("should build again") { 356 | fixture.assertBuildSuccess() 357 | } 358 | 359 | } 360 | 361 | } 362 | 363 | given("a font with a zigzag effect") { 364 | 365 | beforeContainer { 366 | 367 | fixture.buildFile(""" 368 | 369 | import static com.github.blueboxware.gdxplugin.dsl.Constants.* 370 | 371 | bitmapFonts { 372 | 373 | normal { 374 | 375 | inputFont = file('in/etc/roboto.ttf') 376 | 377 | outputFile = file('out/zigzag.fnt') 378 | 379 | size 64 380 | 381 | settings { 382 | effects = [ 383 | color { 384 | color = color("00ffff") 385 | }, 386 | zigzag { 387 | width = 3f 388 | color = color("#FFFF00") 389 | wavelength = 5f 390 | amplitude = 3f 391 | join = JoinMiter 392 | } 393 | ] 394 | } 395 | } 396 | } 397 | 398 | """) 399 | 400 | } 401 | 402 | `when`("building") { 403 | 404 | fixture.build("generateNormalFont") 405 | 406 | then("should create the correct font") { 407 | fixture.assertBuildSuccess() 408 | fixture.assertFontEquals("bitmapFont/zigzag.fnt", "zigzag.fnt") 409 | } 410 | 411 | } 412 | 413 | } 414 | 415 | }) 416 | -------------------------------------------------------------------------------- /src/test/kotlin/TestConfigCacheError.kt: -------------------------------------------------------------------------------- 1 | import io.kotest.core.annotation.EnabledIf 2 | import io.kotest.core.spec.style.BehaviorSpec 3 | import io.kotest.engine.spec.tempdir 4 | 5 | @EnabledIf(ConfigurationCache::class) 6 | internal object TestConfigCacheError : BehaviorSpec({ 7 | 8 | lateinit var fixture: ProjectFixture 9 | 10 | beforeContainer { 11 | fixture = ProjectFixture(tempdir(), addClassPath = true) 12 | fixture.addFile("etc/roboto.ttf") 13 | } 14 | 15 | given("a bitmap font task container") { 16 | 17 | beforeContainer { 18 | 19 | fixture.buildFile( 20 | """ 21 | 22 | bitmapFonts { 23 | 24 | normal { 25 | 26 | inputFont = file('in/etc/roboto.ttf') 27 | 28 | outputFile = file('out/roboto.fnt') 29 | 30 | } 31 | 32 | 33 | 34 | } 35 | """ 36 | ) 37 | 38 | } 39 | 40 | `when`("building") { 41 | 42 | fixture.build("createAllFonts", shouldFail = true) 43 | 44 | then("should give an error") { 45 | 46 | fixture.assertBuildFailure(task = "generateNormalFont") 47 | fixture.assertBuildOutputContains( 48 | "BitmapFont tasks are not compatible with Gradle's configuration cache." 49 | 50 | ) 51 | 52 | } 53 | } 54 | } 55 | 56 | }) 57 | -------------------------------------------------------------------------------- /src/test/kotlin/TestDistanceFieldTask.kt: -------------------------------------------------------------------------------- 1 | import com.github.blueboxware.gdxplugin.GdxPlugin 2 | import io.kotest.core.spec.style.BehaviorSpec 3 | import io.kotest.engine.spec.tempdir 4 | import org.gradle.internal.impldep.junit.framework.TestCase 5 | 6 | 7 | /* 8 | * Copyright 2021 Blue Box Ware 9 | * 10 | * Licensed under the Apache License, Version 2.0 (the "License"); 11 | * you may not use this file except in compliance with the License. 12 | * You may obtain a copy of the License at 13 | * 14 | * http://www.apache.org/licenses/LICENSE-2.0 15 | * 16 | * Unless required by applicable law or agreed to in writing, software 17 | * distributed under the License is distributed on an "AS IS" BASIS, 18 | * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. 19 | * See the License for the specific language governing permissions and 20 | * limitations under the License. 21 | */ 22 | internal object TestDistanceFieldTask: BehaviorSpec({ 23 | 24 | lateinit var fixture: ProjectFixture 25 | 26 | beforeContainer { 27 | fixture = ProjectFixture(tempdir()) 28 | } 29 | 30 | given("a minimal df task") { 31 | 32 | beforeContainer { 33 | 34 | fixture.buildFile( 35 | """ 36 | distanceFields { 37 | 'foo' { 38 | inputFile = file('in/images1/empty.png') 39 | } 40 | } 41 | """ 42 | ) 43 | fixture.addFile("images1/empty.png") 44 | 45 | } 46 | 47 | `when`("listing tasks") { 48 | 49 | fixture.build("tasks") 50 | 51 | then("should contain the declared task") { 52 | fixture.assertBuildOutputContains("generateFooDistanceField") 53 | } 54 | 55 | } 56 | 57 | `when`("building") { 58 | 59 | fixture.build("generateFooDistanceField") 60 | 61 | then("should create the expected image") { 62 | fixture.assertFileEqualsBinary( 63 | fixture.expected["distanceField/df_white.png"], 64 | fixture.input["images1/empty-df.png"] 65 | ) 66 | } 67 | 68 | } 69 | 70 | `when`("building twice") { 71 | 72 | fixture.build("generateFooDistanceField") 73 | fixture.build("generateFooDistanceField") 74 | 75 | then("should be up-to-date the second time") { 76 | fixture.assertBuildUpToDate() 77 | } 78 | 79 | } 80 | 81 | `when`("changing the color after a build") { 82 | 83 | fixture.build("generateFooDistanceField") 84 | fixture.buildFile( 85 | """ 86 | distanceFields { 87 | 'foo' { 88 | inputFile = file('in/images1/empty.png') 89 | color = "ff0000" 90 | } 91 | } 92 | """ 93 | ) 94 | fixture.build("generateFooDistanceField") 95 | 96 | then("should build again") { 97 | fixture.assertBuildSuccess() 98 | } 99 | 100 | then("should create the expected image") { 101 | fixture.assertFileEqualsBinary( 102 | fixture.expected["distanceField/df_red.png"], 103 | fixture.input["images1/empty-df.png"] 104 | ) 105 | } 106 | 107 | } 108 | 109 | `when`("changing the output file argument after a build") { 110 | 111 | fixture.build("generateFooDistanceField") 112 | fixture.buildFile( 113 | """ 114 | distanceFields { 115 | 'foo' { 116 | inputFile = file('in/images1/empty.png') 117 | outputFile = file('out/foo/df.png') 118 | } 119 | } 120 | """ 121 | ) 122 | fixture.build("generateFooDistanceField") 123 | 124 | then("should build again") { 125 | fixture.assertBuildSuccess() 126 | } 127 | 128 | then("should create image at the expected location") { 129 | fixture.assertFileEqualsBinary("distanceField/df_white.png", "foo/df.png") 130 | } 131 | 132 | } 133 | 134 | `when`("changing the format after a build") { 135 | 136 | fixture.build("generateFooDistanceField") 137 | fixture.buildFile( 138 | """ 139 | distanceFields { 140 | 'foo' { 141 | inputFile = file('in/images1/empty.png') 142 | outputFormat = '.gif' 143 | } 144 | } 145 | """ 146 | ) 147 | fixture.build("generateFooDistanceField") 148 | 149 | then("should build again") { 150 | fixture.assertBuildSuccess() 151 | } 152 | 153 | then("should use the correct output filename") { 154 | TestCase.assertTrue(fixture.input["images1/empty-df.gif"].exists()) 155 | } 156 | 157 | } 158 | 159 | `when`("removing the output file after a build") { 160 | 161 | fixture.build("generateFooDistanceField") 162 | fixture.input["images1/empty-df.png"].delete() 163 | fixture.build("generateFooDistanceField") 164 | 165 | then("should build again") { 166 | fixture.assertBuildSuccess() 167 | } 168 | 169 | } 170 | 171 | `when`("running ${GdxPlugin.ALL_DF_FIELDS_TASK_NAME}") { 172 | 173 | fixture.build(GdxPlugin.ALL_DF_FIELDS_TASK_NAME) 174 | 175 | then("should run the df task") { 176 | fixture.assertBuildSuccess() 177 | } 178 | 179 | } 180 | 181 | } 182 | 183 | given("a df task with all arguments") { 184 | 185 | beforeContainer { 186 | 187 | fixture.buildFile( 188 | """ 189 | distanceFields { 190 | 'foo' { 191 | inputFile = file('in/etc/wat.jpg') 192 | downscale = 8 193 | spread = 12 194 | color = 'ff00ff' 195 | outputFormat = ".png" 196 | } 197 | } 198 | """ 199 | ) 200 | fixture.addFile("etc/wat.jpg") 201 | 202 | } 203 | 204 | `when`("build") { 205 | 206 | fixture.build("generateFooDistanceField") 207 | 208 | then("should build") { 209 | fixture.assertBuildSuccess() 210 | } 211 | 212 | then("should create a correct result") { 213 | fixture.assertFileEqualsBinary(fixture.expected["distanceField/wat-df.png"], fixture.input["etc/wat-df.png"]) 214 | } 215 | 216 | } 217 | 218 | `when`("changing the spread after building") { 219 | 220 | fixture.build("generateFooDistanceField") 221 | fixture.buildFile(fixture.getBuildFile().replace("12", "24")) 222 | fixture.build("generateFooDistanceField") 223 | 224 | then("should build again") { 225 | fixture.assertBuildSuccess() 226 | } 227 | 228 | } 229 | 230 | } 231 | 232 | given("a df task with a jpg output extension") { 233 | 234 | beforeContainer { 235 | 236 | fixture.buildFile( 237 | """ 238 | distanceFields { 239 | 'foo' { 240 | inputFile = file('in/etc/wat.jpg') 241 | outputFile = file('out/df.jpg') 242 | spread = 16 243 | downscale = 8 244 | } 245 | } 246 | """ 247 | ) 248 | fixture.addFile("etc/wat.jpg") 249 | 250 | } 251 | 252 | `when`("building") { 253 | 254 | val isOpenJDK = System.getProperty("java.vm.name").contains("OpenJDK") 255 | 256 | fixture.build("generateFooDistanceField", shouldFail = isOpenJDK) 257 | 258 | then("should fail on OpenJDK, create the correct image otherwise") { 259 | if (isOpenJDK) { 260 | fixture.assertBuildFailure() 261 | fixture.assertBuildOutputContains( 262 | "does not have a writer for image type", 263 | "does not support creating jpegs with alpha" 264 | ) 265 | } else { 266 | fixture.assertFileEqualsBinary("distanceField/df_wat.jpg", "df.jpg") 267 | } 268 | } 269 | 270 | } 271 | 272 | } 273 | 274 | given("a df task with a specified format") { 275 | 276 | beforeContainer { 277 | 278 | fixture.buildFile( 279 | """ 280 | distanceFields { 281 | 'foo' { 282 | inputFile = file('in/images1/empty.png') 283 | outputFormat = 'gif' 284 | } 285 | } 286 | """ 287 | ) 288 | fixture.addFile("images1/empty.png") 289 | 290 | } 291 | 292 | `when`("removing the output file after a build") { 293 | 294 | fixture.build("generateFooDistanceField") 295 | fixture.input["images1/empty-df.gif"].delete() 296 | fixture.build("generateFooDistanceField") 297 | 298 | then("should build again") { 299 | fixture.assertBuildSuccess() 300 | } 301 | 302 | } 303 | 304 | `when`("changing the output format after a build") { 305 | 306 | fixture.build("generateFooDistanceField") 307 | fixture.buildFile(fixture.getBuildFile().replace("gif", "png")) 308 | fixture.build("generateFooDistanceField") 309 | 310 | then("should build again") { 311 | fixture.assertBuildSuccess() 312 | } 313 | 314 | } 315 | 316 | } 317 | 318 | }) 319 | -------------------------------------------------------------------------------- /src/test/kotlin/TestEffectsKotlin.kt: -------------------------------------------------------------------------------- 1 | import io.kotest.core.annotation.EnabledIf 2 | import io.kotest.core.spec.style.BehaviorSpec 3 | import io.kotest.engine.spec.tempdir 4 | 5 | /* 6 | * Copyright 2021 Blue Box Ware 7 | * 8 | * Licensed under the Apache License, Version 2.0 (the "License"); 9 | * you may not use this file except in compliance with the License. 10 | * You may obtain a copy of the License at 11 | * 12 | * http://www.apache.org/licenses/LICENSE-2.0 13 | * 14 | * Unless required by applicable law or agreed to in writing, software 15 | * distributed under the License is distributed on an "AS IS" BASIS, 16 | * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. 17 | * See the License for the specific language governing permissions and 18 | * limitations under the License. 19 | */ 20 | @EnabledIf(NoConfigurationCache::class) 21 | internal object TestEffectsKotlin: BehaviorSpec({ 22 | 23 | lateinit var fixture: ProjectFixture 24 | 25 | val buildFile = """ 26 | plugins { 27 | id("com.github.blueboxware.gdx") version "${ProjectFixture.getVersion()}" 28 | } 29 | 30 | bitmapFonts { 31 | create("roboto") { 32 | inputFont = file("in/etc/roboto.ttf") 33 | outputFile = file("out/.fnt") 34 | sizes(64) 35 | settings { 36 | effects = listOf( 37 | color { 38 | color = color("00ffff") 39 | }, 40 | 41 | ) 42 | } 43 | } 44 | } 45 | """ 46 | 47 | beforeContainer { 48 | fixture = ProjectFixture(tempdir(), useKotlin = true, addClassPath = true) 49 | fixture.addFile("etc/roboto.ttf") 50 | } 51 | 52 | given("an outline effect") { 53 | 54 | beforeContainer { 55 | 56 | fixture.buildFile(buildFile.replace("", """ 57 | outline { 58 | width = 4f 59 | color = color("#FFFF00") 60 | join = JoinRound 61 | } 62 | """).replace("", "outline")) 63 | 64 | } 65 | 66 | `when`("building") { 67 | 68 | fixture.build("generateRobotoFont") 69 | 70 | then("should create the correct font") { 71 | fixture.assertBuildSuccess() 72 | fixture.assertFontEquals("bitmapFont/outline.fnt", "outline.fnt") 73 | } 74 | 75 | } 76 | 77 | } 78 | 79 | given("a wobble effect") { 80 | 81 | beforeContainer { 82 | 83 | fixture.buildFile(buildFile.replace("", """ 84 | wobble { 85 | width = 4f 86 | color = color("#FFFF00") 87 | detail = 8f 88 | amplitude = 4f 89 | } 90 | """).replace("", "wobble")) 91 | 92 | } 93 | 94 | `when`("building") { 95 | 96 | fixture.build("generateRobotoFont") 97 | 98 | then("should create the correct font") { 99 | fixture.assertBuildSuccess() 100 | fixture.assertFontEquals("bitmapFont/wobble.fnt", "wobble.fnt", checkTextures = false) 101 | } 102 | 103 | } 104 | 105 | } 106 | 107 | given("a zigzag effect") { 108 | 109 | beforeContainer { 110 | 111 | fixture.buildFile(buildFile.replace("", """ 112 | zigzag { 113 | width = 3f 114 | color = color("#FFFF00") 115 | wavelength = 5f 116 | amplitude = 3f 117 | join = JoinMiter 118 | } 119 | """).replace("", "zigzag")) 120 | 121 | } 122 | 123 | `when`("building") { 124 | 125 | fixture.build("generateRobotoFont") 126 | 127 | then("should create the correct font") { 128 | fixture.assertBuildSuccess() 129 | fixture.assertFontEquals("bitmapFont/zigzag.fnt", "zigzag.fnt") 130 | } 131 | 132 | } 133 | 134 | } 135 | 136 | given("a distance field effect") { 137 | 138 | beforeContainer { 139 | 140 | fixture.buildFile(""" 141 | import com.github.blueboxware.gdxplugin.tasks.BitmapFont 142 | 143 | plugins { 144 | id("com.github.blueboxware.gdx") version "${ProjectFixture.getVersion()}" 145 | } 146 | 147 | val bitmapFonts: NamedDomainObjectContainer by extensions 148 | 149 | bitmapFonts.invoke { 150 | create("roboto") { 151 | inputFont = file("in/etc/roboto.ttf") 152 | outputFile = file("out/distanceField.fnt") 153 | sizes(32) 154 | settings { 155 | effects = listOf( 156 | distanceField { 157 | color = color("ff0000") 158 | scale = 32 159 | spread = 4f 160 | } 161 | ) 162 | } 163 | } 164 | } 165 | """) 166 | 167 | } 168 | 169 | `when`("building") { 170 | 171 | fixture.build("generateRobotoFont") 172 | 173 | then("should create the correct font") { 174 | fixture.assertBuildSuccess() 175 | fixture.assertFontEquals("bitmapFont/distanceField.fnt", "distanceField.fnt") 176 | } 177 | 178 | } 179 | 180 | } 181 | 182 | }) 183 | -------------------------------------------------------------------------------- /src/test/kotlin/TestNinePatchTask.kt: -------------------------------------------------------------------------------- 1 | import com.github.blueboxware.gdxplugin.GdxPlugin 2 | import io.kotest.core.spec.style.BehaviorSpec 3 | import io.kotest.engine.spec.tempdir 4 | 5 | 6 | /* 7 | * Copyright 2021 Blue Box Ware 8 | * 9 | * Licensed under the Apache License, Version 2.0 (the "License"); 10 | * you may not use this file except in compliance with the License. 11 | * You may obtain a copy of the License at 12 | * 13 | * http://www.apache.org/licenses/LICENSE-2.0 14 | * 15 | * Unless required by applicable law or agreed to in writing, software 16 | * distributed under the License is distributed on an "AS IS" BASIS, 17 | * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. 18 | * See the License for the specific language governing permissions and 19 | * limitations under the License. 20 | */ 21 | internal object TestNinePatchTask: BehaviorSpec({ 22 | 23 | lateinit var fixture: ProjectFixture 24 | 25 | beforeContainer { 26 | fixture = ProjectFixture(tempdir()) 27 | fixture.copyFiles { 28 | from(fixture.testDataDir.absolutePath) { 29 | include("ninePatch/") 30 | } 31 | } 32 | } 33 | 34 | given("a ninepatch with only defaults") { 35 | 36 | beforeContainer { 37 | fixture.buildFile(""" 38 | ninePatch { 39 | np { 40 | image = file('in/ninePatch/red.png') 41 | } 42 | } 43 | """) 44 | } 45 | 46 | `when`("building") { 47 | 48 | fixture.build("generateNpNinePatch") 49 | 50 | then("should create the correct ninepatch") { 51 | fixture.assertBuildSuccess() 52 | fixture.assertNinePatchEquals( 53 | listOf(0, 0, 0, 0), 54 | null, 55 | fixture.input["ninePatch/red.png"], 56 | fixture.input["ninePatch/red.9.png"] 57 | ) 58 | 59 | } 60 | 61 | } 62 | 63 | `when`("building twice") { 64 | 65 | fixture.build("generateNpNinePatch") 66 | fixture.build("generateNpNinePatch") 67 | 68 | then("should be up-to-date the second time") { 69 | fixture.assertBuildUpToDate() 70 | } 71 | 72 | } 73 | 74 | `when`("building twice and adding a split") { 75 | 76 | fixture.build("generateNpNinePatch") 77 | fixture.buildFile(""" 78 | ninePatch { 79 | np { 80 | image = file('in/ninePatch/red.png') 81 | top = 1 82 | } 83 | } 84 | """) 85 | fixture.build("generateNpNinePatch") 86 | 87 | then("should build again the second time") { 88 | fixture.assertBuildSuccess() 89 | } 90 | 91 | } 92 | 93 | } 94 | 95 | given("a ninepatch with custom splits and default paddings") { 96 | 97 | beforeContainer { 98 | fixture.buildFile(""" 99 | ninePatch { 100 | np { 101 | image = file('in/ninePatch/red.jpg') 102 | output = file('out/red.9.png') 103 | top = 1 104 | bottom = 2 105 | left = 3 106 | right = 4 107 | paddingTop = 3 108 | } 109 | } 110 | """) 111 | } 112 | 113 | `when`("building") { 114 | 115 | fixture.build("generateNpNinePatch") 116 | 117 | then("should generate the correct ninepatch") { 118 | fixture.assertNinePatchEquals( 119 | listOf(3, 4, 1, 2), 120 | listOf(3, 4, 3, 2), 121 | fixture.input["ninePatch/red.jpg"], 122 | fixture.output["red.9.png"] 123 | ) 124 | } 125 | 126 | } 127 | 128 | `when`("building twice and changing a split in between") { 129 | 130 | fixture.build("generateNpNinePatch") 131 | fixture.buildFile(fixture.getBuildFile().replace("4", "3")) 132 | fixture.build("generateNpNinePatch") 133 | 134 | then("should build again") { 135 | fixture.assertBuildSuccess() 136 | } 137 | 138 | } 139 | 140 | } 141 | 142 | given("a ninepatch with custom paddings") { 143 | 144 | beforeContainer { 145 | fixture.buildFile(""" 146 | ninePatch { 147 | np { 148 | image = file('in/ninePatch/red.png') 149 | output = file('out/red.9.png') 150 | paddingTop = 3 151 | paddingBottom = 4 152 | paddingRight = 2 153 | paddingLeft = 5 154 | } 155 | } 156 | """) 157 | } 158 | 159 | `when`("building") { 160 | 161 | fixture.build("generateNpNinePatch") 162 | 163 | then("should generate the correct ninepatch") { 164 | fixture.assertNinePatchEquals( 165 | listOf(0, 0, 0, 0), 166 | listOf(5, 2, 3, 4), 167 | fixture.input["ninePatch/red.png"], 168 | fixture.output["red.9.png"] 169 | ) 170 | } 171 | 172 | } 173 | 174 | `when`("building twice and changing the padding in between") { 175 | 176 | fixture.build("generateNpNinePatch") 177 | fixture.buildFile(fixture.getBuildFile().replace("3", "1")) 178 | fixture.build("generateNpNinePatch") 179 | 180 | then("should build again") { 181 | fixture.assertBuildSuccess() 182 | } 183 | 184 | } 185 | 186 | } 187 | 188 | given("a few ninePatches with auto") { 189 | 190 | beforeContainer { 191 | fixture.buildFile(""" 192 | ninePatch { 193 | np1 { 194 | image = file('in/ninePatch/overlap.png') 195 | auto = true 196 | } 197 | np2 { 198 | image = file('in/ninePatch/thingy.png') 199 | auto = true 200 | } 201 | np3 { 202 | image = file('in/ninePatch/resizable.png') 203 | auto = true 204 | } 205 | np4 { 206 | image = file('in/ninePatch/rect.png') 207 | auto = true 208 | } 209 | } 210 | """) 211 | } 212 | 213 | `when`("building") { 214 | 215 | fixture.build(GdxPlugin.ALL_NINE_PATCHES_TASK_NAME) 216 | 217 | then("should create the correct nine patches") { 218 | fixture.assertNinePatchEquals( 219 | listOf(40, 40, 40, 40), 220 | null, 221 | fixture.input["ninePatch/overlap.png"], 222 | fixture.input["ninePatch/overlap.9.png"] 223 | ) 224 | fixture.assertNinePatchEquals( 225 | listOf(56, 56, 56, 56), 226 | null, 227 | fixture.input["ninePatch/thingy.png"], 228 | fixture.input["ninePatch/thingy.9.png"] 229 | ) 230 | fixture.assertNinePatchEquals( 231 | listOf(12, 13, 1, 19), 232 | null, 233 | fixture.input["ninePatch/resizable.png"], 234 | fixture.input["ninePatch/resizable.9.png"] 235 | ) 236 | fixture.assertNinePatchEquals( 237 | listOf(8, 8, 8, 8), 238 | null, 239 | fixture.input["ninePatch/rect.png"], 240 | fixture.input["ninePatch/rect.9.png"] 241 | ) 242 | } 243 | 244 | } 245 | 246 | } 247 | 248 | given("a ninepatch with auto and custom center") { 249 | 250 | beforeContainer { 251 | fixture.buildFile(""" 252 | ninePatch { 253 | np { 254 | image = file('in/ninePatch/resizable.png') 255 | auto = true 256 | centerX = 5 257 | centerY = 76 258 | paddingLeft = 2 259 | } 260 | } 261 | """) 262 | } 263 | 264 | `when`("building") { 265 | 266 | fixture.build(GdxPlugin.ALL_NINE_PATCHES_TASK_NAME) 267 | 268 | then("should create the correct nine patch") { 269 | fixture.assertNinePatchEquals( 270 | listOf(1, 19, 75, 7), 271 | listOf(2, 19, 75, 7), 272 | fixture.input["ninePatch/resizable.png"], 273 | fixture.input["ninePatch/resizable.9.png"] 274 | ) 275 | } 276 | 277 | } 278 | 279 | } 280 | 281 | given("a few nine patches with auto and fuzziness") { 282 | 283 | beforeContainer { 284 | fixture.buildFile(""" 285 | ninePatch { 286 | np1 { 287 | image = file('in/ninePatch/document.png') 288 | auto = true 289 | fuzziness = 70 290 | } 291 | np2 { 292 | image = file('in/ninePatch/gradient.jpg') 293 | auto = true 294 | fuzziness = 70 295 | } 296 | } 297 | """) 298 | } 299 | 300 | `when`("building") { 301 | 302 | fixture.build(GdxPlugin.ALL_NINE_PATCHES_TASK_NAME) 303 | 304 | then("should create the correct nine patches") { 305 | fixture.assertNinePatchEquals( 306 | listOf(5, 5, 3, 3), 307 | null, 308 | fixture.input["ninePatch/document.png"], 309 | fixture.input["ninePatch/document.9.png"] 310 | ) 311 | fixture.assertNinePatchEquals( 312 | listOf(123, 89, 108, 56), 313 | null, 314 | fixture.input["ninePatch/gradient.jpg"], 315 | fixture.input["ninePatch/gradient.9.png"] 316 | ) 317 | } 318 | 319 | } 320 | 321 | } 322 | 323 | given("a ninepatch with auto, fuzziness and custom center") { 324 | 325 | beforeContainer { 326 | fixture.buildFile(""" 327 | ninePatch { 328 | np { 329 | image = file('in/ninePatch/resizable.png') 330 | auto = true 331 | centerX = 5 332 | centerY = 76 333 | paddingLeft = 2 334 | fuzziness = 80 335 | } 336 | } 337 | """) 338 | } 339 | 340 | `when`("building") { 341 | 342 | fixture.build(GdxPlugin.ALL_NINE_PATCHES_TASK_NAME) 343 | 344 | then("should create the correct nine patch") { 345 | fixture.assertNinePatchEquals( 346 | listOf(1, 1, 1, 1), 347 | listOf(2, 1, 1, 1), 348 | fixture.input["ninePatch/resizable.png"], 349 | fixture.input["ninePatch/resizable.9.png"] 350 | ) 351 | } 352 | 353 | } 354 | 355 | } 356 | 357 | given("a ninepatch with auto and custom left and top") { 358 | 359 | beforeContainer { 360 | fixture.buildFile(""" 361 | ninePatch { 362 | np { 363 | image = file('in/ninePatch/resizable.png') 364 | auto = true 365 | left = 2 366 | top = 2 367 | } 368 | } 369 | """) 370 | } 371 | 372 | `when`("building") { 373 | 374 | fixture.build(GdxPlugin.ALL_NINE_PATCHES_TASK_NAME) 375 | 376 | then("should create the correct nine patch") { 377 | fixture.assertNinePatchEquals( 378 | listOf(2, 19, 2, 19), 379 | null, 380 | fixture.input["ninePatch/resizable.png"], 381 | fixture.input["ninePatch/resizable.9.png"] 382 | ) 383 | } 384 | 385 | } 386 | 387 | } 388 | 389 | 390 | }) 391 | -------------------------------------------------------------------------------- /src/test/kotlin/TestPlugin.kt: -------------------------------------------------------------------------------- 1 | import com.badlogic.gdx.Version 2 | import io.kotest.core.spec.style.BehaviorSpec 3 | import io.kotest.engine.spec.tempdir 4 | import java.io.File 5 | 6 | /* 7 | * Copyright 2021 Blue Box Ware 8 | * 9 | * Licensed under the Apache License, Version 2.0 (the "License"); 10 | * you may not use this file except in compliance with the License. 11 | * You may obtain a copy of the License at 12 | * 13 | * http://www.apache.org/licenses/LICENSE-2.0 14 | * 15 | * Unless required by applicable law or agreed to in writing, software 16 | * distributed under the License is distributed on an "AS IS" BASIS, 17 | * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. 18 | * See the License for the specific language governing permissions and 19 | * limitations under the License. 20 | */ 21 | internal object TestPlugin: BehaviorSpec({ 22 | 23 | lateinit var fixture: ProjectFixture 24 | 25 | beforeContainer { 26 | fixture = ProjectFixture(tempdir()) 27 | } 28 | 29 | given("a project with the plugin applied") { 30 | 31 | beforeContainer { 32 | fixture.buildFile("") 33 | } 34 | 35 | `when`("running the texturePackerSettingsHelp task") { 36 | 37 | fixture.build("texturePackerSettingsHelp") 38 | 39 | then("displays the available settings") { 40 | fixture.assertBuildOutputContains("filterMin: \"Nearest\"") 41 | } 42 | 43 | } 44 | 45 | `when`("running the gdxVersion task") { 46 | 47 | fixture.build("gdxVersion") 48 | 49 | then("should display the bundled GDX version") { 50 | fixture.assertBuildOutputContains("\n${Version.VERSION}\n") 51 | } 52 | 53 | } 54 | 55 | 56 | } 57 | 58 | given("a project with a forced GDX version") { 59 | 60 | beforeContainer { 61 | 62 | fixture.buildFile(""" 63 | 64 | buildscript { 65 | 66 | ext { 67 | gdxVersion = "1.10.0" 68 | } 69 | 70 | repositories { 71 | flatDir dirs: "libs" 72 | mavenCentral() 73 | } 74 | dependencies { 75 | classpath "com.github.blueboxware:LibGDXGradlePlugin:${ProjectFixture.getVersion()}" 76 | classpath "org.jetbrains.kotlin:kotlin-stdlib:1.9.22" 77 | classpath("com.badlogicgames.gdx:gdx-tools") { 78 | version { 79 | strictly("${'$'}gdxVersion") 80 | } 81 | } 82 | classpath("com.badlogicgames.gdx:gdx-backend-lwjgl3") { 83 | version { 84 | strictly("${'$'}gdxVersion") 85 | } 86 | } 87 | classpath("com.badlogicgames.gdx:gdx-platform") { 88 | version { 89 | strictly("${'$'}gdxVersion") 90 | } 91 | } 92 | } 93 | } 94 | 95 | plugins { 96 | id 'org.jetbrains.kotlin.jvm' version '1.9.22' 97 | } 98 | 99 | apply plugin: 'com.github.blueboxware.gdx' 100 | 101 | bitmapFonts { 102 | 103 | normal { 104 | 105 | inputFont = file('in/etc/roboto.ttf') 106 | 107 | outputFile = file('out/roboto.fnt') 108 | 109 | size 16 110 | 111 | 112 | } 113 | } 114 | 115 | """, false) 116 | 117 | fixture.addFile("etc/roboto.ttf") 118 | 119 | fixture.project.copy { copySpec -> 120 | copySpec.from(File("build/libs").absolutePath) { 121 | it.include("LibGDXGradlePlugin-*.jar") 122 | } 123 | copySpec.into(fixture.output["../libs"]) 124 | } 125 | 126 | } 127 | 128 | `when`("running the gdxVersion task") { 129 | 130 | fixture.build("gdxVersion") 131 | 132 | then("should display the forced GDX version") { 133 | fixture.assertBuildOutputContains("\n1.10.0 (default: ${Version.VERSION})\n") 134 | } 135 | 136 | } 137 | 138 | `when`("running the BitmapFont task") { 139 | fixture.build("createAllFonts") 140 | 141 | then("should create the correct files") { 142 | fixture.assertFilesExist( 143 | "roboto.fnt", 144 | "roboto.png", 145 | ) 146 | } 147 | } 148 | 149 | 150 | } 151 | 152 | 153 | }) 154 | -------------------------------------------------------------------------------- /src/test/kotlin/TestReadme.kt: -------------------------------------------------------------------------------- 1 | import io.kotest.core.spec.style.BehaviorSpec 2 | import io.kotest.datatest.withData 3 | import io.kotest.engine.spec.tempdir 4 | import java.io.File 5 | 6 | /* 7 | * Copyright 2021 Blue Box Ware 8 | * 9 | * Licensed under the Apache License, Version 2.0 (the "License"); 10 | * you may not use this file except in compliance with the License. 11 | * You may obtain a copy of the License at 12 | * 13 | * http://www.apache.org/licenses/LICENSE-2.0 14 | * 15 | * Unless required by applicable law or agreed to in writing, software 16 | * distributed under the License is distributed on an "AS IS" BASIS, 17 | * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. 18 | * See the License for the specific language governing permissions and 19 | * limitations under the License. 20 | */ 21 | internal object TestReadme : BehaviorSpec({ 22 | 23 | val testRegex = 24 | Regex("]*)>(.*?)", option = RegexOption.DOT_MATCHES_ALL) 25 | val argRegex = Regex("""arg="([^"]*)"""") 26 | val idRegex = Regex("""id="([^"]*)"""") 27 | 28 | data class Test(val source: String, val args: String, val useKotlin: Boolean, val id: String, val noCache: Boolean) 29 | 30 | fun tests(): Sequence { 31 | 32 | val pluginVersion = ProjectFixture.getVersion() 33 | 34 | val tests = testRegex.findAll(File("README.md.src").readText()).map { matchResult -> 35 | val useKotlin = matchResult.groupValues[1] == "Kotlin" 36 | val src = matchResult.groupValues[3] 37 | .replace(Regex("", RegexOption.DOT_MATCHES_ALL), "") 38 | .replace("", pluginVersion) 39 | val args = argRegex.find(matchResult.groupValues[2])?.groupValues?.get(1) ?: throw AssertionError() 40 | val id = idRegex.find(matchResult.groupValues[2])?.groupValues?.get(1) ?: "" 41 | val noCache = matchResult.groupValues[2].contains("nocache") 42 | Test(src, args, useKotlin, id + " (${matchResult.groupValues[1]})", noCache) 43 | } 44 | 45 | return if (ProjectFixture.useConfigurationCache) { 46 | tests.filter { !it.noCache } 47 | } else { 48 | tests 49 | } 50 | } 51 | 52 | lateinit var fixture: ProjectFixture 53 | 54 | given("A fragment from the Readme") { 55 | 56 | withData(tests()) { (src, args, useKotlin, id) -> 57 | withData(args.split(" ")) { 58 | 59 | `when`("Building $id") { 60 | 61 | beforeTest { 62 | fixture = ProjectFixture(tempdir(), useKotlin, addClassPath = true) 63 | fixture.project.copy { 64 | it.from(fixture.testDataDir["readme"].absolutePath) 65 | it.into(fixture.project.rootDir) 66 | } 67 | } 68 | 69 | 70 | then("It should succeed ($id)") { 71 | fixture.buildFile(src) 72 | fixture.build(it) 73 | fixture.assertBuildSuccess() 74 | fixture.build(it) 75 | fixture.assertBuildUpToDate() 76 | } 77 | 78 | } 79 | } 80 | 81 | } 82 | 83 | 84 | } 85 | 86 | 87 | }) 88 | -------------------------------------------------------------------------------- /src/test/kotlin/Utils.kt: -------------------------------------------------------------------------------- 1 | 2 | import com.badlogic.gdx.tools.texturepacker.ImageProcessor 3 | import com.badlogic.gdx.tools.texturepacker.TexturePacker 4 | import io.kotest.core.annotation.EnabledCondition 5 | import io.kotest.core.config.AbstractProjectConfig 6 | import io.kotest.core.config.LogLevel 7 | import io.kotest.core.names.DuplicateTestNameMode 8 | import io.kotest.core.spec.Spec 9 | import java.awt.image.BufferedImage 10 | import java.io.File 11 | import javax.imageio.ImageIO 12 | import kotlin.reflect.KClass 13 | 14 | /* 15 | * Copyright 2018 Blue Box Ware 16 | * 17 | * Licensed under the Apache License, Version 2.0 (the "License"); 18 | * you may not use this file except in compliance with the License. 19 | * You may obtain a copy of the License at 20 | * 21 | * http://www.apache.org/licenses/LICENSE-2.0 22 | * 23 | * Unless required by applicable law or agreed to in writing, software 24 | * distributed under the License is distributed on an "AS IS" BASIS, 25 | * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. 26 | * See the License for the specific language governing permissions and 27 | * limitations under the License. 28 | */ 29 | 30 | internal val CURRENT_VERSION_REGEX = Regex("""pluginVersion\s*=\s*([\d.]+)""") 31 | internal val RELEASED_VERSION_REGEX = Regex("""releasedPluginVersion\s*=\s*([\d.]+)""") 32 | 33 | internal fun getCurrentVersion() = 34 | CURRENT_VERSION_REGEX.find(File("gradle.properties").readText())?.groupValues?.getOrNull(1) ?: throw AssertionError() 35 | 36 | internal fun getReleasedVersion() = 37 | RELEASED_VERSION_REGEX.find(File("gradle.properties").readText())?.groupValues?.getOrNull(1) ?: throw AssertionError() 38 | 39 | 40 | internal operator fun File.get(child: String): File { 41 | return File(this, child) 42 | } 43 | 44 | internal fun String.prefixIfNecessary(prefix: String): String = 45 | if (startsWith(prefix)) this else prefix + this 46 | 47 | internal fun BufferedImage.getRect(): TexturePacker.Rect = 48 | ImageProcessor(TexturePacker.Settings()).addImage(this, "foo.9") 49 | 50 | internal fun getRect(file: File): TexturePacker.Rect = ImageIO.read(file).getRect() 51 | 52 | @Suppress("unused") 53 | object Config: AbstractProjectConfig() { 54 | override val duplicateTestNameMode: DuplicateTestNameMode = DuplicateTestNameMode.Silent 55 | override val logLevel = LogLevel.Trace 56 | } 57 | 58 | class NoConfigurationCache: EnabledCondition { 59 | override fun enabled(kclass: KClass): Boolean = !ProjectFixture.useConfigurationCache 60 | } 61 | 62 | class ConfigurationCache: EnabledCondition { 63 | override fun enabled(kclass: KClass): Boolean = ProjectFixture.useConfigurationCache 64 | } 65 | -------------------------------------------------------------------------------- /src/test/testData/etc/freesans.ttf: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/BlueBoxWare/LibGDXGradlePlugin/3fe89c80b9deeae63ee404c281ff004b195d58b9/src/test/testData/etc/freesans.ttf -------------------------------------------------------------------------------- /src/test/testData/etc/roboto.ttf: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/BlueBoxWare/LibGDXGradlePlugin/3fe89c80b9deeae63ee404c281ff004b195d58b9/src/test/testData/etc/roboto.ttf -------------------------------------------------------------------------------- /src/test/testData/etc/wat.jpg: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/BlueBoxWare/LibGDXGradlePlugin/3fe89c80b9deeae63ee404c281ff004b195d58b9/src/test/testData/etc/wat.jpg -------------------------------------------------------------------------------- /src/test/testData/images1/binary.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/BlueBoxWare/LibGDXGradlePlugin/3fe89c80b9deeae63ee404c281ff004b195d58b9/src/test/testData/images1/binary.png -------------------------------------------------------------------------------- /src/test/testData/images1/deb.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/BlueBoxWare/LibGDXGradlePlugin/3fe89c80b9deeae63ee404c281ff004b195d58b9/src/test/testData/images1/deb.png -------------------------------------------------------------------------------- /src/test/testData/images1/document.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/BlueBoxWare/LibGDXGradlePlugin/3fe89c80b9deeae63ee404c281ff004b195d58b9/src/test/testData/images1/document.png -------------------------------------------------------------------------------- /src/test/testData/images1/empty.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/BlueBoxWare/LibGDXGradlePlugin/3fe89c80b9deeae63ee404c281ff004b195d58b9/src/test/testData/images1/empty.png -------------------------------------------------------------------------------- /src/test/testData/images1/sub/binary.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/BlueBoxWare/LibGDXGradlePlugin/3fe89c80b9deeae63ee404c281ff004b195d58b9/src/test/testData/images1/sub/binary.png -------------------------------------------------------------------------------- /src/test/testData/images1/sub/image.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/BlueBoxWare/LibGDXGradlePlugin/3fe89c80b9deeae63ee404c281ff004b195d58b9/src/test/testData/images1/sub/image.png -------------------------------------------------------------------------------- /src/test/testData/images1/sub/pack.json: -------------------------------------------------------------------------------- 1 | { 2 | pot: true, 3 | paddingX: 8, 4 | paddingY: 8, 5 | bleed: true, 6 | bleedIterations: 2, 7 | edgePadding: true, 8 | duplicatePadding: false, 9 | rotation: false, 10 | minWidth: 16, 11 | minHeight: 16, 12 | maxWidth: 1024, 13 | maxHeight: 1024, 14 | square: false, 15 | stripWhitespaceX: false, 16 | stripWhitespaceY: false, 17 | alphaThreshold: 0, 18 | filterMin: Linear, 19 | filterMag: MipMapLinearLinear, 20 | wrapX: ClampToEdge, 21 | wrapY: ClampToEdge, 22 | format: RGBA8888, 23 | alias: true, 24 | outputFormat: jpg, 25 | jpegQuality: 0.9, 26 | ignoreBlankImages: true, 27 | fast: false, 28 | debug: false, 29 | combineSubdirectories: false, 30 | flattenPaths: false, 31 | premultiplyAlpha: false, 32 | useIndexes: true, 33 | limitMemory: true, 34 | grid: true, 35 | scale: [ 1 ], 36 | scaleSuffix: [ "" ] 37 | } -------------------------------------------------------------------------------- /src/test/testData/images1/sub/subsub/pack.json: -------------------------------------------------------------------------------- 1 | { 2 | pot: true, 3 | paddingX: 8, 4 | paddingY: 8, 5 | bleed: true, 6 | bleedIterations: 2, 7 | edgePadding: true, 8 | duplicatePadding: false, 9 | rotation: false, 10 | minWidth: 16, 11 | minHeight: 16, 12 | maxWidth: 1024, 13 | maxHeight: 1024, 14 | square: false, 15 | stripWhitespaceX: false, 16 | stripWhitespaceY: false, 17 | alphaThreshold: 0, 18 | filterMin: Nearest, 19 | filterMag: Nearest, 20 | wrapX: ClampToEdge, 21 | wrapY: ClampToEdge, 22 | format: RGBA8888, 23 | alias: true, 24 | jpegQuality: 0.9, 25 | ignoreBlankImages: true, 26 | fast: false, 27 | debug: false, 28 | combineSubdirectories: false, 29 | flattenPaths: false, 30 | premultiplyAlpha: false, 31 | useIndexes: true, 32 | limitMemory: true, 33 | grid: true, 34 | scale: [ 1 ], 35 | scaleSuffix: [ "" ] 36 | } -------------------------------------------------------------------------------- /src/test/testData/images1/sub/subsub/plan.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/BlueBoxWare/LibGDXGradlePlugin/3fe89c80b9deeae63ee404c281ff004b195d58b9/src/test/testData/images1/sub/subsub/plan.png -------------------------------------------------------------------------------- /src/test/testData/images1/sub/subsub/spreadsheet.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/BlueBoxWare/LibGDXGradlePlugin/3fe89c80b9deeae63ee404c281ff004b195d58b9/src/test/testData/images1/sub/subsub/spreadsheet.png -------------------------------------------------------------------------------- /src/test/testData/images2/add.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/BlueBoxWare/LibGDXGradlePlugin/3fe89c80b9deeae63ee404c281ff004b195d58b9/src/test/testData/images2/add.png -------------------------------------------------------------------------------- /src/test/testData/images2/back.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/BlueBoxWare/LibGDXGradlePlugin/3fe89c80b9deeae63ee404c281ff004b195d58b9/src/test/testData/images2/back.png -------------------------------------------------------------------------------- /src/test/testData/images2/bottom.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/BlueBoxWare/LibGDXGradlePlugin/3fe89c80b9deeae63ee404c281ff004b195d58b9/src/test/testData/images2/bottom.png -------------------------------------------------------------------------------- /src/test/testData/images2/pack.json: -------------------------------------------------------------------------------- 1 | { 2 | pot: true, 3 | paddingX: 2, 4 | paddingY: 2, 5 | bleed: true, 6 | bleedIterations: 2, 7 | edgePadding: true, 8 | duplicatePadding: false, 9 | rotation: false, 10 | minWidth: 16, 11 | minHeight: 16, 12 | maxWidth: 1024, 13 | maxHeight: 1024, 14 | square: false, 15 | stripWhitespaceX: false, 16 | stripWhitespaceY: false, 17 | alphaThreshold: 0, 18 | filterMin: MipMapNearestNearest, 19 | filterMag: Nearest, 20 | wrapX: ClampToEdge, 21 | wrapY: ClampToEdge, 22 | format: RGBA8888, 23 | alias: true, 24 | outputFormat: png, 25 | jpegQuality: 0.9, 26 | ignoreBlankImages: true, 27 | fast: false, 28 | debug: false, 29 | combineSubdirectories: false, 30 | flattenPaths: false, 31 | premultiplyAlpha: false, 32 | useIndexes: true, 33 | limitMemory: true, 34 | grid: false, 35 | scale: [ 1 ], 36 | scaleSuffix: [ "" ] 37 | } -------------------------------------------------------------------------------- /src/test/testData/ninePatch/document.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/BlueBoxWare/LibGDXGradlePlugin/3fe89c80b9deeae63ee404c281ff004b195d58b9/src/test/testData/ninePatch/document.png -------------------------------------------------------------------------------- /src/test/testData/ninePatch/gradient.jpg: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/BlueBoxWare/LibGDXGradlePlugin/3fe89c80b9deeae63ee404c281ff004b195d58b9/src/test/testData/ninePatch/gradient.jpg -------------------------------------------------------------------------------- /src/test/testData/ninePatch/overlap.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/BlueBoxWare/LibGDXGradlePlugin/3fe89c80b9deeae63ee404c281ff004b195d58b9/src/test/testData/ninePatch/overlap.png -------------------------------------------------------------------------------- /src/test/testData/ninePatch/rect.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/BlueBoxWare/LibGDXGradlePlugin/3fe89c80b9deeae63ee404c281ff004b195d58b9/src/test/testData/ninePatch/rect.png -------------------------------------------------------------------------------- /src/test/testData/ninePatch/red.jpg: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/BlueBoxWare/LibGDXGradlePlugin/3fe89c80b9deeae63ee404c281ff004b195d58b9/src/test/testData/ninePatch/red.jpg -------------------------------------------------------------------------------- /src/test/testData/ninePatch/red.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/BlueBoxWare/LibGDXGradlePlugin/3fe89c80b9deeae63ee404c281ff004b195d58b9/src/test/testData/ninePatch/red.png -------------------------------------------------------------------------------- /src/test/testData/ninePatch/resizable.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/BlueBoxWare/LibGDXGradlePlugin/3fe89c80b9deeae63ee404c281ff004b195d58b9/src/test/testData/ninePatch/resizable.png -------------------------------------------------------------------------------- /src/test/testData/ninePatch/thingy.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/BlueBoxWare/LibGDXGradlePlugin/3fe89c80b9deeae63ee404c281ff004b195d58b9/src/test/testData/ninePatch/thingy.png -------------------------------------------------------------------------------- /src/test/testData/readme/fonts/roboto.ttf: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/BlueBoxWare/LibGDXGradlePlugin/3fe89c80b9deeae63ee404c281ff004b195d58b9/src/test/testData/readme/fonts/roboto.ttf -------------------------------------------------------------------------------- /src/test/testData/readme/textures/border.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/BlueBoxWare/LibGDXGradlePlugin/3fe89c80b9deeae63ee404c281ff004b195d58b9/src/test/testData/readme/textures/border.png -------------------------------------------------------------------------------- /src/test/testData/readme/textures/game/add.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/BlueBoxWare/LibGDXGradlePlugin/3fe89c80b9deeae63ee404c281ff004b195d58b9/src/test/testData/readme/textures/game/add.png -------------------------------------------------------------------------------- /src/test/testData/readme/textures/game/document.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/BlueBoxWare/LibGDXGradlePlugin/3fe89c80b9deeae63ee404c281ff004b195d58b9/src/test/testData/readme/textures/game/document.png -------------------------------------------------------------------------------- /src/test/testData/readme/textures/game/pack.json: -------------------------------------------------------------------------------- 1 | { 2 | pot: true, 3 | paddingX: 2, 4 | paddingY: 2, 5 | bleed: true, 6 | bleedIterations: 2, 7 | edgePadding: true, 8 | duplicatePadding: false, 9 | rotation: false, 10 | minWidth: 16, 11 | minHeight: 16, 12 | maxWidth: 1024, 13 | maxHeight: 1024, 14 | square: false, 15 | stripWhitespaceX: false, 16 | stripWhitespaceY: false, 17 | alphaThreshold: 0, 18 | filterMin: MipMapNearestNearest, 19 | filterMag: Nearest, 20 | wrapX: ClampToEdge, 21 | wrapY: ClampToEdge, 22 | format: RGBA8888, 23 | alias: true, 24 | outputFormat: png, 25 | jpegQuality: 0.9, 26 | ignoreBlankImages: true, 27 | fast: false, 28 | debug: false, 29 | combineSubdirectories: false, 30 | flattenPaths: false, 31 | premultiplyAlpha: false, 32 | useIndexes: true, 33 | limitMemory: true, 34 | grid: false, 35 | scale: [ 1 ], 36 | scaleSuffix: [ "" ] 37 | } -------------------------------------------------------------------------------- /src/test/testData/readme/textures/game/sub/pack.json: -------------------------------------------------------------------------------- 1 | { 2 | pot: true, 3 | paddingX: 8, 4 | paddingY: 8, 5 | bleed: true, 6 | bleedIterations: 2, 7 | edgePadding: true, 8 | duplicatePadding: false, 9 | rotation: false, 10 | minWidth: 16, 11 | minHeight: 16, 12 | maxWidth: 1024, 13 | maxHeight: 1024, 14 | square: false, 15 | stripWhitespaceX: false, 16 | stripWhitespaceY: false, 17 | alphaThreshold: 0, 18 | filterMin: Nearest, 19 | filterMag: Nearest, 20 | wrapX: ClampToEdge, 21 | wrapY: ClampToEdge, 22 | format: RGBA8888, 23 | alias: true, 24 | jpegQuality: 0.9, 25 | ignoreBlankImages: true, 26 | fast: false, 27 | debug: false, 28 | combineSubdirectories: false, 29 | flattenPaths: false, 30 | premultiplyAlpha: false, 31 | useIndexes: true, 32 | limitMemory: true, 33 | grid: true, 34 | scale: [ 1 ], 35 | scaleSuffix: [ "" ] 36 | } -------------------------------------------------------------------------------- /src/test/testData/readme/textures/game/sub/plan.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/BlueBoxWare/LibGDXGradlePlugin/3fe89c80b9deeae63ee404c281ff004b195d58b9/src/test/testData/readme/textures/game/sub/plan.png -------------------------------------------------------------------------------- /src/test/testData/readme/textures/game/sub/spreadsheet.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/BlueBoxWare/LibGDXGradlePlugin/3fe89c80b9deeae63ee404c281ff004b195d58b9/src/test/testData/readme/textures/game/sub/spreadsheet.png -------------------------------------------------------------------------------- /src/test/testData/readme/textures/gameOver/back.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/BlueBoxWare/LibGDXGradlePlugin/3fe89c80b9deeae63ee404c281ff004b195d58b9/src/test/testData/readme/textures/gameOver/back.png -------------------------------------------------------------------------------- /src/test/testData/readme/textures/gameOver/bottom.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/BlueBoxWare/LibGDXGradlePlugin/3fe89c80b9deeae63ee404c281ff004b195d58b9/src/test/testData/readme/textures/gameOver/bottom.png -------------------------------------------------------------------------------- /src/test/testData/readme/textures/logo.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/BlueBoxWare/LibGDXGradlePlugin/3fe89c80b9deeae63ee404c281ff004b195d58b9/src/test/testData/readme/textures/logo.png -------------------------------------------------------------------------------- /src/test/testData/readme/textures/menu/empty.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/BlueBoxWare/LibGDXGradlePlugin/3fe89c80b9deeae63ee404c281ff004b195d58b9/src/test/testData/readme/textures/menu/empty.png -------------------------------------------------------------------------------- /src/test/testData/readme/textures/menu/image.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/BlueBoxWare/LibGDXGradlePlugin/3fe89c80b9deeae63ee404c281ff004b195d58b9/src/test/testData/readme/textures/menu/image.png -------------------------------------------------------------------------------- /src/test/testData/readme/textures/menu/pack.json: -------------------------------------------------------------------------------- 1 | { 2 | pot: true, 3 | paddingX: 2, 4 | paddingY: 2, 5 | bleed: true, 6 | bleedIterations: 2, 7 | edgePadding: true, 8 | duplicatePadding: false, 9 | rotation: false, 10 | minWidth: 16, 11 | minHeight: 16, 12 | maxWidth: 1024, 13 | maxHeight: 1024, 14 | square: false, 15 | stripWhitespaceX: false, 16 | stripWhitespaceY: false, 17 | alphaThreshold: 0, 18 | filterMin: MipMapNearestNearest, 19 | filterMag: Nearest, 20 | wrapX: ClampToEdge, 21 | wrapY: ClampToEdge, 22 | format: RGBA8888, 23 | alias: true, 24 | outputFormat: png, 25 | jpegQuality: 0.9, 26 | ignoreBlankImages: true, 27 | fast: false, 28 | debug: false, 29 | combineSubdirectories: false, 30 | flattenPaths: false, 31 | premultiplyAlpha: false, 32 | useIndexes: true, 33 | limitMemory: true, 34 | grid: false, 35 | scale: [ 1 ], 36 | scaleSuffix: [ "" ] 37 | } -------------------------------------------------------------------------------- /src/test/testData/readme/textures/pack.json: -------------------------------------------------------------------------------- 1 | { 2 | pot: true, 3 | paddingX: 8, 4 | paddingY: 8, 5 | bleed: true, 6 | bleedIterations: 2, 7 | edgePadding: true, 8 | duplicatePadding: false, 9 | rotation: false, 10 | minWidth: 16, 11 | minHeight: 16, 12 | maxWidth: 1024, 13 | maxHeight: 1024, 14 | square: false, 15 | stripWhitespaceX: false, 16 | stripWhitespaceY: false, 17 | alphaThreshold: 0, 18 | filterMin: Nearest, 19 | filterMag: Nearest, 20 | wrapX: ClampToEdge, 21 | wrapY: ClampToEdge, 22 | format: RGBA8888, 23 | alias: true, 24 | jpegQuality: 0.9, 25 | ignoreBlankImages: true, 26 | fast: false, 27 | debug: false, 28 | combineSubdirectories: false, 29 | flattenPaths: false, 30 | premultiplyAlpha: false, 31 | useIndexes: true, 32 | limitMemory: true, 33 | grid: true, 34 | scale: [ 1 ], 35 | scaleSuffix: [ "" ] 36 | } -------------------------------------------------------------------------------- /src/test/testData/readme/textures/rect.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/BlueBoxWare/LibGDXGradlePlugin/3fe89c80b9deeae63ee404c281ff004b195d58b9/src/test/testData/readme/textures/rect.png -------------------------------------------------------------------------------- /src/test/testData/readme/textures/title.jpg: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/BlueBoxWare/LibGDXGradlePlugin/3fe89c80b9deeae63ee404c281ff004b195d58b9/src/test/testData/readme/textures/title.jpg -------------------------------------------------------------------------------- /src/test/testData/readme/textures/title.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/BlueBoxWare/LibGDXGradlePlugin/3fe89c80b9deeae63ee404c281ff004b195d58b9/src/test/testData/readme/textures/title.png -------------------------------------------------------------------------------- /src/test/testData/results/bitmapFont/arial16px.fnt: -------------------------------------------------------------------------------- 1 | info face="Arial Black" size=16 bold=1 italic=0 charset="" unicode=0 stretchH=100 smooth=1 aa=1 padding=1,4,2,3 spacing=2,3 2 | common lineHeight=29 base=18 scaleW=64 scaleH=128 pages=1 packed=0 3 | page id=0 file="arial16px.png" 4 | chars count=8 5 | char id=0 x=0 y=16 width=16 height=14 xoffset=-3 yoffset=6 xadvance=21 page=0 chnl=0 6 | char id=32 x=0 y=0 width=0 height=0 xoffset=-3 yoffset=0 xadvance=14 page=0 chnl=0 7 | char id=97 x=16 y=16 width=19 height=13 xoffset=-3 yoffset=7 xadvance=20 page=0 chnl=0 8 | char id=98 x=0 y=0 width=17 height=16 xoffset=-2 yoffset=4 xadvance=20 page=0 chnl=0 9 | char id=99 x=35 y=16 width=17 height=13 xoffset=-2 yoffset=7 xadvance=20 page=0 chnl=0 10 | char id=100 x=17 y=0 width=17 height=16 xoffset=-2 yoffset=4 xadvance=20 page=0 chnl=0 11 | char id=101 x=0 y=30 width=17 height=13 xoffset=-2 yoffset=7 xadvance=20 page=0 chnl=0 12 | char id=102 x=34 y=0 width=15 height=16 xoffset=-3 yoffset=4 xadvance=15 page=0 chnl=0 13 | kernings count=1 14 | kerning first=102 second=32 amount=1 15 | -------------------------------------------------------------------------------- /src/test/testData/results/bitmapFont/arial16px.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/BlueBoxWare/LibGDXGradlePlugin/3fe89c80b9deeae63ee404c281ff004b195d58b9/src/test/testData/results/bitmapFont/arial16px.png -------------------------------------------------------------------------------- /src/test/testData/results/bitmapFont/distanceField.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/BlueBoxWare/LibGDXGradlePlugin/3fe89c80b9deeae63ee404c281ff004b195d58b9/src/test/testData/results/bitmapFont/distanceField.png -------------------------------------------------------------------------------- /src/test/testData/results/bitmapFont/gradient.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/BlueBoxWare/LibGDXGradlePlugin/3fe89c80b9deeae63ee404c281ff004b195d58b9/src/test/testData/results/bitmapFont/gradient.png -------------------------------------------------------------------------------- /src/test/testData/results/bitmapFont/outline.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/BlueBoxWare/LibGDXGradlePlugin/3fe89c80b9deeae63ee404c281ff004b195d58b9/src/test/testData/results/bitmapFont/outline.png -------------------------------------------------------------------------------- /src/test/testData/results/bitmapFont/outlineAndShadow.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/BlueBoxWare/LibGDXGradlePlugin/3fe89c80b9deeae63ee404c281ff004b195d58b9/src/test/testData/results/bitmapFont/outlineAndShadow.png -------------------------------------------------------------------------------- /src/test/testData/results/bitmapFont/roboto32px.fnt: -------------------------------------------------------------------------------- 1 | info face="Roboto Regular" size=32 bold=0 italic=0 charset="" unicode=0 stretchH=100 smooth=1 aa=1 padding=1,1,1,1 spacing=-2,-2 2 | common lineHeight=43 base=34 scaleW=512 scaleH=512 pages=1 packed=0 3 | page id=0 file="roboto32px.png" 4 | chars count=98 5 | char id=0 x=0 y=0 width=0 height=0 xoffset=-1 yoffset=33 xadvance=0 page=0 chnl=0 6 | char id=10 x=0 y=0 width=33 height=45 xoffset=0 yoffset=-1 xadvance=33 page=0 chnl=0 7 | char id=32 x=0 y=0 width=0 height=0 xoffset=-1 yoffset=33 xadvance=8 page=0 chnl=0 8 | char id=33 x=484 y=45 width=5 height=24 xoffset=2 yoffset=11 xadvance=8 page=0 chnl=0 9 | char id=34 x=398 y=69 width=9 height=10 xoffset=1 yoffset=10 xadvance=10 page=0 chnl=0 10 | char id=35 x=23 y=69 width=19 height=24 xoffset=1 yoffset=11 xadvance=20 page=0 chnl=0 11 | char id=36 x=97 y=0 width=17 height=31 xoffset=1 yoffset=7 xadvance=19 page=0 chnl=0 12 | char id=37 x=0 y=69 width=23 height=24 xoffset=1 yoffset=11 xadvance=24 page=0 chnl=0 13 | char id=38 x=42 y=69 width=21 height=24 xoffset=1 yoffset=11 xadvance=20 page=0 chnl=0 14 | char id=39 x=414 y=69 width=5 height=9 xoffset=1 yoffset=10 xadvance=6 page=0 chnl=0 15 | char id=40 x=33 y=0 width=11 height=36 xoffset=1 yoffset=7 xadvance=11 page=0 chnl=0 16 | char id=41 x=44 y=0 width=11 height=36 xoffset=-1 yoffset=7 xadvance=11 page=0 chnl=0 17 | char id=42 x=353 y=69 width=16 height=16 xoffset=-1 yoffset=11 xadvance=14 page=0 chnl=0 18 | char id=43 x=304 y=69 width=18 height=18 xoffset=0 yoffset=15 xadvance=18 page=0 chnl=0 19 | char id=44 x=407 y=69 width=7 height=10 xoffset=-1 yoffset=30 xadvance=6 page=0 chnl=0 20 | char id=45 x=455 y=69 width=10 height=5 xoffset=0 yoffset=22 xadvance=10 page=0 chnl=0 21 | char id=46 x=449 y=69 width=6 height=5 xoffset=1 yoffset=30 xadvance=9 page=0 chnl=0 22 | char id=47 x=175 y=0 width=15 height=27 xoffset=-1 yoffset=11 xadvance=13 page=0 chnl=0 23 | char id=48 x=468 y=45 width=16 height=24 xoffset=1 yoffset=11 xadvance=18 page=0 chnl=0 24 | char id=49 x=323 y=45 width=11 height=24 xoffset=2 yoffset=11 xadvance=18 page=0 chnl=0 25 | char id=50 x=334 y=45 width=17 height=24 xoffset=0 yoffset=11 xadvance=18 page=0 chnl=0 26 | char id=51 x=351 y=45 width=16 height=24 xoffset=1 yoffset=11 xadvance=18 page=0 chnl=0 27 | char id=52 x=367 y=45 width=18 height=24 xoffset=0 yoffset=11 xadvance=18 page=0 chnl=0 28 | char id=53 x=385 y=45 width=17 height=24 xoffset=1 yoffset=11 xadvance=18 page=0 chnl=0 29 | char id=54 x=402 y=45 width=16 height=24 xoffset=1 yoffset=11 xadvance=18 page=0 chnl=0 30 | char id=55 x=418 y=45 width=17 height=24 xoffset=0 yoffset=11 xadvance=18 page=0 chnl=0 31 | char id=56 x=435 y=45 width=17 height=24 xoffset=1 yoffset=11 xadvance=18 page=0 chnl=0 32 | char id=57 x=452 y=45 width=16 height=24 xoffset=1 yoffset=11 xadvance=18 page=0 chnl=0 33 | char id=58 x=504 y=45 width=6 height=19 xoffset=1 yoffset=16 xadvance=8 page=0 chnl=0 34 | char id=59 x=74 y=69 width=8 height=23 xoffset=-1 yoffset=16 xadvance=7 page=0 chnl=0 35 | char id=60 x=322 y=69 width=15 height=16 xoffset=0 yoffset=16 xadvance=16 page=0 chnl=0 36 | char id=61 x=383 y=69 width=15 height=11 xoffset=1 yoffset=18 xadvance=17 page=0 chnl=0 37 | char id=62 x=337 y=69 width=16 height=16 xoffset=1 yoffset=16 xadvance=17 page=0 chnl=0 38 | char id=63 x=489 y=45 width=15 height=24 xoffset=0 yoffset=11 xadvance=15 page=0 chnl=0 39 | char id=64 x=122 y=0 width=27 height=30 xoffset=1 yoffset=11 xadvance=29 page=0 chnl=0 40 | char id=65 x=350 y=0 width=23 height=24 xoffset=-1 yoffset=11 xadvance=21 page=0 chnl=0 41 | char id=66 x=373 y=0 width=17 height=24 xoffset=2 yoffset=11 xadvance=20 page=0 chnl=0 42 | char id=67 x=390 y=0 width=20 height=24 xoffset=1 yoffset=11 xadvance=21 page=0 chnl=0 43 | char id=68 x=410 y=0 width=18 height=24 xoffset=2 yoffset=11 xadvance=21 page=0 chnl=0 44 | char id=69 x=428 y=0 width=17 height=24 xoffset=2 yoffset=11 xadvance=19 page=0 chnl=0 45 | char id=70 x=445 y=0 width=16 height=24 xoffset=2 yoffset=11 xadvance=18 page=0 chnl=0 46 | char id=71 x=461 y=0 width=20 height=24 xoffset=1 yoffset=11 xadvance=22 page=0 chnl=0 47 | char id=72 x=481 y=0 width=19 height=24 xoffset=2 yoffset=11 xadvance=23 page=0 chnl=0 48 | char id=73 x=500 y=0 width=5 height=24 xoffset=2 yoffset=11 xadvance=9 page=0 chnl=0 49 | char id=74 x=0 y=45 width=16 height=24 xoffset=0 yoffset=11 xadvance=17 page=0 chnl=0 50 | char id=75 x=16 y=45 width=20 height=24 xoffset=2 yoffset=11 xadvance=20 page=0 chnl=0 51 | char id=76 x=36 y=45 width=16 height=24 xoffset=2 yoffset=11 xadvance=18 page=0 chnl=0 52 | char id=77 x=52 y=45 width=25 height=24 xoffset=2 yoffset=11 xadvance=29 page=0 chnl=0 53 | char id=78 x=77 y=45 width=19 height=24 xoffset=2 yoffset=11 xadvance=23 page=0 chnl=0 54 | char id=79 x=96 y=45 width=20 height=24 xoffset=1 yoffset=11 xadvance=22 page=0 chnl=0 55 | char id=80 x=116 y=45 width=18 height=24 xoffset=2 yoffset=11 xadvance=20 page=0 chnl=0 56 | char id=81 x=154 y=0 width=21 height=28 xoffset=1 yoffset=11 xadvance=22 page=0 chnl=0 57 | char id=82 x=134 y=45 width=19 height=24 xoffset=2 yoffset=11 xadvance=20 page=0 chnl=0 58 | char id=83 x=153 y=45 width=18 height=24 xoffset=0 yoffset=11 xadvance=18 page=0 chnl=0 59 | char id=84 x=171 y=45 width=20 height=24 xoffset=0 yoffset=11 xadvance=20 page=0 chnl=0 60 | char id=85 x=191 y=45 width=18 height=24 xoffset=1 yoffset=11 xadvance=20 page=0 chnl=0 61 | char id=86 x=209 y=45 width=22 height=24 xoffset=-1 yoffset=11 xadvance=20 page=0 chnl=0 62 | char id=87 x=231 y=45 width=30 height=24 xoffset=-1 yoffset=11 xadvance=28 page=0 chnl=0 63 | char id=88 x=261 y=45 width=22 height=24 xoffset=-1 yoffset=11 xadvance=20 page=0 chnl=0 64 | char id=89 x=283 y=45 width=21 height=24 xoffset=-1 yoffset=11 xadvance=19 page=0 chnl=0 65 | char id=90 x=304 y=45 width=19 height=24 xoffset=0 yoffset=11 xadvance=19 page=0 chnl=0 66 | char id=91 x=81 y=0 width=8 height=33 xoffset=1 yoffset=7 xadvance=9 page=0 chnl=0 67 | char id=92 x=190 y=0 width=15 height=27 xoffset=-1 yoffset=11 xadvance=13 page=0 chnl=0 68 | char id=93 x=89 y=0 width=8 height=33 xoffset=0 yoffset=7 xadvance=9 page=0 chnl=0 69 | char id=94 x=369 y=69 width=14 height=13 xoffset=0 yoffset=11 xadvance=13 page=0 chnl=0 70 | char id=95 x=465 y=69 width=16 height=5 xoffset=0 yoffset=32 xadvance=16 page=0 chnl=0 71 | char id=96 x=439 y=69 width=10 height=7 xoffset=-1 yoffset=9 xadvance=10 page=0 chnl=0 72 | char id=97 x=82 y=69 width=16 height=19 xoffset=1 yoffset=16 xadvance=17 page=0 chnl=0 73 | char id=98 x=217 y=0 width=16 height=25 xoffset=1 yoffset=10 xadvance=17 page=0 chnl=0 74 | char id=99 x=98 y=69 width=16 height=19 xoffset=0 yoffset=16 xadvance=16 page=0 chnl=0 75 | char id=100 x=233 y=0 width=16 height=25 xoffset=0 yoffset=10 xadvance=17 page=0 chnl=0 76 | char id=101 x=114 y=69 width=16 height=19 xoffset=0 yoffset=16 xadvance=16 page=0 chnl=0 77 | char id=102 x=205 y=0 width=12 height=26 xoffset=0 yoffset=9 xadvance=12 page=0 chnl=0 78 | char id=103 x=249 y=0 width=16 height=25 xoffset=0 yoffset=16 xadvance=17 page=0 chnl=0 79 | char id=104 x=265 y=0 width=15 height=25 xoffset=1 yoffset=10 xadvance=17 page=0 chnl=0 80 | char id=105 x=505 y=0 width=5 height=24 xoffset=1 yoffset=11 xadvance=7 page=0 chnl=0 81 | char id=106 x=114 y=0 width=8 height=30 xoffset=-2 yoffset=11 xadvance=7 page=0 chnl=0 82 | char id=107 x=280 y=0 width=16 height=25 xoffset=1 yoffset=10 xadvance=16 page=0 chnl=0 83 | char id=108 x=296 y=0 width=5 height=25 xoffset=1 yoffset=10 xadvance=7 page=0 chnl=0 84 | char id=109 x=130 y=69 width=26 height=19 xoffset=1 yoffset=16 xadvance=27 page=0 chnl=0 85 | char id=110 x=156 y=69 width=15 height=19 xoffset=1 yoffset=16 xadvance=17 page=0 chnl=0 86 | char id=111 x=171 y=69 width=17 height=19 xoffset=0 yoffset=16 xadvance=17 page=0 chnl=0 87 | char id=112 x=301 y=0 width=16 height=25 xoffset=1 yoffset=16 xadvance=17 page=0 chnl=0 88 | char id=113 x=317 y=0 width=16 height=25 xoffset=0 yoffset=16 xadvance=17 page=0 chnl=0 89 | char id=114 x=188 y=69 width=10 height=19 xoffset=1 yoffset=16 xadvance=11 page=0 chnl=0 90 | char id=115 x=198 y=69 width=15 height=19 xoffset=0 yoffset=16 xadvance=16 page=0 chnl=0 91 | char id=116 x=63 y=69 width=11 height=23 xoffset=0 yoffset=12 xadvance=11 page=0 chnl=0 92 | char id=117 x=213 y=69 width=15 height=19 xoffset=1 yoffset=16 xadvance=17 page=0 chnl=0 93 | char id=118 x=228 y=69 width=17 height=19 xoffset=-1 yoffset=16 xadvance=16 page=0 chnl=0 94 | char id=119 x=245 y=69 width=26 height=19 xoffset=-1 yoffset=16 xadvance=24 page=0 chnl=0 95 | char id=120 x=271 y=69 width=18 height=19 xoffset=-1 yoffset=16 xadvance=16 page=0 chnl=0 96 | char id=121 x=333 y=0 width=17 height=25 xoffset=-1 yoffset=16 xadvance=15 page=0 chnl=0 97 | char id=122 x=289 y=69 width=15 height=19 xoffset=0 yoffset=16 xadvance=15 page=0 chnl=0 98 | char id=123 x=55 y=0 width=13 height=34 xoffset=-1 yoffset=8 xadvance=11 page=0 chnl=0 99 | char id=124 x=149 y=0 width=5 height=29 xoffset=2 yoffset=11 xadvance=9 page=0 chnl=0 100 | char id=125 x=68 y=0 width=13 height=34 xoffset=-1 yoffset=8 xadvance=12 page=0 chnl=0 101 | char id=126 x=419 y=69 width=20 height=8 xoffset=1 yoffset=21 xadvance=22 page=0 chnl=0 102 | char id=127 x=0 y=0 width=33 height=45 xoffset=0 yoffset=-1 xadvance=33 page=0 chnl=0 103 | kernings count=118 104 | kerning first=118 second=46 amount=-2 105 | kerning first=87 second=65 amount=-1 106 | kerning first=84 second=111 amount=-2 107 | kerning first=39 second=34 amount=-2 108 | kerning first=87 second=44 amount=-2 109 | kerning first=79 second=89 amount=-1 110 | kerning first=75 second=118 amount=-1 111 | kerning first=39 second=115 amount=-1 112 | kerning first=89 second=117 amount=-1 113 | kerning first=114 second=46 amount=-2 114 | kerning first=39 second=39 amount=-2 115 | kerning first=88 second=45 amount=-1 116 | kerning first=76 second=85 amount=-1 117 | kerning first=84 second=74 amount=-4 118 | kerning first=65 second=87 amount=-1 119 | kerning first=76 second=119 amount=-1 120 | kerning first=86 second=45 amount=-1 121 | kerning first=70 second=46 amount=-4 122 | kerning first=39 second=65 amount=-2 123 | kerning first=84 second=32 amount=-1 124 | kerning first=39 second=99 amount=-1 125 | kerning first=89 second=46 amount=-3 126 | kerning first=84 second=45 amount=-4 127 | kerning first=79 second=44 amount=-2 128 | kerning first=34 second=111 amount=-1 129 | kerning first=80 second=74 amount=-3 130 | kerning first=89 second=114 amount=-1 131 | kerning first=119 second=44 amount=-2 132 | kerning first=111 second=34 amount=-2 133 | kerning first=87 second=46 amount=-2 134 | kerning first=65 second=84 amount=-2 135 | kerning first=65 second=118 amount=-1 136 | kerning first=86 second=97 amount=-1 137 | kerning first=65 second=63 amount=-1 138 | kerning first=89 second=85 amount=-1 139 | kerning first=84 second=118 amount=-1 140 | kerning first=111 second=39 amount=-2 141 | kerning first=46 second=34 amount=-3 142 | kerning first=84 second=97 amount=-2 143 | kerning first=114 second=116 amount=1 144 | kerning first=82 second=84 amount=-1 145 | kerning first=76 second=87 amount=-2 146 | kerning first=65 second=89 amount=-1 147 | kerning first=89 second=111 amount=-1 148 | kerning first=65 second=34 amount=-2 149 | kerning first=84 second=110 amount=-2 150 | kerning first=44 second=34 amount=-3 151 | kerning first=76 second=79 amount=-1 152 | kerning first=46 second=39 amount=-3 153 | kerning first=79 second=46 amount=-2 154 | kerning first=82 second=89 amount=-1 155 | kerning first=65 second=39 amount=-2 156 | kerning first=119 second=46 amount=-2 157 | kerning first=84 second=115 amount=-2 158 | kerning first=70 second=74 amount=-4 159 | kerning first=44 second=39 amount=-3 160 | kerning first=76 second=84 amount=-4 161 | kerning first=89 second=74 amount=-1 162 | kerning first=65 second=86 amount=-1 163 | kerning first=86 second=65 amount=-1 164 | kerning first=76 second=118 amount=-2 165 | kerning first=86 second=99 amount=-1 166 | kerning first=86 second=44 amount=-4 167 | kerning first=84 second=120 amount=-1 168 | kerning first=84 second=65 amount=-1 169 | kerning first=34 second=97 amount=-1 170 | kerning first=84 second=99 amount=-2 171 | kerning first=89 second=45 amount=-1 172 | kerning first=32 second=84 amount=-1 173 | kerning first=84 second=44 amount=-3 174 | kerning first=97 second=34 amount=-1 175 | kerning first=76 second=89 amount=-4 176 | kerning first=39 second=111 amount=-1 177 | kerning first=76 second=34 amount=-5 178 | kerning first=114 second=97 amount=-1 179 | kerning first=87 second=45 amount=-1 180 | kerning first=34 second=34 amount=-2 181 | kerning first=75 second=119 amount=-1 182 | kerning first=80 second=65 amount=-2 183 | kerning first=97 second=39 amount=-1 184 | kerning first=80 second=44 amount=-5 185 | kerning first=70 second=97 amount=-1 186 | kerning first=76 second=39 amount=-5 187 | kerning first=34 second=115 amount=-1 188 | kerning first=84 second=117 amount=-1 189 | kerning first=89 second=97 amount=-1 190 | kerning first=34 second=39 amount=-2 191 | kerning first=89 second=42 amount=-1 192 | kerning first=76 second=86 amount=-3 193 | kerning first=118 second=44 amount=-2 194 | kerning first=89 second=110 amount=-1 195 | kerning first=87 second=97 amount=-1 196 | kerning first=110 second=34 amount=-2 197 | kerning first=86 second=46 amount=-4 198 | kerning first=34 second=65 amount=-2 199 | kerning first=84 second=122 amount=-1 200 | kerning first=34 second=99 amount=-1 201 | kerning first=84 second=46 amount=-3 202 | kerning first=66 second=89 amount=-1 203 | kerning first=89 second=115 amount=-1 204 | kerning first=47 second=47 amount=-3 205 | kerning first=84 second=114 amount=-1 206 | kerning first=114 second=44 amount=-2 207 | kerning first=110 second=39 amount=-2 208 | kerning first=81 second=84 amount=-1 209 | kerning first=76 second=117 amount=-1 210 | kerning first=65 second=119 amount=-1 211 | kerning first=70 second=65 amount=-3 212 | kerning first=80 second=46 amount=-5 213 | kerning first=75 second=45 amount=-1 214 | kerning first=70 second=44 amount=-4 215 | kerning first=84 second=119 amount=-1 216 | kerning first=89 second=65 amount=-1 217 | kerning first=39 second=97 amount=-1 218 | kerning first=86 second=111 amount=-1 219 | kerning first=89 second=99 amount=-1 220 | kerning first=89 second=44 amount=-3 221 | kerning first=81 second=89 amount=-1 222 | -------------------------------------------------------------------------------- /src/test/testData/results/bitmapFont/roboto32px.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/BlueBoxWare/LibGDXGradlePlugin/3fe89c80b9deeae63ee404c281ff004b195d58b9/src/test/testData/results/bitmapFont/roboto32px.png -------------------------------------------------------------------------------- /src/test/testData/results/bitmapFont/wobble.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/BlueBoxWare/LibGDXGradlePlugin/3fe89c80b9deeae63ee404c281ff004b195d58b9/src/test/testData/results/bitmapFont/wobble.png -------------------------------------------------------------------------------- /src/test/testData/results/bitmapFont/zigzag.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/BlueBoxWare/LibGDXGradlePlugin/3fe89c80b9deeae63ee404c281ff004b195d58b9/src/test/testData/results/bitmapFont/zigzag.png -------------------------------------------------------------------------------- /src/test/testData/results/distanceField/df_red.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/BlueBoxWare/LibGDXGradlePlugin/3fe89c80b9deeae63ee404c281ff004b195d58b9/src/test/testData/results/distanceField/df_red.png -------------------------------------------------------------------------------- /src/test/testData/results/distanceField/df_wat.jpg: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/BlueBoxWare/LibGDXGradlePlugin/3fe89c80b9deeae63ee404c281ff004b195d58b9/src/test/testData/results/distanceField/df_wat.jpg -------------------------------------------------------------------------------- /src/test/testData/results/distanceField/df_white.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/BlueBoxWare/LibGDXGradlePlugin/3fe89c80b9deeae63ee404c281ff004b195d58b9/src/test/testData/results/distanceField/df_white.png -------------------------------------------------------------------------------- /src/test/testData/results/distanceField/wat-df.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/BlueBoxWare/LibGDXGradlePlugin/3fe89c80b9deeae63ee404c281ff004b195d58b9/src/test/testData/results/distanceField/wat-df.png -------------------------------------------------------------------------------- /src/test/testData/results/packTextures/customSettings/pack1Foo.atlas: -------------------------------------------------------------------------------- 1 | 2 | pack1Foo.jpg 3 | size: 512, 128 4 | format: RGBA8888 5 | filter: MipMapLinearNearest, Linear 6 | repeat: none 7 | add 8 | rotate: false 9 | xy: 2, 2 10 | size: 96, 96 11 | orig: 96, 96 12 | offset: 0, 0 13 | index: -1 14 | back 15 | rotate: false 16 | xy: 100, 2 17 | size: 96, 96 18 | orig: 96, 96 19 | offset: 0, 0 20 | index: -1 21 | bottom 22 | rotate: false 23 | xy: 198, 2 24 | size: 96, 96 25 | orig: 96, 96 26 | offset: 0, 0 27 | index: -1 28 | -------------------------------------------------------------------------------- /src/test/testData/results/packTextures/customSettings/pack1Scaled.jpg: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/BlueBoxWare/LibGDXGradlePlugin/3fe89c80b9deeae63ee404c281ff004b195d58b9/src/test/testData/results/packTextures/customSettings/pack1Scaled.jpg -------------------------------------------------------------------------------- /src/test/testData/results/packTextures/customSettings/pack2Normal2.jpg: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/BlueBoxWare/LibGDXGradlePlugin/3fe89c80b9deeae63ee404c281ff004b195d58b9/src/test/testData/results/packTextures/customSettings/pack2Normal2.jpg -------------------------------------------------------------------------------- /src/test/testData/results/packTextures/customSettings/pack2Scaled.atlas: -------------------------------------------------------------------------------- 1 | 2 | pack2Scaled.jpg 3 | size: 512, 128 4 | format: RGBA8888 5 | filter: MipMapLinearNearest, Linear 6 | repeat: none 7 | binary 8 | rotate: false 9 | xy: 2, 2 10 | size: 64, 64 11 | orig: 64, 64 12 | offset: 0, 0 13 | index: -1 14 | deb 15 | rotate: false 16 | xy: 68, 2 17 | size: 64, 64 18 | orig: 64, 64 19 | offset: 0, 0 20 | index: -1 21 | document 22 | rotate: false 23 | xy: 134, 2 24 | size: 64, 64 25 | orig: 64, 64 26 | offset: 0, 0 27 | index: -1 28 | empty 29 | rotate: false 30 | xy: 200, 2 31 | size: 64, 64 32 | orig: 64, 64 33 | offset: 0, 0 34 | index: -1 35 | 36 | pack2Scaled2.jpg 37 | size: 256, 128 38 | format: RGBA8888 39 | filter: MipMapLinearNearest, Linear 40 | repeat: none 41 | sub/binary 42 | rotate: false 43 | xy: 2, 2 44 | size: 64, 64 45 | orig: 64, 64 46 | offset: 0, 0 47 | index: -1 48 | sub/image 49 | rotate: false 50 | xy: 68, 2 51 | size: 64, 64 52 | orig: 64, 64 53 | offset: 0, 0 54 | index: -1 55 | 56 | pack2Scaled3.jpg 57 | size: 256, 128 58 | format: RGBA8888 59 | filter: MipMapLinearNearest, Linear 60 | repeat: none 61 | sub/subsub/plan 62 | rotate: false 63 | xy: 2, 2 64 | size: 64, 64 65 | orig: 64, 64 66 | offset: 0, 0 67 | index: -1 68 | sub/subsub/spreadsheet 69 | rotate: false 70 | xy: 68, 2 71 | size: 64, 64 72 | orig: 64, 64 73 | offset: 0, 0 74 | index: -1 75 | -------------------------------------------------------------------------------- /src/test/testData/results/packTextures/customTask.atlas: -------------------------------------------------------------------------------- 1 | 2 | customTask.png 3 | size: 128, 64 4 | format: RGBA8888 5 | filter: MipMapLinearLinear, Nearest 6 | repeat: none 7 | add 8 | rotate: false 9 | xy: 2, 2 10 | size: 32, 32 11 | orig: 32, 32 12 | offset: 0, 0 13 | index: -1 14 | back 15 | rotate: false 16 | xy: 36, 2 17 | size: 32, 32 18 | orig: 32, 32 19 | offset: 0, 0 20 | index: -1 21 | bottom 22 | rotate: false 23 | xy: 70, 2 24 | size: 32, 32 25 | orig: 32, 32 26 | offset: 0, 0 27 | index: -1 28 | -------------------------------------------------------------------------------- /src/test/testData/results/packTextures/filteringAndRenaming.atlas: -------------------------------------------------------------------------------- 1 | 2 | pack.png 3 | size: 256, 64 4 | format: RGBA8888 5 | filter: Nearest, Nearest 6 | repeat: none 7 | backck 8 | rotate: false 9 | xy: 2, 2 10 | size: 32, 32 11 | orig: 32, 32 12 | offset: 0, 0 13 | index: -1 14 | binary 15 | rotate: false 16 | xy: 36, 2 17 | size: 32, 32 18 | orig: 32, 32 19 | offset: 0, 0 20 | index: -1 21 | bottom 22 | rotate: false 23 | xy: 70, 2 24 | size: 32, 32 25 | orig: 32, 32 26 | offset: 0, 0 27 | index: -1 28 | deb 29 | rotate: false 30 | xy: 104, 2 31 | size: 32, 32 32 | orig: 32, 32 33 | offset: 0, 0 34 | index: -1 35 | document 36 | rotate: false 37 | xy: 138, 2 38 | size: 32, 32 39 | orig: 32, 32 40 | offset: 0, 0 41 | index: -1 42 | 43 | pack2.png 44 | size: 128, 64 45 | format: RGBA8888 46 | filter: Nearest, Nearest 47 | repeat: none 48 | sub/binary 49 | rotate: false 50 | xy: 2, 2 51 | size: 32, 32 52 | orig: 32, 32 53 | offset: 0, 0 54 | index: -1 55 | sub/image 56 | rotate: false 57 | xy: 36, 2 58 | size: 32, 32 59 | orig: 32, 32 60 | offset: 0, 0 61 | index: -1 62 | -------------------------------------------------------------------------------- /src/test/testData/results/packTextures/minimalSpec.atlas: -------------------------------------------------------------------------------- 1 | 2 | pack.png 3 | size: 128, 64 4 | format: RGBA8888 5 | filter: Nearest, Nearest 6 | repeat: none 7 | images2/add 8 | rotate: false 9 | xy: 2, 2 10 | size: 32, 32 11 | orig: 32, 32 12 | offset: 0, 0 13 | index: -1 14 | images2/back 15 | rotate: false 16 | xy: 36, 2 17 | size: 32, 32 18 | orig: 32, 32 19 | offset: 0, 0 20 | index: -1 21 | images2/bottom 22 | rotate: false 23 | xy: 70, 2 24 | size: 32, 32 25 | orig: 32, 32 26 | offset: 0, 0 27 | index: -1 28 | 29 | pack2.png 30 | size: 256, 64 31 | format: RGBA8888 32 | filter: Nearest, Nearest 33 | repeat: none 34 | images1/binary 35 | rotate: false 36 | xy: 2, 2 37 | size: 32, 32 38 | orig: 32, 32 39 | offset: 0, 0 40 | index: -1 41 | images1/deb 42 | rotate: false 43 | xy: 36, 2 44 | size: 32, 32 45 | orig: 32, 32 46 | offset: 0, 0 47 | index: -1 48 | images1/document 49 | rotate: false 50 | xy: 70, 2 51 | size: 32, 32 52 | orig: 32, 32 53 | offset: 0, 0 54 | index: -1 55 | images1/empty 56 | rotate: false 57 | xy: 104, 2 58 | size: 32, 32 59 | orig: 32, 32 60 | offset: 0, 0 61 | index: -1 62 | 63 | pack3.png 64 | size: 128, 64 65 | format: RGBA8888 66 | filter: Nearest, Nearest 67 | repeat: none 68 | images1/sub/binary 69 | rotate: false 70 | xy: 2, 2 71 | size: 32, 32 72 | orig: 32, 32 73 | offset: 0, 0 74 | index: -1 75 | images1/sub/image 76 | rotate: false 77 | xy: 36, 2 78 | size: 32, 32 79 | orig: 32, 32 80 | offset: 0, 0 81 | index: -1 82 | 83 | pack4.png 84 | size: 128, 64 85 | format: RGBA8888 86 | filter: Nearest, Nearest 87 | repeat: none 88 | images1/sub/subsub/plan 89 | rotate: false 90 | xy: 2, 2 91 | size: 32, 32 92 | orig: 32, 32 93 | offset: 0, 0 94 | index: -1 95 | images1/sub/subsub/spreadsheet 96 | rotate: false 97 | xy: 36, 2 98 | size: 32, 32 99 | orig: 32, 32 100 | offset: 0, 0 101 | index: -1 102 | -------------------------------------------------------------------------------- /src/test/testData/results/packTextures/minimalSpecAfterDeletingImage.atlas: -------------------------------------------------------------------------------- 1 | 2 | pack.png 3 | size: 128, 64 4 | format: RGBA8888 5 | filter: Nearest, Nearest 6 | repeat: none 7 | images2/add 8 | rotate: false 9 | xy: 2, 2 10 | size: 32, 32 11 | orig: 32, 32 12 | offset: 0, 0 13 | index: -1 14 | images2/back 15 | rotate: false 16 | xy: 36, 2 17 | size: 32, 32 18 | orig: 32, 32 19 | offset: 0, 0 20 | index: -1 21 | images2/bottom 22 | rotate: false 23 | xy: 70, 2 24 | size: 32, 32 25 | orig: 32, 32 26 | offset: 0, 0 27 | index: -1 28 | 29 | pack2.png 30 | size: 256, 64 31 | format: RGBA8888 32 | filter: Nearest, Nearest 33 | repeat: none 34 | images1/binary 35 | rotate: false 36 | xy: 2, 2 37 | size: 32, 32 38 | orig: 32, 32 39 | offset: 0, 0 40 | index: -1 41 | images1/deb 42 | rotate: false 43 | xy: 36, 2 44 | size: 32, 32 45 | orig: 32, 32 46 | offset: 0, 0 47 | index: -1 48 | images1/document 49 | rotate: false 50 | xy: 70, 2 51 | size: 32, 32 52 | orig: 32, 32 53 | offset: 0, 0 54 | index: -1 55 | images1/empty 56 | rotate: false 57 | xy: 104, 2 58 | size: 32, 32 59 | orig: 32, 32 60 | offset: 0, 0 61 | index: -1 62 | 63 | pack3.png 64 | size: 64, 64 65 | format: RGBA8888 66 | filter: Nearest, Nearest 67 | repeat: none 68 | images1/sub/binary 69 | rotate: false 70 | xy: 2, 2 71 | size: 32, 32 72 | orig: 32, 32 73 | offset: 0, 0 74 | index: -1 75 | 76 | pack4.png 77 | size: 128, 64 78 | format: RGBA8888 79 | filter: Nearest, Nearest 80 | repeat: none 81 | images1/sub/subsub/plan 82 | rotate: false 83 | xy: 2, 2 84 | size: 32, 32 85 | orig: 32, 32 86 | offset: 0, 0 87 | index: -1 88 | images1/sub/subsub/spreadsheet 89 | rotate: false 90 | xy: 36, 2 91 | size: 32, 32 92 | orig: 32, 32 93 | offset: 0, 0 94 | index: -1 95 | -------------------------------------------------------------------------------- /src/test/testData/results/packTextures/multipleScales1.atlas: -------------------------------------------------------------------------------- 1 | 2 | packone.png 3 | size: 128, 64 4 | format: RGBA8888 5 | filter: Nearest, Nearest 6 | repeat: none 7 | images2/add 8 | rotate: false 9 | xy: 2, 2 10 | size: 32, 32 11 | orig: 32, 32 12 | offset: 0, 0 13 | index: -1 14 | images2/back 15 | rotate: false 16 | xy: 36, 2 17 | size: 32, 32 18 | orig: 32, 32 19 | offset: 0, 0 20 | index: -1 21 | images2/bottom 22 | rotate: false 23 | xy: 70, 2 24 | size: 32, 32 25 | orig: 32, 32 26 | offset: 0, 0 27 | index: -1 28 | 29 | packone2.png 30 | size: 256, 64 31 | format: RGBA8888 32 | filter: Nearest, Nearest 33 | repeat: none 34 | images1/binary 35 | rotate: false 36 | xy: 2, 2 37 | size: 32, 32 38 | orig: 32, 32 39 | offset: 0, 0 40 | index: -1 41 | images1/deb 42 | rotate: false 43 | xy: 36, 2 44 | size: 32, 32 45 | orig: 32, 32 46 | offset: 0, 0 47 | index: -1 48 | images1/document 49 | rotate: false 50 | xy: 70, 2 51 | size: 32, 32 52 | orig: 32, 32 53 | offset: 0, 0 54 | index: -1 55 | images1/empty 56 | rotate: false 57 | xy: 104, 2 58 | size: 32, 32 59 | orig: 32, 32 60 | offset: 0, 0 61 | index: -1 62 | 63 | packone3.png 64 | size: 128, 64 65 | format: RGBA8888 66 | filter: Nearest, Nearest 67 | repeat: none 68 | images1/sub/binary 69 | rotate: false 70 | xy: 2, 2 71 | size: 32, 32 72 | orig: 32, 32 73 | offset: 0, 0 74 | index: -1 75 | images1/sub/image 76 | rotate: false 77 | xy: 36, 2 78 | size: 32, 32 79 | orig: 32, 32 80 | offset: 0, 0 81 | index: -1 82 | 83 | packone4.png 84 | size: 128, 64 85 | format: RGBA8888 86 | filter: Nearest, Nearest 87 | repeat: none 88 | images1/sub/subsub/plan 89 | rotate: false 90 | xy: 2, 2 91 | size: 32, 32 92 | orig: 32, 32 93 | offset: 0, 0 94 | index: -1 95 | images1/sub/subsub/spreadsheet 96 | rotate: false 97 | xy: 36, 2 98 | size: 32, 32 99 | orig: 32, 32 100 | offset: 0, 0 101 | index: -1 102 | -------------------------------------------------------------------------------- /src/test/testData/results/packTextures/multipleScales2.atlas: -------------------------------------------------------------------------------- 1 | 2 | packtwo.png 3 | size: 256, 128 4 | format: RGBA8888 5 | filter: Nearest, Nearest 6 | repeat: none 7 | images2/add 8 | rotate: false 9 | xy: 2, 2 10 | size: 64, 64 11 | orig: 64, 64 12 | offset: 0, 0 13 | index: -1 14 | images2/back 15 | rotate: false 16 | xy: 68, 2 17 | size: 64, 64 18 | orig: 64, 64 19 | offset: 0, 0 20 | index: -1 21 | images2/bottom 22 | rotate: false 23 | xy: 134, 2 24 | size: 64, 64 25 | orig: 64, 64 26 | offset: 0, 0 27 | index: -1 28 | 29 | packtwo2.png 30 | size: 512, 128 31 | format: RGBA8888 32 | filter: Nearest, Nearest 33 | repeat: none 34 | images1/binary 35 | rotate: false 36 | xy: 2, 2 37 | size: 64, 64 38 | orig: 64, 64 39 | offset: 0, 0 40 | index: -1 41 | images1/deb 42 | rotate: false 43 | xy: 68, 2 44 | size: 64, 64 45 | orig: 64, 64 46 | offset: 0, 0 47 | index: -1 48 | images1/document 49 | rotate: false 50 | xy: 134, 2 51 | size: 64, 64 52 | orig: 64, 64 53 | offset: 0, 0 54 | index: -1 55 | images1/empty 56 | rotate: false 57 | xy: 200, 2 58 | size: 64, 64 59 | orig: 64, 64 60 | offset: 0, 0 61 | index: -1 62 | 63 | packtwo3.png 64 | size: 256, 128 65 | format: RGBA8888 66 | filter: Nearest, Nearest 67 | repeat: none 68 | images1/sub/binary 69 | rotate: false 70 | xy: 2, 2 71 | size: 64, 64 72 | orig: 64, 64 73 | offset: 0, 0 74 | index: -1 75 | images1/sub/image 76 | rotate: false 77 | xy: 68, 2 78 | size: 64, 64 79 | orig: 64, 64 80 | offset: 0, 0 81 | index: -1 82 | 83 | packtwo4.png 84 | size: 256, 128 85 | format: RGBA8888 86 | filter: Nearest, Nearest 87 | repeat: none 88 | images1/sub/subsub/plan 89 | rotate: false 90 | xy: 2, 2 91 | size: 64, 64 92 | orig: 64, 64 93 | offset: 0, 0 94 | index: -1 95 | images1/sub/subsub/spreadsheet 96 | rotate: false 97 | xy: 68, 2 98 | size: 64, 64 99 | orig: 64, 64 100 | offset: 0, 0 101 | index: -1 102 | -------------------------------------------------------------------------------- /src/test/testData/results/packTextures/multipleScales3.atlas: -------------------------------------------------------------------------------- 1 | 2 | packthree.png 3 | size: 512, 128 4 | format: RGBA8888 5 | filter: Nearest, Nearest 6 | repeat: none 7 | images2/add 8 | rotate: false 9 | xy: 2, 2 10 | size: 96, 96 11 | orig: 96, 96 12 | offset: 0, 0 13 | index: -1 14 | images2/back 15 | rotate: false 16 | xy: 100, 2 17 | size: 96, 96 18 | orig: 96, 96 19 | offset: 0, 0 20 | index: -1 21 | images2/bottom 22 | rotate: false 23 | xy: 198, 2 24 | size: 96, 96 25 | orig: 96, 96 26 | offset: 0, 0 27 | index: -1 28 | 29 | packthree2.png 30 | size: 512, 128 31 | format: RGBA8888 32 | filter: Nearest, Nearest 33 | repeat: none 34 | images1/binary 35 | rotate: false 36 | xy: 2, 2 37 | size: 96, 96 38 | orig: 96, 96 39 | offset: 0, 0 40 | index: -1 41 | images1/deb 42 | rotate: false 43 | xy: 100, 2 44 | size: 96, 96 45 | orig: 96, 96 46 | offset: 0, 0 47 | index: -1 48 | images1/document 49 | rotate: false 50 | xy: 198, 2 51 | size: 96, 96 52 | orig: 96, 96 53 | offset: 0, 0 54 | index: -1 55 | images1/empty 56 | rotate: false 57 | xy: 296, 2 58 | size: 96, 96 59 | orig: 96, 96 60 | offset: 0, 0 61 | index: -1 62 | 63 | packthree3.png 64 | size: 256, 128 65 | format: RGBA8888 66 | filter: Nearest, Nearest 67 | repeat: none 68 | images1/sub/binary 69 | rotate: false 70 | xy: 2, 2 71 | size: 96, 96 72 | orig: 96, 96 73 | offset: 0, 0 74 | index: -1 75 | images1/sub/image 76 | rotate: false 77 | xy: 100, 2 78 | size: 96, 96 79 | orig: 96, 96 80 | offset: 0, 0 81 | index: -1 82 | 83 | packthree4.png 84 | size: 256, 128 85 | format: RGBA8888 86 | filter: Nearest, Nearest 87 | repeat: none 88 | images1/sub/subsub/plan 89 | rotate: false 90 | xy: 2, 2 91 | size: 96, 96 92 | orig: 96, 96 93 | offset: 0, 0 94 | index: -1 95 | images1/sub/subsub/spreadsheet 96 | rotate: false 97 | xy: 100, 2 98 | size: 96, 96 99 | orig: 96, 96 100 | offset: 0, 0 101 | index: -1 102 | -------------------------------------------------------------------------------- /src/test/testData/results/packTextures/multipleScalesSubdir1.atlas: -------------------------------------------------------------------------------- 1 | 2 | pack.png 3 | size: 128, 64 4 | format: RGBA8888 5 | filter: Nearest, Nearest 6 | repeat: none 7 | images2/add 8 | rotate: false 9 | xy: 2, 2 10 | size: 32, 32 11 | orig: 32, 32 12 | offset: 0, 0 13 | index: -1 14 | images2/back 15 | rotate: false 16 | xy: 36, 2 17 | size: 32, 32 18 | orig: 32, 32 19 | offset: 0, 0 20 | index: -1 21 | images2/bottom 22 | rotate: false 23 | xy: 70, 2 24 | size: 32, 32 25 | orig: 32, 32 26 | offset: 0, 0 27 | index: -1 28 | 29 | pack2.png 30 | size: 256, 64 31 | format: RGBA8888 32 | filter: Nearest, Nearest 33 | repeat: none 34 | images1/binary 35 | rotate: false 36 | xy: 2, 2 37 | size: 32, 32 38 | orig: 32, 32 39 | offset: 0, 0 40 | index: -1 41 | images1/deb 42 | rotate: false 43 | xy: 36, 2 44 | size: 32, 32 45 | orig: 32, 32 46 | offset: 0, 0 47 | index: -1 48 | images1/document 49 | rotate: false 50 | xy: 70, 2 51 | size: 32, 32 52 | orig: 32, 32 53 | offset: 0, 0 54 | index: -1 55 | images1/empty 56 | rotate: false 57 | xy: 104, 2 58 | size: 32, 32 59 | orig: 32, 32 60 | offset: 0, 0 61 | index: -1 62 | 63 | pack3.png 64 | size: 128, 64 65 | format: RGBA8888 66 | filter: Nearest, Nearest 67 | repeat: none 68 | images1/sub/binary 69 | rotate: false 70 | xy: 2, 2 71 | size: 32, 32 72 | orig: 32, 32 73 | offset: 0, 0 74 | index: -1 75 | images1/sub/image 76 | rotate: false 77 | xy: 36, 2 78 | size: 32, 32 79 | orig: 32, 32 80 | offset: 0, 0 81 | index: -1 82 | 83 | pack4.png 84 | size: 128, 64 85 | format: RGBA8888 86 | filter: Nearest, Nearest 87 | repeat: none 88 | images1/sub/subsub/plan 89 | rotate: false 90 | xy: 2, 2 91 | size: 32, 32 92 | orig: 32, 32 93 | offset: 0, 0 94 | index: -1 95 | images1/sub/subsub/spreadsheet 96 | rotate: false 97 | xy: 36, 2 98 | size: 32, 32 99 | orig: 32, 32 100 | offset: 0, 0 101 | index: -1 102 | -------------------------------------------------------------------------------- /src/test/testData/results/packTextures/multipleScalesSubdir2.atlas: -------------------------------------------------------------------------------- 1 | 2 | pack.png 3 | size: 256, 128 4 | format: RGBA8888 5 | filter: Nearest, Nearest 6 | repeat: none 7 | images2/add 8 | rotate: false 9 | xy: 2, 2 10 | size: 64, 64 11 | orig: 64, 64 12 | offset: 0, 0 13 | index: -1 14 | images2/back 15 | rotate: false 16 | xy: 68, 2 17 | size: 64, 64 18 | orig: 64, 64 19 | offset: 0, 0 20 | index: -1 21 | images2/bottom 22 | rotate: false 23 | xy: 134, 2 24 | size: 64, 64 25 | orig: 64, 64 26 | offset: 0, 0 27 | index: -1 28 | 29 | pack2.png 30 | size: 512, 128 31 | format: RGBA8888 32 | filter: Nearest, Nearest 33 | repeat: none 34 | images1/binary 35 | rotate: false 36 | xy: 2, 2 37 | size: 64, 64 38 | orig: 64, 64 39 | offset: 0, 0 40 | index: -1 41 | images1/deb 42 | rotate: false 43 | xy: 68, 2 44 | size: 64, 64 45 | orig: 64, 64 46 | offset: 0, 0 47 | index: -1 48 | images1/document 49 | rotate: false 50 | xy: 134, 2 51 | size: 64, 64 52 | orig: 64, 64 53 | offset: 0, 0 54 | index: -1 55 | images1/empty 56 | rotate: false 57 | xy: 200, 2 58 | size: 64, 64 59 | orig: 64, 64 60 | offset: 0, 0 61 | index: -1 62 | 63 | pack3.png 64 | size: 256, 128 65 | format: RGBA8888 66 | filter: Nearest, Nearest 67 | repeat: none 68 | images1/sub/binary 69 | rotate: false 70 | xy: 2, 2 71 | size: 64, 64 72 | orig: 64, 64 73 | offset: 0, 0 74 | index: -1 75 | images1/sub/image 76 | rotate: false 77 | xy: 68, 2 78 | size: 64, 64 79 | orig: 64, 64 80 | offset: 0, 0 81 | index: -1 82 | 83 | pack4.png 84 | size: 256, 128 85 | format: RGBA8888 86 | filter: Nearest, Nearest 87 | repeat: none 88 | images1/sub/subsub/plan 89 | rotate: false 90 | xy: 2, 2 91 | size: 64, 64 92 | orig: 64, 64 93 | offset: 0, 0 94 | index: -1 95 | images1/sub/subsub/spreadsheet 96 | rotate: false 97 | xy: 68, 2 98 | size: 64, 64 99 | orig: 64, 64 100 | offset: 0, 0 101 | index: -1 102 | -------------------------------------------------------------------------------- /src/test/testData/results/packTextures/multipleScalesSubdir3.atlas: -------------------------------------------------------------------------------- 1 | 2 | pack.png 3 | size: 512, 128 4 | format: RGBA8888 5 | filter: Nearest, Nearest 6 | repeat: none 7 | images2/add 8 | rotate: false 9 | xy: 2, 2 10 | size: 96, 96 11 | orig: 96, 96 12 | offset: 0, 0 13 | index: -1 14 | images2/back 15 | rotate: false 16 | xy: 100, 2 17 | size: 96, 96 18 | orig: 96, 96 19 | offset: 0, 0 20 | index: -1 21 | images2/bottom 22 | rotate: false 23 | xy: 198, 2 24 | size: 96, 96 25 | orig: 96, 96 26 | offset: 0, 0 27 | index: -1 28 | 29 | pack2.png 30 | size: 512, 128 31 | format: RGBA8888 32 | filter: Nearest, Nearest 33 | repeat: none 34 | images1/binary 35 | rotate: false 36 | xy: 2, 2 37 | size: 96, 96 38 | orig: 96, 96 39 | offset: 0, 0 40 | index: -1 41 | images1/deb 42 | rotate: false 43 | xy: 100, 2 44 | size: 96, 96 45 | orig: 96, 96 46 | offset: 0, 0 47 | index: -1 48 | images1/document 49 | rotate: false 50 | xy: 198, 2 51 | size: 96, 96 52 | orig: 96, 96 53 | offset: 0, 0 54 | index: -1 55 | images1/empty 56 | rotate: false 57 | xy: 296, 2 58 | size: 96, 96 59 | orig: 96, 96 60 | offset: 0, 0 61 | index: -1 62 | 63 | pack3.png 64 | size: 256, 128 65 | format: RGBA8888 66 | filter: Nearest, Nearest 67 | repeat: none 68 | images1/sub/binary 69 | rotate: false 70 | xy: 2, 2 71 | size: 96, 96 72 | orig: 96, 96 73 | offset: 0, 0 74 | index: -1 75 | images1/sub/image 76 | rotate: false 77 | xy: 100, 2 78 | size: 96, 96 79 | orig: 96, 96 80 | offset: 0, 0 81 | index: -1 82 | 83 | pack4.png 84 | size: 256, 128 85 | format: RGBA8888 86 | filter: Nearest, Nearest 87 | repeat: none 88 | images1/sub/subsub/plan 89 | rotate: false 90 | xy: 2, 2 91 | size: 96, 96 92 | orig: 96, 96 93 | offset: 0, 0 94 | index: -1 95 | images1/sub/subsub/spreadsheet 96 | rotate: false 97 | xy: 100, 2 98 | size: 96, 96 99 | orig: 96, 96 100 | offset: 0, 0 101 | index: -1 102 | -------------------------------------------------------------------------------- /src/test/testData/results/packTextures/namedContainerPack1.atlas: -------------------------------------------------------------------------------- 1 | 2 | pack1.png 3 | size: 256, 64 4 | format: RGBA8888 5 | filter: Nearest, Nearest 6 | repeat: none 7 | binary 8 | rotate: false 9 | xy: 2, 2 10 | size: 32, 32 11 | orig: 32, 32 12 | offset: 0, 0 13 | index: -1 14 | deb 15 | rotate: false 16 | xy: 36, 2 17 | size: 32, 32 18 | orig: 32, 32 19 | offset: 0, 0 20 | index: -1 21 | document 22 | rotate: false 23 | xy: 70, 2 24 | size: 32, 32 25 | orig: 32, 32 26 | offset: 0, 0 27 | index: -1 28 | empty 29 | rotate: false 30 | xy: 104, 2 31 | size: 32, 32 32 | orig: 32, 32 33 | offset: 0, 0 34 | index: -1 35 | 36 | pack1-2.png 37 | size: 128, 64 38 | format: RGBA8888 39 | filter: Nearest, Nearest 40 | repeat: none 41 | sub/binary 42 | rotate: false 43 | xy: 2, 2 44 | size: 32, 32 45 | orig: 32, 32 46 | offset: 0, 0 47 | index: -1 48 | sub/image 49 | rotate: false 50 | xy: 36, 2 51 | size: 32, 32 52 | orig: 32, 32 53 | offset: 0, 0 54 | index: -1 55 | 56 | pack1-3.png 57 | size: 128, 64 58 | format: RGBA8888 59 | filter: Nearest, Nearest 60 | repeat: none 61 | sub/subsub/plan 62 | rotate: false 63 | xy: 2, 2 64 | size: 32, 32 65 | orig: 32, 32 66 | offset: 0, 0 67 | index: -1 68 | sub/subsub/spreadsheet 69 | rotate: false 70 | xy: 36, 2 71 | size: 32, 32 72 | orig: 32, 32 73 | offset: 0, 0 74 | index: -1 75 | -------------------------------------------------------------------------------- /src/test/testData/results/packTextures/namedContainerPack2.atlas: -------------------------------------------------------------------------------- 1 | 2 | test.png 3 | size: 128, 64 4 | format: RGBA8888 5 | filter: MipMapLinearLinear, Nearest 6 | repeat: none 7 | add 8 | rotate: false 9 | xy: 2, 2 10 | size: 32, 32 11 | orig: 32, 32 12 | offset: 0, 0 13 | index: -1 14 | back 15 | rotate: false 16 | xy: 36, 2 17 | size: 32, 32 18 | orig: 32, 32 19 | offset: 0, 0 20 | index: -1 21 | bottom 22 | rotate: false 23 | xy: 70, 2 24 | size: 32, 32 25 | orig: 32, 32 26 | offset: 0, 0 27 | index: -1 28 | -------------------------------------------------------------------------------- /src/test/testData/results/packTextures/namedContainerPack3.atlas: -------------------------------------------------------------------------------- 1 | 2 | pack3.png 3 | size: 128, 64 4 | format: RGBA8888 5 | filter: Nearest, Nearest 6 | repeat: none 7 | images2/add 8 | rotate: false 9 | xy: 2, 2 10 | size: 32, 32 11 | orig: 32, 32 12 | offset: 0, 0 13 | index: -1 14 | images2/back 15 | rotate: false 16 | xy: 36, 2 17 | size: 32, 32 18 | orig: 32, 32 19 | offset: 0, 0 20 | index: -1 21 | images2/bottom 22 | rotate: false 23 | xy: 70, 2 24 | size: 32, 32 25 | orig: 32, 32 26 | offset: 0, 0 27 | index: -1 28 | 29 | pack3-2.png 30 | size: 256, 64 31 | format: RGBA8888 32 | filter: Nearest, Nearest 33 | repeat: none 34 | images1/binary 35 | rotate: false 36 | xy: 2, 2 37 | size: 32, 32 38 | orig: 32, 32 39 | offset: 0, 0 40 | index: -1 41 | images1/deb 42 | rotate: false 43 | xy: 36, 2 44 | size: 32, 32 45 | orig: 32, 32 46 | offset: 0, 0 47 | index: -1 48 | images1/document 49 | rotate: false 50 | xy: 70, 2 51 | size: 32, 32 52 | orig: 32, 32 53 | offset: 0, 0 54 | index: -1 55 | images1/empty 56 | rotate: false 57 | xy: 104, 2 58 | size: 32, 32 59 | orig: 32, 32 60 | offset: 0, 0 61 | index: -1 62 | 63 | pack3-3.png 64 | size: 128, 64 65 | format: RGBA8888 66 | filter: Nearest, Nearest 67 | repeat: none 68 | images1/sub/binary 69 | rotate: false 70 | xy: 2, 2 71 | size: 32, 32 72 | orig: 32, 32 73 | offset: 0, 0 74 | index: -1 75 | images1/sub/image 76 | rotate: false 77 | xy: 36, 2 78 | size: 32, 32 79 | orig: 32, 32 80 | offset: 0, 0 81 | index: -1 82 | 83 | pack3-4.png 84 | size: 128, 64 85 | format: RGBA8888 86 | filter: Nearest, Nearest 87 | repeat: none 88 | images1/sub/subsub/plan 89 | rotate: false 90 | xy: 2, 2 91 | size: 32, 32 92 | orig: 32, 32 93 | offset: 0, 0 94 | index: -1 95 | images1/sub/subsub/spreadsheet 96 | rotate: false 97 | xy: 36, 2 98 | size: 32, 32 99 | orig: 32, 32 100 | offset: 0, 0 101 | index: -1 102 | -------------------------------------------------------------------------------- /src/test/testData/results/packTextures/noLegacyOutput.atlas: -------------------------------------------------------------------------------- 1 | pack.png 2 | size: 16, 16 3 | solid 4 | bounds: 2, 2, 3, 4 5 | 6 | pack2.png 7 | size: 128, 64 8 | images2/add 9 | bounds: 2, 2, 32, 32 10 | images2/back 11 | bounds: 36, 2, 32, 32 12 | images2/bottom 13 | bounds: 70, 2, 32, 32 14 | 15 | pack3.png 16 | size: 256, 64 17 | images1/binary 18 | bounds: 2, 2, 32, 32 19 | images1/deb 20 | bounds: 36, 2, 32, 32 21 | images1/document 22 | bounds: 70, 2, 32, 32 23 | images1/empty 24 | bounds: 104, 2, 32, 32 25 | 26 | pack4.png 27 | size: 128, 64 28 | images1/sub/binary 29 | bounds: 2, 2, 32, 32 30 | images1/sub/image 31 | bounds: 36, 2, 32, 32 32 | 33 | pack5.png 34 | size: 128, 64 35 | images1/sub/subsub/plan 36 | bounds: 2, 2, 32, 32 37 | images1/sub/subsub/spreadsheet 38 | bounds: 36, 2, 32, 32 39 | -------------------------------------------------------------------------------- /src/test/testData/results/packTextures/solids.atlas: -------------------------------------------------------------------------------- 1 | 2 | pack.png 3 | size: 16, 16 4 | format: RGBA8888 5 | filter: Nearest, Nearest 6 | repeat: none 7 | green 8 | rotate: false 9 | xy: 2, 2 10 | size: 1, 4 11 | orig: 1, 4 12 | offset: 0, 0 13 | index: -1 14 | red 15 | rotate: false 16 | xy: 2, 8 17 | size: 3, 4 18 | orig: 3, 4 19 | offset: 0, 0 20 | index: -1 21 | white 22 | rotate: false 23 | xy: 7, 11 24 | size: 1, 1 25 | orig: 1, 1 26 | offset: 0, 0 27 | index: -1 28 | -------------------------------------------------------------------------------- /src/test/testData/results/packTextures/solids.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/BlueBoxWare/LibGDXGradlePlugin/3fe89c80b9deeae63ee404c281ff004b195d58b9/src/test/testData/results/packTextures/solids.png -------------------------------------------------------------------------------- /src/test/testData/results/packTextures/withAllSettings1.atlas: -------------------------------------------------------------------------------- 1 | 2 | pack1.jpg 3 | size: 512, 128 4 | format: RGBA4444 5 | filter: MipMap, Linear 6 | repeat: none 7 | binary 8 | rotate: false 9 | xy: 72, 0 10 | size: 29, 31 11 | orig: 32, 32 12 | offset: 2, 0 13 | index: -1 14 | deb 15 | rotate: false 16 | xy: 180, 0 17 | size: 32, 24 18 | orig: 32, 32 19 | offset: 0, 3 20 | index: -1 21 | document 22 | rotate: false 23 | xy: 216, 0 24 | size: 30, 31 25 | orig: 32, 32 26 | offset: 1, 0 27 | index: -1 28 | empty 29 | rotate: false 30 | xy: 252, 0 31 | size: 30, 31 32 | orig: 32, 32 33 | offset: 1, 0 34 | index: -1 35 | binary 36 | rotate: false 37 | xy: 108, 0 38 | size: 29, 31 39 | orig: 32, 32 40 | offset: 2, 0 41 | index: -1 42 | image 43 | rotate: false 44 | xy: 288, 0 45 | size: 32, 26 46 | orig: 32, 32 47 | offset: 0, 3 48 | index: -1 49 | plan 50 | rotate: false 51 | xy: 324, 0 52 | size: 31, 31 53 | orig: 32, 32 54 | offset: 1, 1 55 | index: -1 56 | spreadsheet 57 | rotate: false 58 | xy: 360, 0 59 | size: 31, 31 60 | orig: 32, 32 61 | offset: 1, 0 62 | index: -1 63 | add 64 | rotate: false 65 | xy: 0, 0 66 | size: 22, 22 67 | orig: 32, 32 68 | offset: 5, 4 69 | index: -1 70 | back 71 | rotate: false 72 | xy: 36, 0 73 | size: 28, 26 74 | orig: 32, 32 75 | offset: 2, 3 76 | index: -1 77 | bottom 78 | rotate: false 79 | xy: 144, 0 80 | size: 26, 30 81 | orig: 32, 32 82 | offset: 3, 0 83 | index: -1 84 | -------------------------------------------------------------------------------- /src/test/testData/results/packTextures/withAllSettings1.jpg: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/BlueBoxWare/LibGDXGradlePlugin/3fe89c80b9deeae63ee404c281ff004b195d58b9/src/test/testData/results/packTextures/withAllSettings1.jpg -------------------------------------------------------------------------------- /src/test/testData/results/packTextures/withAllSettings2.atlas: -------------------------------------------------------------------------------- 1 | 2 | pack2.jpg 3 | size: 1024, 128 4 | format: RGBA4444 5 | filter: MipMap, Linear 6 | repeat: none 7 | binary 8 | rotate: false 9 | xy: 136, 0 10 | size: 56, 61 11 | orig: 64, 64 12 | offset: 5, 0 13 | index: -1 14 | deb 15 | rotate: false 16 | xy: 340, 0 17 | size: 64, 46 18 | orig: 64, 64 19 | offset: 0, 7 20 | index: -1 21 | document 22 | rotate: false 23 | xy: 408, 0 24 | size: 58, 61 25 | orig: 64, 64 26 | offset: 3, 0 27 | index: -1 28 | empty 29 | rotate: false 30 | xy: 476, 0 31 | size: 58, 61 32 | orig: 64, 64 33 | offset: 3, 0 34 | index: -1 35 | binary 36 | rotate: false 37 | xy: 204, 0 38 | size: 56, 61 39 | orig: 64, 64 40 | offset: 5, 0 41 | index: -1 42 | image 43 | rotate: false 44 | xy: 544, 0 45 | size: 62, 50 46 | orig: 64, 64 47 | offset: 1, 7 48 | index: -1 49 | plan 50 | rotate: false 51 | xy: 612, 0 52 | size: 60, 60 53 | orig: 64, 64 54 | offset: 3, 3 55 | index: -1 56 | spreadsheet 57 | rotate: false 58 | xy: 680, 0 59 | size: 61, 61 60 | orig: 64, 64 61 | offset: 3, 0 62 | index: -1 63 | add 64 | rotate: false 65 | xy: 0, 0 66 | size: 42, 42 67 | orig: 64, 64 68 | offset: 11, 9 69 | index: -1 70 | back 71 | rotate: false 72 | xy: 68, 0 73 | size: 54, 50 74 | orig: 64, 64 75 | offset: 5, 7 76 | index: -1 77 | bottom 78 | rotate: false 79 | xy: 272, 0 80 | size: 50, 58 81 | orig: 64, 64 82 | offset: 7, 1 83 | index: -1 84 | -------------------------------------------------------------------------------- /src/test/testData/results/packTextures/withAllSettings2.jpg: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/BlueBoxWare/LibGDXGradlePlugin/3fe89c80b9deeae63ee404c281ff004b195d58b9/src/test/testData/results/packTextures/withAllSettings2.jpg -------------------------------------------------------------------------------- /src/test/testData/results/packTextures/withSettingsAndCustomName.atlas: -------------------------------------------------------------------------------- 1 | 2 | textures.png 3 | size: 128, 64 4 | format: RGB565 5 | filter: MipMapLinearNearest, MipMap 6 | repeat: none 7 | images2/add 8 | rotate: false 9 | xy: 2, 2 10 | size: 32, 32 11 | orig: 32, 32 12 | offset: 0, 0 13 | index: -1 14 | images2/back 15 | rotate: false 16 | xy: 36, 2 17 | size: 32, 32 18 | orig: 32, 32 19 | offset: 0, 0 20 | index: -1 21 | images2/bottom 22 | rotate: false 23 | xy: 70, 2 24 | size: 32, 32 25 | orig: 32, 32 26 | offset: 0, 0 27 | index: -1 28 | 29 | textures2.png 30 | size: 256, 64 31 | format: RGB565 32 | filter: MipMapLinearNearest, MipMap 33 | repeat: none 34 | images1/binary 35 | rotate: false 36 | xy: 2, 2 37 | size: 32, 32 38 | orig: 32, 32 39 | offset: 0, 0 40 | index: -1 41 | images1/deb 42 | rotate: false 43 | xy: 36, 2 44 | size: 32, 32 45 | orig: 32, 32 46 | offset: 0, 0 47 | index: -1 48 | images1/document 49 | rotate: false 50 | xy: 70, 2 51 | size: 32, 32 52 | orig: 32, 32 53 | offset: 0, 0 54 | index: -1 55 | images1/empty 56 | rotate: false 57 | xy: 104, 2 58 | size: 32, 32 59 | orig: 32, 32 60 | offset: 0, 0 61 | index: -1 62 | 63 | textures3.png 64 | size: 128, 64 65 | format: RGB565 66 | filter: MipMapLinearNearest, MipMap 67 | repeat: none 68 | images1/sub/binary 69 | rotate: false 70 | xy: 2, 2 71 | size: 32, 32 72 | orig: 32, 32 73 | offset: 0, 0 74 | index: -1 75 | images1/sub/image 76 | rotate: false 77 | xy: 36, 2 78 | size: 32, 32 79 | orig: 32, 32 80 | offset: 0, 0 81 | index: -1 82 | 83 | textures4.png 84 | size: 128, 64 85 | format: RGB565 86 | filter: MipMapLinearNearest, MipMap 87 | repeat: none 88 | images1/sub/subsub/plan 89 | rotate: false 90 | xy: 2, 2 91 | size: 32, 32 92 | orig: 32, 32 93 | offset: 0, 0 94 | index: -1 95 | images1/sub/subsub/spreadsheet 96 | rotate: false 97 | xy: 36, 2 98 | size: 32, 32 99 | orig: 32, 32 100 | offset: 0, 0 101 | index: -1 102 | -------------------------------------------------------------------------------- /src/test/testData/results/packTextures/withSettingsAndCustomName2.atlas: -------------------------------------------------------------------------------- 1 | 2 | textures.png 3 | size: 128, 64 4 | format: RGB565 5 | filter: Linear, MipMap 6 | repeat: none 7 | images2/add 8 | rotate: false 9 | xy: 2, 2 10 | size: 32, 32 11 | orig: 32, 32 12 | offset: 0, 0 13 | index: -1 14 | images2/back 15 | rotate: false 16 | xy: 36, 2 17 | size: 32, 32 18 | orig: 32, 32 19 | offset: 0, 0 20 | index: -1 21 | images2/bottom 22 | rotate: false 23 | xy: 70, 2 24 | size: 32, 32 25 | orig: 32, 32 26 | offset: 0, 0 27 | index: -1 28 | 29 | textures2.png 30 | size: 256, 64 31 | format: RGB565 32 | filter: Linear, MipMap 33 | repeat: none 34 | images1/binary 35 | rotate: false 36 | xy: 2, 2 37 | size: 32, 32 38 | orig: 32, 32 39 | offset: 0, 0 40 | index: -1 41 | images1/deb 42 | rotate: false 43 | xy: 36, 2 44 | size: 32, 32 45 | orig: 32, 32 46 | offset: 0, 0 47 | index: -1 48 | images1/document 49 | rotate: false 50 | xy: 70, 2 51 | size: 32, 32 52 | orig: 32, 32 53 | offset: 0, 0 54 | index: -1 55 | images1/empty 56 | rotate: false 57 | xy: 104, 2 58 | size: 32, 32 59 | orig: 32, 32 60 | offset: 0, 0 61 | index: -1 62 | 63 | textures3.png 64 | size: 128, 64 65 | format: RGB565 66 | filter: Linear, MipMap 67 | repeat: none 68 | images1/sub/binary 69 | rotate: false 70 | xy: 2, 2 71 | size: 32, 32 72 | orig: 32, 32 73 | offset: 0, 0 74 | index: -1 75 | images1/sub/image 76 | rotate: false 77 | xy: 36, 2 78 | size: 32, 32 79 | orig: 32, 32 80 | offset: 0, 0 81 | index: -1 82 | 83 | textures4.png 84 | size: 128, 64 85 | format: RGB565 86 | filter: Linear, MipMap 87 | repeat: none 88 | images1/sub/subsub/plan 89 | rotate: false 90 | xy: 2, 2 91 | size: 32, 32 92 | orig: 32, 32 93 | offset: 0, 0 94 | index: -1 95 | images1/sub/subsub/spreadsheet 96 | rotate: false 97 | xy: 36, 2 98 | size: 32, 32 99 | orig: 32, 32 100 | offset: 0, 0 101 | index: -1 102 | -------------------------------------------------------------------------------- /src/test/testData/results/packTextures/withSettingsFile.atlas: -------------------------------------------------------------------------------- 1 | 2 | pack.jpg 3 | size: 128, 64 4 | format: RGBA8888 5 | filter: Linear, MipMapLinearLinear 6 | repeat: none 7 | add 8 | rotate: false 9 | xy: 8, 8 10 | size: 32, 32 11 | orig: 32, 32 12 | offset: 0, 0 13 | index: -1 14 | back 15 | rotate: false 16 | xy: 48, 8 17 | size: 32, 32 18 | orig: 32, 32 19 | offset: 0, 0 20 | index: -1 21 | bottom 22 | rotate: false 23 | xy: 88, 8 24 | size: 32, 32 25 | orig: 32, 32 26 | offset: 0, 0 27 | index: -1 28 | -------------------------------------------------------------------------------- /src/test/testData/results/packTextures/withUsePackJson.atlas: -------------------------------------------------------------------------------- 1 | 2 | pack.png 3 | size: 128, 64 4 | format: RGBA8888 5 | filter: MipMapNearestNearest, Nearest 6 | repeat: none 7 | images2/add 8 | rotate: false 9 | xy: 2, 2 10 | size: 32, 32 11 | orig: 32, 32 12 | offset: 0, 0 13 | index: -1 14 | images2/back 15 | rotate: false 16 | xy: 36, 2 17 | size: 32, 32 18 | orig: 32, 32 19 | offset: 0, 0 20 | index: -1 21 | images2/bottom 22 | rotate: false 23 | xy: 70, 2 24 | size: 32, 32 25 | orig: 32, 32 26 | offset: 0, 0 27 | index: -1 28 | 29 | pack2.png 30 | size: 256, 64 31 | format: RGBA8888 32 | filter: Nearest, Nearest 33 | repeat: none 34 | images1/binary 35 | rotate: false 36 | xy: 2, 2 37 | size: 32, 32 38 | orig: 32, 32 39 | offset: 0, 0 40 | index: -1 41 | images1/deb 42 | rotate: false 43 | xy: 36, 2 44 | size: 32, 32 45 | orig: 32, 32 46 | offset: 0, 0 47 | index: -1 48 | images1/document 49 | rotate: false 50 | xy: 70, 2 51 | size: 32, 32 52 | orig: 32, 32 53 | offset: 0, 0 54 | index: -1 55 | images1/empty 56 | rotate: false 57 | xy: 104, 2 58 | size: 32, 32 59 | orig: 32, 32 60 | offset: 0, 0 61 | index: -1 62 | 63 | pack.jpg 64 | size: 128, 64 65 | format: RGBA8888 66 | filter: Linear, MipMapLinearLinear 67 | repeat: none 68 | images1/sub/binary 69 | rotate: false 70 | xy: 8, 8 71 | size: 32, 32 72 | orig: 32, 32 73 | offset: 0, 0 74 | index: -1 75 | images1/sub/image 76 | rotate: false 77 | xy: 48, 8 78 | size: 32, 32 79 | orig: 32, 32 80 | offset: 0, 0 81 | index: -1 82 | 83 | pack2.jpg 84 | size: 128, 64 85 | format: RGBA8888 86 | filter: Nearest, Nearest 87 | repeat: none 88 | images1/sub/subsub/plan 89 | rotate: false 90 | xy: 8, 8 91 | size: 32, 32 92 | orig: 32, 32 93 | offset: 0, 0 94 | index: -1 95 | images1/sub/subsub/spreadsheet 96 | rotate: false 97 | xy: 48, 8 98 | size: 32, 32 99 | orig: 32, 32 100 | offset: 0, 0 101 | index: -1 102 | --------------------------------------------------------------------------------