├── .gitignore
├── .idea
├── compiler.xml
├── copyright
│ └── profiles_settings.xml
├── encodings.xml
└── runConfigurations.xml
├── LICENSE.txt
├── README.md
├── build.gradle
├── gradle
└── wrapper
│ ├── gradle-wrapper.jar
│ └── gradle-wrapper.properties
├── gradlew
├── gradlew.bat
└── src
└── main
└── java
└── com
└── arcao
└── fontcreator
├── ArgumentParser.java
├── Arguments.java
├── FontConverterV3.java
└── FontCreator.java
/.gitignore:
--------------------------------------------------------------------------------
1 | # Created by https://www.gitignore.io/api/gradle,intellij,java
2 |
3 | ### Intellij ###
4 | # Covers JetBrains IDEs: IntelliJ, RubyMine, PhpStorm, AppCode, PyCharm, CLion, Android Studio and Webstorm
5 | # Reference: https://intellij-support.jetbrains.com/hc/en-us/articles/206544839
6 |
7 | # User-specific stuff:
8 | .idea/workspace.xml
9 | .idea/tasks.xml
10 | .idea/dictionaries
11 | .idea/vcs.xml
12 | .idea/jsLibraryMappings.xml
13 |
14 | # Sensitive or high-churn files:
15 | .idea/dataSources.ids
16 | .idea/dataSources.xml
17 | .idea/dataSources.local.xml
18 | .idea/sqlDataSources.xml
19 | .idea/dynamic.xml
20 | .idea/uiDesigner.xml
21 |
22 | # Gradle:
23 | .idea/gradle.xml
24 | .idea/libraries
25 |
26 | # Mongo Explorer plugin:
27 | .idea/mongoSettings.xml
28 |
29 | ## File-based project format:
30 | *.iws
31 |
32 | ## Plugin-specific files:
33 |
34 | # IntelliJ
35 | /out/
36 |
37 | # mpeltonen/sbt-idea plugin
38 | .idea_modules/
39 |
40 | # JIRA plugin
41 | atlassian-ide-plugin.xml
42 |
43 | # Crashlytics plugin (for Android Studio and IntelliJ)
44 | com_crashlytics_export_strings.xml
45 | crashlytics.properties
46 | crashlytics-build.properties
47 | fabric.properties
48 |
49 | ### Intellij Patch ###
50 | # Comment Reason: https://github.com/joeblau/gitignore.io/issues/186#issuecomment-215987721
51 |
52 | *.iml
53 | .idea/modules.xml
54 | .idea/misc.xml
55 | *.ipr
56 |
57 |
58 | ### Java ###
59 | *.class
60 |
61 | # Mobile Tools for Java (J2ME)
62 | .mtj.tmp/
63 |
64 | # Package Files #
65 | *.jar
66 | *.war
67 | *.ear
68 |
69 | # virtual machine crash logs, see http://www.java.com/en/download/help/error_hotspot.xml
70 | hs_err_pid*
71 |
72 |
73 | ### Gradle ###
74 | .gradle
75 | /build/
76 |
77 | # Ignore Gradle GUI config
78 | gradle-app.setting
79 |
80 | # Avoid ignoring Gradle wrapper jar file (.jar files are usually ignored)
81 | !gradle-wrapper.jar
82 |
83 | # Cache of project
84 | .gradletasknamecache
85 |
86 | # # Work around https://youtrack.jetbrains.com/issue/IDEA-116898
87 | # gradle/wrapper/gradle-wrapper.properties
--------------------------------------------------------------------------------
/.idea/compiler.xml:
--------------------------------------------------------------------------------
1 |
2 |
3 |
4 |
5 |
6 |
7 |
8 |
9 |
10 |
11 |
12 |
13 |
14 |
15 |
16 |
17 |
18 |
19 |
20 |
21 |
22 |
--------------------------------------------------------------------------------
/.idea/copyright/profiles_settings.xml:
--------------------------------------------------------------------------------
1 |
2 |
3 |
--------------------------------------------------------------------------------
/.idea/encodings.xml:
--------------------------------------------------------------------------------
1 |
2 |
3 |
4 |
5 |
6 |
--------------------------------------------------------------------------------
/.idea/runConfigurations.xml:
--------------------------------------------------------------------------------
1 |
2 |
3 |
4 |
11 |
12 |
--------------------------------------------------------------------------------
/LICENSE.txt:
--------------------------------------------------------------------------------
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 |
--------------------------------------------------------------------------------
/README.md:
--------------------------------------------------------------------------------
1 | # esp8266-oled-ssd1306-font-creator
2 | Font creator for the [esp8266-oled-ssd1306](https://github.com/squix78/esp8266-oled-ssd1306) library. It's generate font.h file in Font V3 format used in this library.
3 |
4 | ## Download
5 | You can download pre-build console application from [latest release page](https://github.com/arcao/esp8266-oled-ssd1306-font-creator/releases/latest). For running this application you need `JRE 1.8` (`Sun JRE` or `OpenJDK`) and newer. In `fontcreator/bin` directory are located `bat`/`bash` scripts to execute the app. For usages see bellow...
6 |
7 | ## Install from latest sources
8 | For installation you need to have installed at least `Sun JDK 1.8` or `OpenJDK 1.8`.
9 |
10 | 1. Download the source package [from this page](https://github.com/arcao/esp8266-oled-ssd1306-font-creator/archive/master.zip)
11 | 2. Unzip the archive.
12 | 3. Run `gradlew installDist` in `esp8266-oled-ssd1306-font-creator-master` directory. It should prepare distribution `zip` and `tar` files in `build/distributions` directory and also unpack the distribution archive in `build/install`.
13 | 4. Go to `build/install/fontcreator/bin` subdirectory. There are located `bat`/`bash` scripts to execute the app. For usages see bellow...
14 |
15 | ## Usage
16 | ```
17 | Font creator for the esp8266-oled-ssd1306 library
18 | Created by Arcao (http://arcao.com), based on squix78 (http://blog.squix.ch) work.
19 |
20 | Usage: fontcreator [options] [FONT]
21 |
22 | Non-option arguments:
23 | [FONT] -- system font name or path to font file to be processed
24 |
25 | Option Description
26 | ------ -----------
27 | -b, --bold use bold font variant
28 | -c, --charset font table index charset (default: iso-8859-1)
29 | -h, --help display this help and exit
30 | -i, --italic use italic font style
31 | -o, --output [File] write .h font table to file instead to StdOut
32 | -s, --size font size
33 | -y, --yoffset [Integer] shifts characters upwards (pixels) (default: 0)
34 | ```
35 |
36 | ## License
37 | ```
38 | Copyright 2016 Martin "Arcao" Sloup
39 |
40 | Licensed under the Apache License, Version 2.0 (the "License");
41 | you may not use this file except in compliance with the License.
42 | You may obtain a copy of the License at
43 |
44 | http://www.apache.org/licenses/LICENSE-2.0
45 |
46 | Unless required by applicable law or agreed to in writing, software
47 | distributed under the License is distributed on an "AS IS" BASIS,
48 | WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
49 | See the License for the specific language governing permissions and
50 | limitations under the License.
51 | ```
52 |
--------------------------------------------------------------------------------
/build.gradle:
--------------------------------------------------------------------------------
1 | apply plugin: 'application'
2 |
3 | applicationName = 'fontcreator'
4 | archivesBaseName = applicationName
5 | version = '1.0'
6 | mainClassName = 'com.arcao.fontcreator.FontCreator'
7 | sourceCompatibility = 1.8
8 |
9 | //Get dependencies from jcenter
10 | repositories {
11 | jcenter()
12 | }
13 |
14 | configurations {
15 | provided
16 | compile.extendsFrom provided
17 | }
18 |
19 | //Project dependencies
20 | dependencies {
21 | compile 'net.sf.jopt-simple:jopt-simple:5.0.2'
22 | }
23 |
24 | jar {
25 | manifest {
26 | attributes "Implementation-Title": applicationName
27 | attributes "Implementation-Version": project.version
28 | attributes 'Main-Class': mainClassName
29 | }
30 | }
31 |
32 | distZip {
33 | version = null
34 | }
35 |
36 | distTar {
37 | version = null
38 | }
39 |
40 |
--------------------------------------------------------------------------------
/gradle/wrapper/gradle-wrapper.jar:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/arcao/esp8266-oled-ssd1306-font-creator/23591bdf9dde1584dc2039637b005631c6356a7e/gradle/wrapper/gradle-wrapper.jar
--------------------------------------------------------------------------------
/gradle/wrapper/gradle-wrapper.properties:
--------------------------------------------------------------------------------
1 | #Tue Sep 13 15:42:13 CEST 2016
2 | distributionBase=GRADLE_USER_HOME
3 | distributionPath=wrapper/dists
4 | zipStoreBase=GRADLE_USER_HOME
5 | zipStorePath=wrapper/dists
6 | distributionUrl=https\://services.gradle.org/distributions/gradle-2.14.1-bin.zip
7 |
--------------------------------------------------------------------------------
/gradlew:
--------------------------------------------------------------------------------
1 | #!/usr/bin/env bash
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 | # Split up the JVM_OPTS And GRADLE_OPTS values into an array, following the shell quoting and substitution rules
158 | function splitJvmOpts() {
159 | JVM_OPTS=("$@")
160 | }
161 | eval splitJvmOpts $DEFAULT_JVM_OPTS $JAVA_OPTS $GRADLE_OPTS
162 | JVM_OPTS[${#JVM_OPTS[*]}]="-Dorg.gradle.appname=$APP_BASE_NAME"
163 |
164 | exec "$JAVACMD" "${JVM_OPTS[@]}" -classpath "$CLASSPATH" org.gradle.wrapper.GradleWrapperMain "$@"
165 |
--------------------------------------------------------------------------------
/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 | if "%@eval[2+2]" == "4" goto 4NT_args
53 |
54 | :win9xME_args
55 | @rem Slurp the command line arguments.
56 | set CMD_LINE_ARGS=
57 | set _SKIP=2
58 |
59 | :win9xME_args_slurp
60 | if "x%~1" == "x" goto execute
61 |
62 | set CMD_LINE_ARGS=%*
63 | goto execute
64 |
65 | :4NT_args
66 | @rem Get arguments from the 4NT Shell from JP Software
67 | set CMD_LINE_ARGS=%$
68 |
69 | :execute
70 | @rem Setup the command line
71 |
72 | set CLASSPATH=%APP_HOME%\gradle\wrapper\gradle-wrapper.jar
73 |
74 | @rem Execute Gradle
75 | "%JAVA_EXE%" %DEFAULT_JVM_OPTS% %JAVA_OPTS% %GRADLE_OPTS% "-Dorg.gradle.appname=%APP_BASE_NAME%" -classpath "%CLASSPATH%" org.gradle.wrapper.GradleWrapperMain %CMD_LINE_ARGS%
76 |
77 | :end
78 | @rem End local scope for the variables with windows NT shell
79 | if "%ERRORLEVEL%"=="0" goto mainEnd
80 |
81 | :fail
82 | rem Set variable GRADLE_EXIT_CONSOLE if you need the _script_ return code instead of
83 | rem the _cmd.exe /c_ return code!
84 | if not "" == "%GRADLE_EXIT_CONSOLE%" exit 1
85 | exit /b 1
86 |
87 | :mainEnd
88 | if "%OS%"=="Windows_NT" endlocal
89 |
90 | :omega
91 |
--------------------------------------------------------------------------------
/src/main/java/com/arcao/fontcreator/ArgumentParser.java:
--------------------------------------------------------------------------------
1 | package com.arcao.fontcreator;
2 |
3 | import java.io.File;
4 | import java.io.IOException;
5 |
6 | import joptsimple.OptionException;
7 | import joptsimple.OptionParser;
8 | import joptsimple.OptionSet;
9 | import joptsimple.OptionSpec;
10 |
11 | import static java.util.Arrays.asList;
12 |
13 | public class ArgumentParser {
14 | private final OptionParser parser = new OptionParser();
15 |
16 | private final OptionSpec help;
17 | private final OptionSpec size;
18 | private final OptionSpec bold;
19 | private final OptionSpec italic;
20 | private final OptionSpec charset;
21 | private final OptionSpec outputFile;
22 | private final OptionSpec font;
23 | private final OptionSpec yoffset;
24 |
25 | public ArgumentParser() {
26 | help = parser.acceptsAll(asList("h", "help"), "display this help and exit").forHelp();
27 | size = parser.acceptsAll(asList("s", "size"), "font size").withRequiredArg().ofType(Integer.class);
28 | yoffset = parser.acceptsAll(asList("y", "yoffset"), "shifts characters upwards (pixels)").withOptionalArg().ofType(Integer.class).defaultsTo(0);
29 | bold = parser.acceptsAll(asList("b", "bold"), "use bold font variant");
30 | italic = parser.acceptsAll(asList("i", "italic"), "use italic font style");
31 | charset = parser.acceptsAll(asList("c", "charset"), "font table index charset").withOptionalArg().defaultsTo("iso-8859-1").ofType(String.class);
32 | outputFile = parser.acceptsAll(asList("o", "output"), "write .h font table to file instead to StdOut").withOptionalArg().ofType(File.class);
33 | font = parser.nonOptions("system font name or path to font file to be processed").describedAs("FONT").ofType(String.class);
34 | }
35 |
36 | public Arguments parse(String args[]) throws OptionException {
37 | OptionSet options = parser.parse(args);
38 |
39 | return new Arguments() {
40 | @Override
41 | public boolean help() {
42 | return options.has(help);
43 | }
44 |
45 | @Override
46 | public int size() {
47 | return options.valueOf(size);
48 | }
49 |
50 | @Override
51 | public int yoffset() {
52 | return options.valueOf(yoffset);
53 | }
54 |
55 | @Override
56 | public boolean bold() {
57 | return options.has(bold);
58 | }
59 |
60 | @Override
61 | public boolean italic() {
62 | return options.has(italic);
63 | }
64 |
65 | @Override
66 | public String charset() {
67 | return options.valueOf(charset);
68 | }
69 |
70 | @Override
71 | public File outputFile() {
72 | return options.valueOf(outputFile);
73 | }
74 |
75 | @Override
76 | public String font() {
77 | return options.valueOf(font);
78 | }
79 | };
80 | }
81 |
82 | public void printHelp() {
83 | try {
84 | parser.printHelpOn(System.out);
85 | } catch (IOException e) {
86 | // ignore
87 | }
88 | }
89 | }
90 |
--------------------------------------------------------------------------------
/src/main/java/com/arcao/fontcreator/Arguments.java:
--------------------------------------------------------------------------------
1 | package com.arcao.fontcreator;
2 |
3 |
4 | import java.io.File;
5 |
6 | interface Arguments {
7 | boolean help();
8 |
9 | int size();
10 |
11 | boolean bold();
12 |
13 | boolean italic();
14 |
15 | String charset();
16 |
17 | File outputFile();
18 |
19 | String font();
20 |
21 | int yoffset();
22 |
23 | }
24 |
--------------------------------------------------------------------------------
/src/main/java/com/arcao/fontcreator/FontConverterV3.java:
--------------------------------------------------------------------------------
1 | /*
2 | Based on squix78 implementation (MIT License) from:
3 | https://github.com/squix78/esp8266-oled-ssd1306-font-converter/blob/81bf43601496b2e607563d374a03b8b385e31940/src/main/java/ch/squix/esp8266/fontconverter/rest/FontConverterV3.java
4 |
5 | Some parts was changed or improved for application usage by Arcao.
6 | */
7 | package com.arcao.fontcreator;
8 |
9 | import java.awt.Color;
10 | import java.awt.Font;
11 | import java.awt.FontMetrics;
12 | import java.awt.Graphics2D;
13 | import java.awt.RenderingHints;
14 | import java.awt.image.BufferedImage;
15 | import java.nio.charset.Charset;
16 | import java.util.ArrayList;
17 | import java.util.Arrays;
18 | import java.util.List;
19 |
20 | public class FontConverterV3 {
21 |
22 | private static final int END_CHAR = 256;
23 | private static final int START_CHAR = 32;
24 |
25 | private Graphics2D g;
26 | private FontMetrics fontMetrics;
27 | private BufferedImage image;
28 | private Charset charset;
29 |
30 | private int yoffset;
31 |
32 |
33 | public FontConverterV3(Font font) {
34 | image = new BufferedImage(100, 100, BufferedImage.TYPE_INT_RGB);
35 | g = (Graphics2D) image.getGraphics();
36 | g.setRenderingHint(RenderingHints.KEY_TEXT_ANTIALIASING,
37 | RenderingHints.VALUE_TEXT_ANTIALIAS_OFF);
38 | g.setFont(font);
39 | fontMetrics = g.getFontMetrics();
40 | }
41 |
42 | public FontConverterV3(Font font, Charset charset) {
43 | this(font);
44 | this.charset = charset;
45 | }
46 |
47 | public void printFontData(StringBuilder builder, int yoffset) {
48 | this.yoffset=yoffset;
49 | List letterList = produceLetterDataList();
50 |
51 | String fontName = g.getFont().getFontName().replaceAll("[\\s\\-\\.]", "_") + "_"
52 | + getFontStyle() + "_" + g.getFont().getSize();
53 | builder.append("// Font table version: 3\n");
54 | builder.append("// Created by FontCreator (https://github.com/arcao/esp8266-oled-ssd1306-font-creator.\n");
55 | builder.append("// In case of problems make sure that you are using the font file with the correct version!\n");
56 | builder.append(String.format("const char %s[] PROGMEM = {\n", fontName));
57 | writeHexValue(builder, "Width", getMaxCharWidth());
58 | writeHexValue(builder, "Height", getMaxCharHeight());
59 | writeHexValue(builder, "First Char", START_CHAR);
60 | writeHexValue(builder, "Numbers of Chars", END_CHAR - START_CHAR);
61 | builder.append("\n");
62 | builder.append("\t// Jump Table:\n");
63 |
64 | int lastJumpPoint = 0;
65 | for (LetterData letter : letterList) {
66 | int letterWidth = letter.getWidth();
67 | int size = letter.getByteSize();
68 | String code = "" + ((int) letter.getCode()) + "=" + letter.getCode();
69 | if (letter.isVisible()) {
70 | writeJumpTable(builder, code, lastJumpPoint, size, letterWidth);
71 | lastJumpPoint += size;
72 | } else {
73 | writeJumpTable(builder, code, 0xFFFF, size, letterWidth);
74 | }
75 | }
76 |
77 | builder.append("\n");
78 | builder.append("\t// Font Data:\n");
79 |
80 | letterList.stream().filter(LetterData::isVisible).forEach(letter -> {
81 | builder.append("\t");
82 | builder.append(letter.toString());
83 | if ((int) letter.getCode() != END_CHAR - 1) {
84 | builder.append(",");
85 | }
86 | builder.append(String.format("\t// %d\n", (int) letter.getCode()));
87 | });
88 |
89 | builder.append("};\n");
90 | }
91 |
92 | private List produceLetterDataList() {
93 | List letterDataList = new ArrayList<>(END_CHAR - START_CHAR);
94 | for (int i = START_CHAR; i < END_CHAR; i++) {
95 | char ch;
96 | if (charset == null) {
97 | ch = (char) i;
98 | } else {
99 | ch = new String(new byte[]{(byte) (i & 0xFF)}, charset).charAt(0);
100 | }
101 |
102 | letterDataList.add(createLetterData(ch));
103 | }
104 | return letterDataList;
105 | }
106 |
107 | private LetterData createLetterData(char code) {
108 | BufferedImage letterImage = drawLetter(code);
109 |
110 | int width = fontMetrics.charWidth(code);
111 | int height = fontMetrics.getHeight();
112 |
113 | int arrayHeight = (int) Math.ceil((double) height / 8.0);
114 | int arraySize = width * arrayHeight;
115 |
116 | int character[] = new int[arraySize];
117 |
118 | boolean isVisibleChar = false;
119 |
120 | if (width > 0) {
121 | for (int i = 0; i < arraySize; i++) {
122 | int xImg = (i / arrayHeight);
123 | int yImg = (i % arrayHeight) * 8;
124 | int currentByte = 0;
125 | for (int b = 0; b < 8; b++) {
126 | if (yImg + b <= height) {
127 | if (letterImage.getRGB(xImg, yImg + b) == Color.BLACK.getRGB()) {
128 | isVisibleChar = true;
129 | currentByte = currentByte | (1 << b);
130 | } else {
131 | currentByte = currentByte & ~(1 << b);
132 | }
133 | }
134 | }
135 |
136 | character[i] = (byte) currentByte;
137 | }
138 | }
139 |
140 | // Remove rightmost zeros to save bytes
141 | int lastByteNotNull = -1;
142 | for (int i = 0; i < character.length; i++) {
143 | if (character[i] != 0)
144 | lastByteNotNull = i;
145 | }
146 |
147 | character = Arrays.copyOf(character, lastByteNotNull + 1);
148 |
149 | return new LetterData(code, character, width, isVisibleChar);
150 | }
151 |
152 | private BufferedImage drawLetter(char code) {
153 | g.setColor(Color.WHITE);
154 | g.fillRect(0, 0, 450, 250);
155 | g.setColor(Color.BLACK);
156 | g.drawString(String.valueOf(code), 0, fontMetrics.getAscent() + fontMetrics.getLeading() - yoffset);
157 | return image;
158 | }
159 |
160 |
161 | private String getFontStyle() {
162 | Font font = g.getFont();
163 | if (font.isPlain()) {
164 | return "Plain";
165 | } else if (font.isItalic() && font.isBold()) {
166 | return "ItalicBold";
167 | } else if (font.isBold()) {
168 | return "Bold";
169 | } else if (font.isItalic()) {
170 | return "Italic";
171 | }
172 | return "";
173 | }
174 |
175 | private void writeJumpTable(StringBuilder builder, String label, int jump, int size, int width) {
176 | builder.append(String.format("\t0x%02X, ", (jump >> 8) & 0xFF)); // MSB
177 | builder.append(String.format("0x%02X, ", jump & 0xFF)); // LSB
178 | builder.append(String.format("0x%02X, ", size)); // byteSize
179 | builder.append(String.format("0x%02X, ", width)); // WIDTH
180 | builder.append(String.format(" // %s:%d\n", label, jump));
181 | }
182 |
183 | private void writeHexValue(StringBuilder builder, String label, int value) {
184 | builder.append(String.format("\t0x%02X, // %s: %d", value, label, value));
185 | builder.append("\n");
186 | }
187 |
188 | private int getMaxCharWidth() {
189 | int maxWidth = 0;
190 | for (int i = START_CHAR; i < END_CHAR; i++) {
191 | maxWidth = Math.max(maxWidth, fontMetrics.charWidth((char) i));
192 | }
193 | return maxWidth;
194 | }
195 |
196 | private int getMaxCharHeight() {
197 | return fontMetrics.getMaxAscent() + fontMetrics.getMaxDescent() + fontMetrics.getLeading();
198 | }
199 |
200 | private class LetterData {
201 |
202 | private char code;
203 | private int[] bytes;
204 | private int width;
205 | private boolean visible;
206 |
207 | LetterData(char code, int[] bytes, int width, boolean visible) {
208 | this.code = code;
209 | this.bytes = bytes;
210 | this.width = width;
211 | this.visible = visible;
212 | }
213 |
214 | char getCode() {
215 | return code;
216 | }
217 |
218 | int getWidth() {
219 | return width;
220 | }
221 |
222 | boolean isVisible() {
223 | return visible;
224 | }
225 |
226 | int getByteSize() {
227 | return bytes.length;
228 | }
229 |
230 | public String toString() {
231 | if (bytes.length <= 0 || !visible) {
232 | return "";
233 | }
234 | StringBuilder builder = new StringBuilder();
235 | for (int i = 0; i < bytes.length; i++) {
236 | if (i > 0) {
237 | builder.append(",");
238 | }
239 | builder.append(String.format("0x%02X", (byte) bytes[i]));
240 | }
241 | return builder.toString();
242 |
243 | }
244 | }
245 |
246 | }
--------------------------------------------------------------------------------
/src/main/java/com/arcao/fontcreator/FontCreator.java:
--------------------------------------------------------------------------------
1 | package com.arcao.fontcreator;
2 |
3 | import java.awt.Font;
4 | import java.io.File;
5 | import java.io.FileOutputStream;
6 | import java.io.PrintStream;
7 | import java.nio.charset.Charset;
8 |
9 | import joptsimple.OptionException;
10 |
11 | public class FontCreator {
12 | private static final ArgumentParser parser = new ArgumentParser();
13 |
14 | private static void showHelp() {
15 | System.out.println("Font creator for the esp8266-oled-ssd1306 library");
16 | System.out.println("Created by Arcao (http://arcao.com), based on squix78 (http://blog.squix.ch) work.");
17 | System.out.println("");
18 | System.out.print("Usage: fontcreator [options] [FONT]");
19 | System.out.println("");
20 | parser.printHelp();
21 | }
22 |
23 | public static void main(String args[]) {
24 | if (args == null || args.length == 0) {
25 | showHelp();
26 | return;
27 | }
28 |
29 | Arguments arguments;
30 | try {
31 | arguments = parser.parse(args);
32 | } catch (OptionException e) {
33 | System.err.println("ERROR: " + e.getMessage());
34 | System.err.println();
35 | showHelp();
36 | return;
37 | }
38 |
39 | if (arguments.help()) {
40 | showHelp();
41 | return;
42 | }
43 |
44 | try {
45 | int fontStyle = Font.PLAIN;
46 | if (arguments.bold())
47 | fontStyle |= Font.BOLD;
48 | if (arguments.italic())
49 | fontStyle |= Font.ITALIC;
50 |
51 | Font font;
52 | File fontFile = new File(arguments.font());
53 | if (fontFile.exists()) {
54 | font = Font.createFont(Font.TRUETYPE_FONT, fontFile).deriveFont(fontStyle, arguments.size());
55 | } else {
56 | font = new Font(arguments.font(), fontStyle, arguments.size());
57 | }
58 |
59 | Charset charset = Charset.forName("iso-8859-1");
60 | if (arguments.charset() != null)
61 | charset = Charset.forName(arguments.charset());
62 |
63 | FontConverterV3 fontConverter = new FontConverterV3(font, charset);
64 |
65 | StringBuilder builder = new StringBuilder();
66 | fontConverter.printFontData(builder, arguments.yoffset());
67 |
68 | PrintStream out = System.out;
69 | if (arguments.outputFile() != null) {
70 | out = new PrintStream(new FileOutputStream(arguments.outputFile()), true, "utf-8");
71 | }
72 |
73 | out.print(builder.toString());
74 | out.close();
75 | } catch (Throwable t) {
76 | t.printStackTrace();
77 | }
78 | }
79 | }
80 |
--------------------------------------------------------------------------------