9 Commits
v1.0 ... v1.1

Author SHA1 Message Date
Song Minjae
1689e39f6f demo v1.1 Latin ExtB 2017-02-20 23:24:02 +09:00
Song Minjae
ccc7be93f2 adjustment on hangul choseong ssangtikeut 2017-02-20 23:08:46 +09:00
Song Minjae
d603de9c69 slight adjustments 2017-02-20 22:41:55 +09:00
Song Minjae
f05c39b687 added missing segment of code 2017-02-20 22:41:40 +09:00
Song Minjae
98ee3c97f8 new spritesheet latin ext-b 2017-02-20 20:30:29 +09:00
Song Minjae
db7c41e12a ext-a and readme update 2017-02-20 19:49:32 +09:00
Minjae Song
e75c81c071 Update README.md 2017-02-17 20:42:22 +09:00
Minjae Song
9f8767f2b8 Update README.md 2017-02-17 14:32:55 +09:00
Minjae Song
3fbc36a3e4 Update LICENSE.md 2017-02-17 04:36:48 +09:00
20 changed files with 1002 additions and 191 deletions

View File

@@ -20,5 +20,6 @@ LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE
SOFTWARE. SOFTWARE.
====
WenQuanYi font is distributed under GNU GPL Version 2. See their [license document here](http://wenq.org/wqy2/index.cgi?GPL) WenQuanYi font is distributed under GNU GPL Version 2. See their [license document here](http://wenq.org/wqy2/index.cgi?GPL)

View File

@@ -4,7 +4,9 @@
![Cyrillic sample Russian, Bulgarian, Serbian](https://github.com/minjaesong/Terrarum-sans-bitmap/blob/master/terrarum_sans_cyrillic_2.png) ![Cyrillic sample Russian, Bulgarian, Serbian](https://github.com/minjaesong/Terrarum-sans-bitmap/blob/master/terrarum_sans_cyrillic_2.png)
This font is a bitmap font used in my game project, Terrarum (hence the name). It Supports ExtA, Romanian (subset of ExtB), Cyrillic (Russian, Bulgarian, Serbian), Greek, Chinese, Japanese and Korean. **Font demo** — head to the **Release** tab
This font is a bitmap font used in my game project, Terrarum (hence the name). The font supports more than 90 % of european languages, as well as Chinese, Japanese and Korean. More technical side, it supports Latin-1 Supplement, Latin Ext-A, Latin Ext-B, Cyrillic (Russian, Bulgarian, Serbian), Greek, Chinese (limited to Unicode BMP), Japanese, Korean (all 11 172 possible syllables).
The code for the fonts are meant to be used with Slick2d (extends ```Font``` class). If you are not using the framework, please refer to the __Font metrics__ section to implement the font metrics correctly on your system. The code for the fonts are meant to be used with Slick2d (extends ```Font``` class). If you are not using the framework, please refer to the __Font metrics__ section to implement the font metrics correctly on your system.
@@ -13,20 +15,20 @@ The issue page is open. If you have some issues to submit, or have a question, p
## Contribution guidelines ## Contribution guidelines
You can contribute to the font by fixing wrong glyphs, suggesting better ones, extending character set (like Latin Extended B), or code for other game frameworks such as LibGDX. Please leave pull request for that. You can contribute to the font by fixing wrong glyphs, suggesting better ones, extending character set (like Georgian and Thai), or code for other game frameworks such as LibGDX. Please leave pull request for that.
Font images are stored in ```assets/graphics/fonts``` directory. Image format must be TGA with Alpha — no PNG. If someone needs PNG, they can batch-convert the font using utils like ImageMagick. Font Spritesheets are stored in ```assets/graphics/fonts``` directory. Image format must be TGA with Alpha — no PNG. If someone needs PNG, they can batch-convert the font using utils like ImageMagick.
## Using on Slick2d ## Using on Slick2d
On your code (Kotlin): On your code (Kotlin):
class YourGame { class YourGame : BasicGame("YourGameName") {
lateinit var fontGame: Font lateinit var fontGame: Font
override fun initStatesList(gc: GameContainer) { override fun init(gc: GameContainer) {
fontGame = GameFontImpl() fontGame = GameFontImpl()
... ...
} }
@@ -39,16 +41,16 @@ On your code (Kotlin):
On your code (Java): On your code (Java):
class YourGame { class YourGame extends BasicGame {
Font fontGame; Font fontGame;
void initStatesList(GameContainer gc) { @Override void init(GameContainer gc) {
fontGame = new GameFontImpl(); fontGame = new GameFontImpl();
... ...
} }
void render(GameContainer gc, Graphics g) { @Override void render(GameContainer gc, Graphics g) {
g.setFont(fontGame); g.setFont(fontGame);
g.drawString(...); g.drawString(...);
} }
@@ -56,11 +58,11 @@ On your code (Java):
## Font metrics ## Font metrics
The font expects both variable widths and fixed width to be supported. Any images with ```_variable``` means it expects variable widths. Anything else expects fixed width. ```romana_narrow``` has width of 6 (no, not 5), ```romana_wide``` has width of 9, ```cjkpunct``` has width of 10, ```kana``` has width of 12, ```hangul_johab``` has width of 11, ```wenquanyi``` has width of 16. Although the font is basically a Spritesheet, some of the sheet expects variable widths to be supported. Any sheets with ```_variable``` means it expects variable widths. Anything else expects fixed width (regular Spritesheet behaviour). ```cjkpunct``` has width of 10, ```kana``` has width of 12, ```hangul_johab``` has width of 11, ```wenquanyi``` has width of 16.
### Parsing glyph widths for variable font sheets ### Parsing glyph widths for variable font sheets
Width is encoded in binary number, on pixels. On the font image, every glyph has vertical dots on their right side (to be exact, every (16k - 1)th pixel on x axis). From top to bottom, each dot represents 1, 2, 4 and 8. For example, ASCII glyph 'C' has width of 9, 'W' has width of 11, " (double quote) has width of 6. Width is encoded in binary number, on pixels. On the font spritesheet, every glyph has vertical dots on their right side (to be exact, every (16k - 1)th pixel on x axis). From top to bottom, each dot represents 1, 2, 4 and 8. For example, ASCII glyph 'C' has width of 9, 'W' has width of 11, " (double quote) has width of 6.
### Implementing the Korean writing system ### Implementing the Korean writing system
@@ -68,6 +70,10 @@ On this font, Hangul letters are printed by assemblying two or three letter piec
This is a Kotlin-like pseudocode for assembling the glyph: This is a Kotlin-like pseudocode for assembling the glyph:
function getHanChosung(hanIndex: Int) = hanIndex / (21 * 28)
function getHanJungseong(hanIndex: Int) = hanIndex / 28 % 21
function getHanJongseong(hanIndex: Int) = hanIndex % 28
jungseongWide = arrayOf(8, 12, 13, 17, 18, 21) jungseongWide = arrayOf(8, 12, 13, 17, 18, 21)
jungseongComplex = arrayOf(9, 10, 11, 14, 15, 16, 22) jungseongComplex = arrayOf(9, 10, 11, 14, 15, 16, 22)

View File

@@ -56,7 +56,9 @@ open class GameFontBase : Font {
private fun isHangul(c: Char) = c.toInt() >= 0xAC00 && c.toInt() < 0xD7A4 private fun isHangul(c: Char) = c.toInt() >= 0xAC00 && c.toInt() < 0xD7A4
private fun isAscii(c: Char) = c.toInt() >= 0x20 && c.toInt() <= 0xFF private fun isAscii(c: Char) = c.toInt() >= 0x20 && c.toInt() <= 0xFF
private fun isRunic(c: Char) = runicList.contains(c)
private fun isExtA(c: Char) = c.toInt() >= 0x100 && c.toInt() < 0x180 private fun isExtA(c: Char) = c.toInt() >= 0x100 && c.toInt() < 0x180
private fun isExtB(c: Char) = c.toInt() >= 0x180 && c.toInt() < 0x250
private fun isKana(c: Char) = c.toInt() >= 0x3040 && c.toInt() < 0x3100 private fun isKana(c: Char) = c.toInt() >= 0x3040 && c.toInt() < 0x3100
private fun isCJKPunct(c: Char) = c.toInt() >= 0x3000 && c.toInt() < 0x3040 private fun isCJKPunct(c: Char) = c.toInt() >= 0x3000 && c.toInt() < 0x3040
private fun isUniHan(c: Char) = c.toInt() >= 0x3400 && c.toInt() < 0xA000 private fun isUniHan(c: Char) = c.toInt() >= 0x3400 && c.toInt() < 0xA000
@@ -66,14 +68,18 @@ open class GameFontBase : Font {
private fun isWenQuanYi1(c: Char) = c.toInt() >= 0x33F3 && c.toInt() <= 0x69FC private fun isWenQuanYi1(c: Char) = c.toInt() >= 0x33F3 && c.toInt() <= 0x69FC
private fun isWenQuanYi2(c: Char) = c.toInt() >= 0x69FD && c.toInt() <= 0x9FDC private fun isWenQuanYi2(c: Char) = c.toInt() >= 0x69FD && c.toInt() <= 0x9FDC
private fun isGreek(c: Char) = c.toInt() >= 0x370 && c.toInt() <= 0x3CE private fun isGreek(c: Char) = c.toInt() >= 0x370 && c.toInt() <= 0x3CE
private fun isRomanian(c: Char) = c.toInt() >= 0x218 && c.toInt() <= 0x21A
private fun isRomanianNarrow(c: Char) = c.toInt() == 0x21B
private fun extAindexX(c: Char) = (c.toInt() - 0x100) % 16 private fun extAindexX(c: Char) = (c.toInt() - 0x100) % 16
private fun extAindexY(c: Char) = (c.toInt() - 0x100) / 16 private fun extAindexY(c: Char) = (c.toInt() - 0x100) / 16
private fun extBindexX(c: Char) = (c.toInt() - 0x180) % 16
private fun extBindexY(c: Char) = (c.toInt() - 0x180) / 16
private fun runicIndexX(c: Char) = runicList.indexOf(c) % 16
private fun runicIndexY(c: Char) = runicList.indexOf(c) / 16
private fun kanaIndexX(c: Char) = (c.toInt() - 0x3040) % 16 private fun kanaIndexX(c: Char) = (c.toInt() - 0x3040) % 16
private fun kanaIndexY(c: Char) = (c.toInt() - 0x3040) / 16 private fun kanaIndexY(c: Char) = (c.toInt() - 0x3040) / 16
@@ -100,19 +106,6 @@ open class GameFontBase : Font {
private fun greekIndexX(c: Char) = (c.toInt() - 0x370) % 16 private fun greekIndexX(c: Char) = (c.toInt() - 0x370) % 16
private fun greekIndexY(c: Char) = (c.toInt() - 0x370) / 16 private fun greekIndexY(c: Char) = (c.toInt() - 0x370) / 16
private fun romanianIndexX(c: Char) = c.toInt() - 0x218
private fun romanianIndexY(c: Char) = 0
private fun thaiIndexX(c: Char) = (c.toInt() - 0xE00) % 16
private fun thaiIndexY(c: Char) = (c.toInt() - 0xE00) / 16
private fun thaiNarrowIndexX(c: Char) = 3
private fun thaiNarrowIndexY(c: Char) = 0
private val narrowWidthSheets = arrayOf(
SHEET_EXTB_ROMANIAN_NARROW
)
private val unihanWidthSheets = arrayOf( private val unihanWidthSheets = arrayOf(
SHEET_UNIHAN, SHEET_UNIHAN,
SHEET_FW_UNI, SHEET_FW_UNI,
@@ -126,7 +119,8 @@ open class GameFontBase : Font {
SHEET_ASCII_VARW, SHEET_ASCII_VARW,
SHEET_CYRILIC_VARW, SHEET_CYRILIC_VARW,
SHEET_EXTA_VARW, SHEET_EXTA_VARW,
SHEET_GREEK_VARW SHEET_GREEK_VARW,
SHEET_EXTB_VARW
) )
@@ -151,8 +145,6 @@ open class GameFontBase : Font {
} }
else if (zeroWidthSheets.contains(ctype)) else if (zeroWidthSheets.contains(ctype))
len += 0 len += 0
else if (narrowWidthSheets.contains(ctype))
len += W_LATIN_NARROW
else if (ctype == SHEET_CJK_PUNCT) else if (ctype == SHEET_CJK_PUNCT)
len += W_ASIAN_PUNCT len += W_ASIAN_PUNCT
else if (ctype == SHEET_HANGUL) else if (ctype == SHEET_HANGUL)
@@ -188,6 +180,11 @@ open class GameFontBase : Font {
for (i in 0..s.length - 1) { for (i in 0..s.length - 1) {
val ch = s[i] val ch = s[i]
if (ch.isColourCode()) {
thisCol = colourKey[ch]!!
continue
}
if (isHangul(ch)) { if (isHangul(ch)) {
val hIndex = ch.toInt() - 0xAC00 val hIndex = ch.toInt() - 0xAC00
@@ -246,6 +243,11 @@ open class GameFontBase : Font {
for (i in 0..s.length - 1) { for (i in 0..s.length - 1) {
val ch = s[i] val ch = s[i]
if (ch.isColourCode()) {
thisCol = colourKey[ch]!!
continue
}
if (isWenQuanYi1(ch)) { if (isWenQuanYi1(ch)) {
val glyphW = getWidth("" + ch) val glyphW = getWidth("" + ch)
wenQuanYi_1.getSubImage(wenQuanYiIndexX(ch), wenQuanYi1IndexY(ch)).drawWithShadow( wenQuanYi_1.getSubImage(wenQuanYiIndexX(ch), wenQuanYi1IndexY(ch)).drawWithShadow(
@@ -263,6 +265,11 @@ open class GameFontBase : Font {
for (i in 0..s.length - 1) { for (i in 0..s.length - 1) {
val ch = s[i] val ch = s[i]
if (ch.isColourCode()) {
thisCol = colourKey[ch]!!
continue
}
if (isWenQuanYi2(ch)) { if (isWenQuanYi2(ch)) {
val glyphW = getWidth("" + ch) val glyphW = getWidth("" + ch)
wenQuanYi_2.getSubImage(wenQuanYiIndexX(ch), wenQuanYi2IndexY(ch)).drawWithShadow( wenQuanYi_2.getSubImage(wenQuanYiIndexX(ch), wenQuanYi2IndexY(ch)).drawWithShadow(
@@ -280,6 +287,11 @@ open class GameFontBase : Font {
for (i in 0..s.length - 1) { for (i in 0..s.length - 1) {
val ch = s[i] val ch = s[i]
if (ch.isColourCode()) {
thisCol = colourKey[ch]!!
continue
}
if (!isHangul(ch) && !isUniHan(ch)) { if (!isHangul(ch) && !isUniHan(ch)) {
// if not init, endUse first // if not init, endUse first
@@ -296,6 +308,10 @@ open class GameFontBase : Font {
sheetX = extAindexX(ch) sheetX = extAindexX(ch)
sheetY = extAindexY(ch) sheetY = extAindexY(ch)
} }
SHEET_EXTB_VARW -> {
sheetX = extBindexX(ch)
sheetY = extBindexY(ch)
}
SHEET_KANA -> { SHEET_KANA -> {
sheetX = kanaIndexX(ch) sheetX = kanaIndexX(ch)
sheetY = kanaIndexY(ch) sheetY = kanaIndexY(ch)
@@ -320,14 +336,6 @@ open class GameFontBase : Font {
sheetX = greekIndexX(ch) sheetX = greekIndexX(ch)
sheetY = greekIndexY(ch) sheetY = greekIndexY(ch)
} }
SHEET_EXTB_ROMANIAN_WIDE -> {
sheetX = romanianIndexX(ch)
sheetY = romanianIndexY(ch)
}
SHEET_EXTB_ROMANIAN_NARROW -> {
sheetX = 0
sheetY = 0
}
else -> { else -> {
sheetX = ch.toInt() % 16 sheetX = ch.toInt() % 16
sheetY = ch.toInt() / 16 sheetY = ch.toInt() / 16
@@ -365,10 +373,7 @@ open class GameFontBase : Font {
} }
private fun getSheetType(c: Char): Int { private fun getSheetType(c: Char): Int {
// EFs if (isHangul(c))
if (isRomanianNarrow(c))
return SHEET_EXTB_ROMANIAN_NARROW
else if (isHangul(c))
return SHEET_HANGUL return SHEET_HANGUL
else if (isKana(c)) else if (isKana(c))
return SHEET_KANA return SHEET_KANA
@@ -378,6 +383,8 @@ open class GameFontBase : Font {
return SHEET_ASCII_VARW return SHEET_ASCII_VARW
else if (isExtA(c)) else if (isExtA(c))
return SHEET_EXTA_VARW return SHEET_EXTA_VARW
else if (isExtB(c))
return SHEET_EXTB_VARW
else if (isCyrilic(c)) else if (isCyrilic(c))
return SHEET_CYRILIC_VARW return SHEET_CYRILIC_VARW
else if (isUniPunct(c)) else if (isUniPunct(c))
@@ -388,8 +395,8 @@ open class GameFontBase : Font {
return SHEET_FW_UNI return SHEET_FW_UNI
else if (isGreek(c)) else if (isGreek(c))
return SHEET_GREEK_VARW return SHEET_GREEK_VARW
else if (isRomanian(c)) else if (c.isColourCode())
return SHEET_EXTB_ROMANIAN_WIDE return SHEET_COLOURCODE
else else
return SHEET_UNKNOWN// fixed width punctuations return SHEET_UNKNOWN// fixed width punctuations
// fixed width // fixed width
@@ -418,6 +425,8 @@ open class GameFontBase : Font {
drawString(x + xoff, y, printedBody, color) drawString(x + xoff, y, printedBody, color)
} }
fun Char.isColourCode() = colourKey.containsKey(this)
fun buildWidthTable(sheet: SpriteSheet, codeOffset: Int, codeRange: IntRange, rows: Int = 16) { fun buildWidthTable(sheet: SpriteSheet, codeOffset: Int, codeRange: IntRange, rows: Int = 16) {
fun Byte.toUint() = java.lang.Byte.toUnsignedInt(this) fun Byte.toUint() = java.lang.Byte.toUnsignedInt(this)
@@ -483,6 +492,7 @@ open class GameFontBase : Font {
internal val asciiWidths: HashMap<Int, Int> = HashMap() internal val asciiWidths: HashMap<Int, Int> = HashMap()
lateinit internal var extASheet: SpriteSheet lateinit internal var extASheet: SpriteSheet
lateinit internal var extBSheet: SpriteSheet
lateinit internal var kanaSheet: SpriteSheet lateinit internal var kanaSheet: SpriteSheet
lateinit internal var cjkPunct: SpriteSheet lateinit internal var cjkPunct: SpriteSheet
// static SpriteSheet uniHan; // static SpriteSheet uniHan;
@@ -492,8 +502,6 @@ open class GameFontBase : Font {
lateinit internal var wenQuanYi_1: SpriteSheet lateinit internal var wenQuanYi_1: SpriteSheet
lateinit internal var wenQuanYi_2: SpriteSheet lateinit internal var wenQuanYi_2: SpriteSheet
lateinit internal var greekSheet: SpriteSheet lateinit internal var greekSheet: SpriteSheet
lateinit internal var romanianSheet: SpriteSheet
lateinit internal var romanianSheetNarrow: SpriteSheet
internal val JUNG_COUNT = 21 internal val JUNG_COUNT = 21
internal val JONG_COUNT = 28 internal val JONG_COUNT = 28
@@ -502,8 +510,7 @@ open class GameFontBase : Font {
internal val W_HANGUL = 11 internal val W_HANGUL = 11
internal val W_KANA = 12 internal val W_KANA = 12
internal val W_UNIHAN = 16 internal val W_UNIHAN = 16
internal val W_LATIN_WIDE = 9 // width of regular letters, including m internal val W_LATIN_WIDE = 9 // width of regular letters
internal val W_LATIN_NARROW = 5 // width of letter f, t, i, l
internal val H = 20 internal val H = 20
internal val H_HANGUL = 16 internal val H_HANGUL = 16
@@ -512,24 +519,42 @@ open class GameFontBase : Font {
internal val SHEET_ASCII_VARW = 0 internal val SHEET_ASCII_VARW = 0
internal val SHEET_HANGUL = 1 internal val SHEET_HANGUL = 1
internal val SHEET_EXTA_VARW = 2 internal val SHEET_EXTA_VARW = 3
internal val SHEET_KANA = 3 internal val SHEET_EXTB_VARW = 4
internal val SHEET_CJK_PUNCT = 4 internal val SHEET_KANA = 5
internal val SHEET_UNIHAN = 5 internal val SHEET_CJK_PUNCT = 6
internal val SHEET_CYRILIC_VARW = 6 internal val SHEET_UNIHAN = 7
internal val SHEET_FW_UNI = 7 internal val SHEET_CYRILIC_VARW = 8
internal val SHEET_UNI_PUNCT = 8 internal val SHEET_FW_UNI = 9
internal val SHEET_WENQUANYI_1 = 9 internal val SHEET_UNI_PUNCT = 10
internal val SHEET_WENQUANYI_2 = 10 internal val SHEET_WENQUANYI_1 = 11
internal val SHEET_GREEK_VARW = 11 internal val SHEET_WENQUANYI_2 = 12
internal val SHEET_EXTB_ROMANIAN_WIDE = 12 internal val SHEET_GREEK_VARW = 13
internal val SHEET_EXTB_ROMANIAN_NARROW = 13
internal val SHEET_UNKNOWN = 254 internal val SHEET_UNKNOWN = 254
internal val SHEET_COLOURCODE = 255 internal val SHEET_COLOURCODE = 255
lateinit internal var sheetKey: Array<SpriteSheet?> lateinit internal var sheetKey: Array<SpriteSheet?>
/**
* Runic letters list used for game. The set is
* Younger Futhark + Medieval rune 'e' + Punct + Runic Almanac
* BEWARE OF SIMILAR-LOOKING RUNES, especially:
* * Algiz ᛉ instead of Maðr ᛘ
* * Short-Twig Hagall ᚽ instead of Runic Letter E ᛂ
* * Runic Letter OE ᚯ instead of Óss ᚬ
* Examples:
* ᛭ᛋᛁᚴᚱᛁᚦᛦ᛭
* ᛭ᛂᛚᛋᛅ᛭ᛏᚱᚢᛏᚾᛁᚾᚴᚢᚾᛅ᛬ᛅᚱᚾᛅᛏᛅᛚᛋ
*/
internal val runicList = arrayOf('ᚠ', 'ᚢ', 'ᚦ', 'ᚬ', 'ᚱ', 'ᚴ', 'ᚼ', 'ᚾ', '', 'ᛅ', 'ᛋ', 'ᛏ', 'ᛒ', 'ᛘ', 'ᛚ', 'ᛦ', 'ᛂ', '', '᛫', '', 'ᛮ', 'ᛯ', 'ᛰ')
internal var interchar = 0 internal var interchar = 0
internal var scale = 1 internal var scale = 1
set(value) { set(value) {
@@ -537,6 +562,49 @@ open class GameFontBase : Font {
else throw IllegalArgumentException("Font scale cannot be zero or negative (input: $value)") else throw IllegalArgumentException("Font scale cannot be zero or negative (input: $value)")
} }
val colourKey = hashMapOf(
Pair(0x10.toChar(), Color(0xFFFFFF)), //*w hite
Pair(0x11.toChar(), Color(0xFFE080)), //*y ellow
Pair(0x12.toChar(), Color(0xFFB020)), //o range
Pair(0x13.toChar(), Color(0xFF8080)), //*r ed
Pair(0x14.toChar(), Color(0xFFA0E0)), //f uchsia
Pair(0x15.toChar(), Color(0xE0A0FF)), //*m agenta (purple)
Pair(0x16.toChar(), Color(0x8080FF)), //*b lue
Pair(0x17.toChar(), Color(0x80FFFF)), //c yan
Pair(0x18.toChar(), Color(0x80FF80)), //*g reen
Pair(0x19.toChar(), Color(0x008000)), //v iridian
Pair(0x1A.toChar(), Color(0x805030)), //x (khaki)
Pair(0x1B.toChar(), Color(0x808080)) //*k
//* marked: commonly used
)
val colToCode = hashMapOf(
Pair("w", 0x10.toChar()),
Pair("y", 0x11.toChar()),
Pair("o", 0x12.toChar()),
Pair("r", 0x13.toChar()),
Pair("f", 0x14.toChar()),
Pair("m", 0x15.toChar()),
Pair("b", 0x16.toChar()),
Pair("c", 0x17.toChar()),
Pair("g", 0x18.toChar()),
Pair("v", 0x19.toChar()),
Pair("x", 0x1A.toChar()),
Pair("k", 0x1B.toChar())
)
val codeToCol = hashMapOf(
Pair("w", colourKey[0x10.toChar()]),
Pair("y", colourKey[0x11.toChar()]),
Pair("o", colourKey[0x12.toChar()]),
Pair("r", colourKey[0x13.toChar()]),
Pair("f", colourKey[0x14.toChar()]),
Pair("m", colourKey[0x15.toChar()]),
Pair("b", colourKey[0x16.toChar()]),
Pair("c", colourKey[0x17.toChar()]),
Pair("g", colourKey[0x18.toChar()]),
Pair("v", colourKey[0x19.toChar()]),
Pair("x", colourKey[0x1A.toChar()]),
Pair("k", colourKey[0x1B.toChar()])
)
}// end of companion object }// end of companion object
} }

View File

@@ -16,6 +16,8 @@ class GameFontImpl : GameFontBase() {
"./assets/graphics/fonts/ascii_variable.tga", 15, 19, 1) "./assets/graphics/fonts/ascii_variable.tga", 15, 19, 1)
GameFontBase.extASheet = SpriteSheet( GameFontBase.extASheet = SpriteSheet(
"./assets/graphics/fonts/LatinExtA_variable.tga", 15, 19, 1) "./assets/graphics/fonts/LatinExtA_variable.tga", 15, 19, 1)
GameFontBase.extBSheet = SpriteSheet(
"./assets/graphics/fonts/LatinExtB_variable.tga", 15, 19, 1)
GameFontBase.kanaSheet = SpriteSheet( GameFontBase.kanaSheet = SpriteSheet(
"./assets/graphics/fonts/kana.tga", GameFontBase.W_KANA, GameFontBase.H_KANA) "./assets/graphics/fonts/kana.tga", GameFontBase.W_KANA, GameFontBase.H_KANA)
GameFontBase.cjkPunct = SpriteSheet( GameFontBase.cjkPunct = SpriteSheet(
@@ -43,15 +45,13 @@ class GameFontImpl : GameFontBase() {
"./assets/graphics/fonts/wenquanyi_11pt_part2.tga", 16, 18, 2) "./assets/graphics/fonts/wenquanyi_11pt_part2.tga", 16, 18, 2)
GameFontBase.greekSheet = SpriteSheet( GameFontBase.greekSheet = SpriteSheet(
"./assets/graphics/fonts/greek_variable.tga", 15, 19, 1) "./assets/graphics/fonts/greek_variable.tga", 15, 19, 1)
GameFontBase.romanianSheet = SpriteSheet(
"./assets/graphics/fonts/romana_wide.tga", GameFontBase.W_LATIN_WIDE, GameFontBase.H)
GameFontBase.romanianSheetNarrow = SpriteSheet(
"./assets/graphics/fonts/romana_narrow.tga", GameFontBase.W_LATIN_NARROW, GameFontBase.H)
val shk = arrayOf( val shk = arrayOf(
GameFontBase.asciiSheet, GameFontBase.asciiSheet,
GameFontBase.hangulSheet, GameFontBase.hangulSheet,
null, // here was customised runic sheet
GameFontBase.extASheet, GameFontBase.extASheet,
GameFontBase.extBSheet,
GameFontBase.kanaSheet, GameFontBase.kanaSheet,
GameFontBase.cjkPunct, GameFontBase.cjkPunct,
null, // Full unihan, filler because we're using WenQuanYi null, // Full unihan, filler because we're using WenQuanYi
@@ -60,16 +60,24 @@ class GameFontImpl : GameFontBase() {
GameFontBase.uniPunct, GameFontBase.uniPunct,
GameFontBase.wenQuanYi_1, GameFontBase.wenQuanYi_1,
GameFontBase.wenQuanYi_2, GameFontBase.wenQuanYi_2,
GameFontBase.greekSheet, GameFontBase.greekSheet
GameFontBase.romanianSheet,
GameFontBase.romanianSheetNarrow
) )
GameFontBase.sheetKey = shk GameFontBase.sheetKey = shk
buildWidthTable(asciiSheet, 0, 0..0xFF) buildWidthTable(asciiSheet, 0, 0..0xFF)
buildWidthTable(extASheet, 0x100, 0..0x7F) buildWidthTable(extASheet, 0x100, 0..0x7F)
buildWidthTable(cyrilic, 0x400, 0..0x5F) buildWidthTable(extBSheet, 0x180, 0..0xCF)
buildWidthTable(cyrilic, 0x400, 0..0x5F)
buildWidthTable(greekSheet, 0x370, 0..0x5F) buildWidthTable(greekSheet, 0x370, 0..0x5F)
} }
fun reload() {
GameFontBase.cyrilic = SpriteSheet(
when (GameFontDemo.gameLocale.substring(0..1)) {
"bg" -> "./assets/graphics/fonts/cyrilic_bulgarian_variable.tga"
"sr" -> "./assets/graphics/fonts/cyrilic_serbian_variable.tga"
else -> "./assets/graphics/fonts/cyrilic_variable.tga"
}, 15, 19, 1)
}
} }

Binary file not shown.

Before

Width:  |  Height:  |  Size: 160 KiB

After

Width:  |  Height:  |  Size: 160 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 260 KiB

Binary file not shown.

Before

Width:  |  Height:  |  Size: 120 KiB

After

Width:  |  Height:  |  Size: 120 KiB

Binary file not shown.

Before

Width:  |  Height:  |  Size: 120 KiB

After

Width:  |  Height:  |  Size: 120 KiB

Binary file not shown.

Before

Width:  |  Height:  |  Size: 120 KiB

After

Width:  |  Height:  |  Size: 120 KiB

Binary file not shown.

Before

Width:  |  Height:  |  Size: 192 KiB

After

Width:  |  Height:  |  Size: 192 KiB

Binary file not shown.

Before

Width:  |  Height:  |  Size: 444 B

Binary file not shown.

Before

Width:  |  Height:  |  Size: 2.2 KiB

View File

@@ -0,0 +1,552 @@
package net.torvald.imagefont
import org.lwjgl.opengl.GL11
import org.newdawn.slick.*
import org.newdawn.slick.opengl.Texture
import java.nio.ByteOrder
import java.util.*
/**
* Created by minjaesong on 16-01-27.
*/
open class GameFontBase : Font {
private fun getHan(hanIndex: Int): IntArray {
val han_x = hanIndex % JONG_COUNT
val han_y = hanIndex / JONG_COUNT
val ret = intArrayOf(han_x, han_y)
return ret
}
private fun getHanChosung(hanIndex: Int) = hanIndex / (JUNG_COUNT * JONG_COUNT)
private fun getHanJungseong(hanIndex: Int) = hanIndex / JONG_COUNT % JUNG_COUNT
private fun getHanJongseong(hanIndex: Int) = hanIndex % JONG_COUNT
private val jungseongWide = arrayOf(8, 12, 13, 17, 18, 21)
private val jungseongComplex = arrayOf(9, 10, 11, 14, 15, 16, 22)
private fun isJungseongWide(hanIndex: Int) = jungseongWide.contains(getHanJungseong(hanIndex))
private fun isJungseongComplex(hanIndex: Int) = jungseongComplex.contains(getHanJungseong(hanIndex))
private fun getHanInitialRow(hanIndex: Int): Int {
val ret: Int
if (isJungseongWide(hanIndex))
ret = 2
else if (isJungseongComplex(hanIndex))
ret = 4
else
ret = 0
return if (getHanJongseong(hanIndex) == 0) ret else ret + 1
}
private fun getHanMedialRow(hanIndex: Int) = if (getHanJongseong(hanIndex) == 0) 6 else 7
private fun getHanFinalRow(hanIndex: Int): Int {
val jungseongIndex = getHanJungseong(hanIndex)
return if (jungseongWide.contains(jungseongIndex))
8
else
9
}
private fun isHangul(c: Char) = c.toInt() >= 0xAC00 && c.toInt() < 0xD7A4
private fun isAscii(c: Char) = c.toInt() >= 0x20 && c.toInt() <= 0xFF
private fun isExtA(c: Char) = c.toInt() >= 0x100 && c.toInt() < 0x180
private fun isKana(c: Char) = c.toInt() >= 0x3040 && c.toInt() < 0x3100
private fun isCJKPunct(c: Char) = c.toInt() >= 0x3000 && c.toInt() < 0x3040
private fun isUniHan(c: Char) = c.toInt() >= 0x3400 && c.toInt() < 0xA000
private fun isCyrilic(c: Char) = c.toInt() >= 0x400 && c.toInt() < 0x460
private fun isFullwidthUni(c: Char) = c.toInt() >= 0xFF00 && c.toInt() < 0xFF20
private fun isUniPunct(c: Char) = c.toInt() >= 0x2000 && c.toInt() < 0x2070
private fun isWenQuanYi1(c: Char) = c.toInt() >= 0x33F3 && c.toInt() <= 0x69FC
private fun isWenQuanYi2(c: Char) = c.toInt() >= 0x69FD && c.toInt() <= 0x9FDC
private fun isGreek(c: Char) = c.toInt() >= 0x370 && c.toInt() <= 0x3CE
private fun isRomanian(c: Char) = c.toInt() >= 0x218 && c.toInt() <= 0x21A
private fun isRomanianNarrow(c: Char) = c.toInt() == 0x21B
private fun extAindexX(c: Char) = (c.toInt() - 0x100) % 16
private fun extAindexY(c: Char) = (c.toInt() - 0x100) / 16
private fun kanaIndexX(c: Char) = (c.toInt() - 0x3040) % 16
private fun kanaIndexY(c: Char) = (c.toInt() - 0x3040) / 16
private fun cjkPunctIndexX(c: Char) = (c.toInt() - 0x3000) % 16
private fun cjkPunctIndexY(c: Char) = (c.toInt() - 0x3000) / 16
private fun uniHanIndexX(c: Char) = (c.toInt() - 0x3400) % 256
private fun uniHanIndexY(c: Char) = (c.toInt() - 0x3400) / 256
private fun cyrilicIndexX(c: Char) = (c.toInt() - 0x400) % 16
private fun cyrilicIndexY(c: Char) = (c.toInt() - 0x400) / 16
private fun fullwidthUniIndexX(c: Char) = (c.toInt() - 0xFF00) % 16
private fun fullwidthUniIndexY(c: Char) = (c.toInt() - 0xFF00) / 16
private fun uniPunctIndexX(c: Char) = (c.toInt() - 0x2000) % 16
private fun uniPunctIndexY(c: Char) = (c.toInt() - 0x2000) / 16
private fun wenQuanYiIndexX(c: Char) =
(c.toInt() - if (c.toInt() <= 0x4DB5) 0x33F3 else 0x33F3 + 0x4A) % 32
private fun wenQuanYi1IndexY(c: Char) = (c.toInt() - (0x33F3 + 0x4A)) / 32
private fun wenQuanYi2IndexY(c: Char) = (c.toInt() - 0x69FD) / 32
private fun greekIndexX(c: Char) = (c.toInt() - 0x370) % 16
private fun greekIndexY(c: Char) = (c.toInt() - 0x370) / 16
private fun romanianIndexX(c: Char) = c.toInt() - 0x218
private fun romanianIndexY(c: Char) = 0
private fun thaiIndexX(c: Char) = (c.toInt() - 0xE00) % 16
private fun thaiIndexY(c: Char) = (c.toInt() - 0xE00) / 16
private fun thaiNarrowIndexX(c: Char) = 3
private fun thaiNarrowIndexY(c: Char) = 0
private val narrowWidthSheets = arrayOf(
SHEET_EXTB_ROMANIAN_NARROW
)
private val unihanWidthSheets = arrayOf(
SHEET_UNIHAN,
SHEET_FW_UNI,
SHEET_WENQUANYI_1,
SHEET_WENQUANYI_2
)
private val zeroWidthSheets = arrayOf(
SHEET_COLOURCODE
)
private val variableWidthSheets = arrayOf(
SHEET_ASCII_VARW,
SHEET_CYRILIC_VARW,
SHEET_EXTA_VARW,
SHEET_GREEK_VARW
)
override fun getWidth(s: String) = getWidthSubstr(s, s.length)
private fun getWidthSubstr(s: String, endIndex: Int): Int {
var len = 0
for (i in 0..endIndex - 1) {
val chr = s[i]
val ctype = getSheetType(s[i])
if (chr.toInt() == 0x21B) // Romanian t; HAX!
len += 6
else if (variableWidthSheets.contains(ctype)) {
try {
len += asciiWidths[chr.toInt()]!!
}
catch (e: kotlin.KotlinNullPointerException) {
println("KotlinNullPointerException on glyph number ${Integer.toHexString(chr.toInt()).toUpperCase()}")
System.exit(1)
}
}
else if (zeroWidthSheets.contains(ctype))
len += 0
else if (narrowWidthSheets.contains(ctype))
len += W_LATIN_NARROW
else if (ctype == SHEET_CJK_PUNCT)
len += W_ASIAN_PUNCT
else if (ctype == SHEET_HANGUL)
len += W_HANGUL
else if (ctype == SHEET_KANA)
len += W_KANA
else if (unihanWidthSheets.contains(ctype))
len += W_UNIHAN
else
len += W_LATIN_WIDE
if (i < endIndex - 1) len += interchar
}
return len * scale
}
override fun getHeight(s: String) = H * scale
override fun getLineHeight() = H * scale
override fun drawString(x: Float, y: Float, s: String) = drawString(x, y, s, Color.white)
override fun drawString(x: Float, y: Float, s: String, color: Color) {
GL11.glEnable(GL11.GL_BLEND)
GL11.glColorMask(true, true, true, true)
GL11.glBlendFunc(GL11.GL_SRC_ALPHA, GL11.GL_ONE_MINUS_SRC_ALPHA)
var thisCol = color
// hangul fonts first
//hangulSheet.startUse() // disabling texture binding to make the font coloured
// JOHAB
for (i in 0..s.length - 1) {
val ch = s[i]
if (isHangul(ch)) {
val hIndex = ch.toInt() - 0xAC00
val indexCho = getHanChosung(hIndex)
val indexJung = getHanJungseong(hIndex)
val indexJong = getHanJongseong(hIndex)
val choRow = getHanInitialRow(hIndex)
val jungRow = getHanMedialRow(hIndex)
val jongRow = getHanFinalRow(hIndex)
val glyphW = getWidth(ch.toString())
hangulSheet.getSubImage(indexCho, choRow).drawWithShadow(
Math.round(x + getWidthSubstr(s, i + 1) - glyphW).toFloat(),
Math.round(((H - H_HANGUL) / 2).toFloat() + y + 1f).toFloat(),
scale.toFloat(), thisCol
)
hangulSheet.getSubImage(indexJung, jungRow).drawWithShadow(
Math.round(x + getWidthSubstr(s, i + 1) - glyphW).toFloat(),
Math.round(((H - H_HANGUL) / 2).toFloat() + y + 1f).toFloat(),
scale.toFloat(), thisCol
)
hangulSheet.getSubImage(indexJong, jongRow).drawWithShadow(
Math.round(x + getWidthSubstr(s, i + 1) - glyphW).toFloat(),
Math.round(((H - H_HANGUL) / 2).toFloat() + y + 1f).toFloat(),
scale.toFloat(), thisCol
)
}
}
//hangulSheet.endUse()
// unihan fonts
/*uniHan.startUse();
for (int i = 0; i < s.length(); i++) {
char ch = s.charAt(i);
if (isUniHan(ch)) {
int glyphW = getWidth("" + ch);
uniHan.renderInUse(
Math.round(x
+ getWidthSubstr(s, i + 1) - glyphW
)
, Math.round((H - H_UNIHAN) / 2 + y)
, uniHanIndexX(ch)
, uniHanIndexY(ch)
);
}
}
uniHan.endUse();*/
// WenQuanYi 1
//wenQuanYi_1.startUse()
for (i in 0..s.length - 1) {
val ch = s[i]
if (isWenQuanYi1(ch)) {
val glyphW = getWidth("" + ch)
wenQuanYi_1.getSubImage(wenQuanYiIndexX(ch), wenQuanYi1IndexY(ch)).drawWithShadow(
Math.round(x + getWidthSubstr(s, i + 1) - glyphW).toFloat(),
Math.round((H - H_UNIHAN) / 2 + y).toFloat(),
scale.toFloat(), thisCol
)
}
}
//wenQuanYi_1.endUse()
// WenQuanYi 2
//wenQuanYi_2.startUse()
for (i in 0..s.length - 1) {
val ch = s[i]
if (isWenQuanYi2(ch)) {
val glyphW = getWidth("" + ch)
wenQuanYi_2.getSubImage(wenQuanYiIndexX(ch), wenQuanYi2IndexY(ch)).drawWithShadow(
Math.round(x + getWidthSubstr(s, i + 1) - glyphW).toFloat(),
Math.round((H - H_UNIHAN) / 2 + y).toFloat(),
scale.toFloat(), thisCol
)
}
}
//wenQuanYi_2.endUse()
// regular fonts
var prevInstance = -1
for (i in 0..s.length - 1) {
val ch = s[i]
if (!isHangul(ch) && !isUniHan(ch)) {
// if not init, endUse first
if (prevInstance != -1) {
//sheetKey[prevInstance].endUse()
}
//sheetKey[getSheetType(ch)].startUse()
prevInstance = getSheetType(ch)
val sheetX: Int
val sheetY: Int
when (prevInstance) {
SHEET_EXTA_VARW -> {
sheetX = extAindexX(ch)
sheetY = extAindexY(ch)
}
SHEET_KANA -> {
sheetX = kanaIndexX(ch)
sheetY = kanaIndexY(ch)
}
SHEET_CJK_PUNCT -> {
sheetX = cjkPunctIndexX(ch)
sheetY = cjkPunctIndexY(ch)
}
SHEET_CYRILIC_VARW -> {
sheetX = cyrilicIndexX(ch)
sheetY = cyrilicIndexY(ch)
}
SHEET_FW_UNI -> {
sheetX = fullwidthUniIndexX(ch)
sheetY = fullwidthUniIndexY(ch)
}
SHEET_UNI_PUNCT -> {
sheetX = uniPunctIndexX(ch)
sheetY = uniPunctIndexY(ch)
}
SHEET_GREEK_VARW -> {
sheetX = greekIndexX(ch)
sheetY = greekIndexY(ch)
}
SHEET_EXTB_ROMANIAN_WIDE -> {
sheetX = romanianIndexX(ch)
sheetY = romanianIndexY(ch)
}
SHEET_EXTB_ROMANIAN_NARROW -> {
sheetX = 0
sheetY = 0
}
else -> {
sheetX = ch.toInt() % 16
sheetY = ch.toInt() / 16
}
}
val glyphW = getWidth("" + ch)
try {
sheetKey[prevInstance]!!.getSubImage(sheetX, sheetY).drawWithShadow(
Math.round(x + getWidthSubstr(s, i + 1) - glyphW).toFloat(),
// to deal with the height difference of the sheets
Math.round(y).toFloat() + (if (prevInstance == SHEET_CJK_PUNCT) -1 // height hack
else if (prevInstance == SHEET_FW_UNI) (H - H_HANGUL) / 2 // completely legit height adjustment
else 0).toFloat(),
scale.toFloat(), thisCol
)
}
catch (e: ArrayIndexOutOfBoundsException) {
// character that does not exist in the sheet. No render, pass.
}
catch (e1: RuntimeException) {
// System.err.println("[GameFontBase] RuntimeException raised while processing character '$ch' (U+${Integer.toHexString(ch.toInt()).toUpperCase()})")
// e1.printStackTrack()
}
}
}
if (prevInstance != -1) {
//sheetKey[prevInstance].endUse()
}
GL11.glEnd()
}
private fun getSheetType(c: Char): Int {
// EFs
if (isRomanianNarrow(c))
return SHEET_EXTB_ROMANIAN_NARROW
else if (isHangul(c))
return SHEET_HANGUL
else if (isKana(c))
return SHEET_KANA
else if (isUniHan(c))
return SHEET_UNIHAN
else if (isAscii(c))
return SHEET_ASCII_VARW
else if (isExtA(c))
return SHEET_EXTA_VARW
else if (isCyrilic(c))
return SHEET_CYRILIC_VARW
else if (isUniPunct(c))
return SHEET_UNI_PUNCT
else if (isCJKPunct(c))
return SHEET_CJK_PUNCT
else if (isFullwidthUni(c))
return SHEET_FW_UNI
else if (isGreek(c))
return SHEET_GREEK_VARW
else if (isRomanian(c))
return SHEET_EXTB_ROMANIAN_WIDE
else
return SHEET_UNKNOWN// fixed width punctuations
// fixed width
// fallback
}
/**
* Draw part of a string to the screen. Note that this will still position the text as though
* it's part of the bigger string.
* @param x
* *
* @param y
* *
* @param s
* *
* @param color
* *
* @param startIndex
* *
* @param endIndex
*/
override fun drawString(x: Float, y: Float, s: String, color: Color, startIndex: Int, endIndex: Int) {
val unprintedHead = s.substring(0, startIndex)
val printedBody = s.substring(startIndex, endIndex)
val xoff = getWidth(unprintedHead)
drawString(x + xoff, y, printedBody, color)
}
fun buildWidthTable(sheet: SpriteSheet, codeOffset: Int, codeRange: IntRange, rows: Int = 16) {
fun Byte.toUint() = java.lang.Byte.toUnsignedInt(this)
/** @return Intarray(R, G, B, A) */
fun Texture.getPixel(x: Int, y: Int): IntArray {
val textureWidth = this.textureWidth
val hasAlpha = this.hasAlpha()
val offset = (if (hasAlpha) 4 else 3) * (textureWidth * y + x) // 4: # of channels (RGBA)
if (ByteOrder.nativeOrder() == ByteOrder.LITTLE_ENDIAN) {
return intArrayOf(
this.textureData[offset].toUint(),
this.textureData[offset + 1].toUint(),
this.textureData[offset + 2].toUint(),
if (hasAlpha)
this.textureData[offset + 3].toUint()
else 255
)
}
else {
return intArrayOf(
this.textureData[offset + 2].toUint(),
this.textureData[offset + 1].toUint(),
this.textureData[offset].toUint(),
if (hasAlpha)
this.textureData[offset + 3].toUint()
else 255
)
}
}
val binaryCodeOffset = 15
val cellW = sheet.getSubImage(0, 0).width + 1 // should be 16
val cellH = sheet.getSubImage(0, 0).height + 1 // should be 20
// control chars
for (ccode in codeRange) {
val glyphX = ccode % rows
val glyphY = ccode / rows
val codeStartX = (glyphX * cellW) + binaryCodeOffset
val codeStartY = (glyphY * cellH)
var glyphWidth = 0
for (downCtr in 0..3) {
// if alpha is not zero, assume it's 1
if (sheet.texture.getPixel(codeStartX, codeStartY + downCtr)[3] == 255) {
glyphWidth = glyphWidth or (1 shl downCtr)
}
}
asciiWidths[codeOffset + ccode] = glyphWidth
}
}
companion object {
lateinit internal var hangulSheet: SpriteSheet
lateinit internal var asciiSheet: SpriteSheet
internal val asciiWidths: HashMap<Int, Int> = HashMap()
lateinit internal var extASheet: SpriteSheet
lateinit internal var kanaSheet: SpriteSheet
lateinit internal var cjkPunct: SpriteSheet
// static SpriteSheet uniHan;
lateinit internal var cyrilic: SpriteSheet
lateinit internal var fullwidthForms: SpriteSheet
lateinit internal var uniPunct: SpriteSheet
lateinit internal var wenQuanYi_1: SpriteSheet
lateinit internal var wenQuanYi_2: SpriteSheet
lateinit internal var greekSheet: SpriteSheet
lateinit internal var romanianSheet: SpriteSheet
lateinit internal var romanianSheetNarrow: SpriteSheet
internal val JUNG_COUNT = 21
internal val JONG_COUNT = 28
internal val W_ASIAN_PUNCT = 10
internal val W_HANGUL = 11
internal val W_KANA = 12
internal val W_UNIHAN = 16
internal val W_LATIN_WIDE = 9 // width of regular letters, including m
internal val W_LATIN_NARROW = 5 // width of letter f, t, i, l
internal val H = 20
internal val H_HANGUL = 16
internal val H_UNIHAN = 16
internal val H_KANA = 20
internal val SHEET_ASCII_VARW = 0
internal val SHEET_HANGUL = 1
internal val SHEET_EXTA_VARW = 2
internal val SHEET_KANA = 3
internal val SHEET_CJK_PUNCT = 4
internal val SHEET_UNIHAN = 5
internal val SHEET_CYRILIC_VARW = 6
internal val SHEET_FW_UNI = 7
internal val SHEET_UNI_PUNCT = 8
internal val SHEET_WENQUANYI_1 = 9
internal val SHEET_WENQUANYI_2 = 10
internal val SHEET_GREEK_VARW = 11
internal val SHEET_EXTB_ROMANIAN_WIDE = 12
internal val SHEET_EXTB_ROMANIAN_NARROW = 13
internal val SHEET_UNKNOWN = 254
internal val SHEET_COLOURCODE = 255
lateinit internal var sheetKey: Array<SpriteSheet?>
internal var interchar = 0
internal var scale = 1
set(value) {
if (value > 0) field = value
else throw IllegalArgumentException("Font scale cannot be zero or negative (input: $value)")
}
}// end of companion object
}
fun Image.drawWithShadow(x: Float, y: Float, color: Color) =
this.drawWithShadow(x, y, 1f, color)
fun Image.drawWithShadow(x: Float, y: Float, scale: Float, color: Color) {
this.draw(x + 1, y + 1, scale, color.darker(0.5f))
this.draw(x , y + 1, scale, color.darker(0.5f))
this.draw(x + 1, y , scale, color.darker(0.5f))
this.draw(x, y, scale, color)
}

View File

@@ -0,0 +1,75 @@
package net.torvald.imagefont
import net.torvald.terrarum.imagefont.GameFontDemo
import org.newdawn.slick.*
/**
* Created by minjaesong on 16-01-20.
*/
class GameFontImpl : GameFontBase() {
init {
GameFontBase.hangulSheet = SpriteSheet(
"./assets/graphics/fonts/hangul_johab.tga", GameFontBase.W_HANGUL, GameFontBase.H_HANGUL)
GameFontBase.asciiSheet = SpriteSheet(
"./assets/graphics/fonts/ascii_variable.tga", 15, 19, 1)
GameFontBase.extASheet = SpriteSheet(
"./assets/graphics/fonts/LatinExtA_variable.tga", 15, 19, 1)
GameFontBase.kanaSheet = SpriteSheet(
"./assets/graphics/fonts/kana.tga", GameFontBase.W_KANA, GameFontBase.H_KANA)
GameFontBase.cjkPunct = SpriteSheet(
"./assets/graphics/fonts/cjkpunct.tga", GameFontBase.W_ASIAN_PUNCT, GameFontBase.H_KANA)
/*uniHan = new SpriteSheet(
"./assets/graphics/fonts/unifont_unihan"
+ ((!terrarum.gameLocale.contains("zh"))
? "_ja" : "")
+".tga"
, W_UNIHAN, H_UNIHAN
);*/
GameFontBase.cyrilic = SpriteSheet(
when (GameFontDemo.gameLocale.substring(0..1)) {
"bg" -> "./assets/graphics/fonts/cyrilic_bulgarian_variable.tga"
"sr" -> "./assets/graphics/fonts/cyrilic_serbian_variable.tga"
else -> "./assets/graphics/fonts/cyrilic_variable.tga"
}, 15, 19, 1)
GameFontBase.fullwidthForms = SpriteSheet(
"./assets/graphics/fonts/fullwidth_forms.tga", GameFontBase.W_UNIHAN, GameFontBase.H_UNIHAN)
GameFontBase.uniPunct = SpriteSheet(
"./assets/graphics/fonts/unipunct.tga", GameFontBase.W_LATIN_WIDE, GameFontBase.H)
GameFontBase.wenQuanYi_1 = SpriteSheet(
"./assets/graphics/fonts/wenquanyi_11pt_part1.tga", 16, 18, 2)
GameFontBase.wenQuanYi_2 = SpriteSheet(
"./assets/graphics/fonts/wenquanyi_11pt_part2.tga", 16, 18, 2)
GameFontBase.greekSheet = SpriteSheet(
"./assets/graphics/fonts/greek_variable.tga", 15, 19, 1)
GameFontBase.romanianSheet = SpriteSheet(
"./assets/graphics/fonts/romana_wide.tga", GameFontBase.W_LATIN_WIDE, GameFontBase.H)
GameFontBase.romanianSheetNarrow = SpriteSheet(
"./assets/graphics/fonts/romana_narrow.tga", GameFontBase.W_LATIN_NARROW, GameFontBase.H)
val shk = arrayOf(
GameFontBase.asciiSheet,
GameFontBase.hangulSheet,
GameFontBase.extASheet,
GameFontBase.kanaSheet,
GameFontBase.cjkPunct,
null, // Full unihan, filler because we're using WenQuanYi
GameFontBase.cyrilic,
GameFontBase.fullwidthForms,
GameFontBase.uniPunct,
GameFontBase.wenQuanYi_1,
GameFontBase.wenQuanYi_2,
GameFontBase.greekSheet,
GameFontBase.romanianSheet,
GameFontBase.romanianSheetNarrow
)
GameFontBase.sheetKey = shk
buildWidthTable(asciiSheet, 0, 0..0xFF)
buildWidthTable(extASheet, 0x100, 0..0x7F)
buildWidthTable(cyrilic, 0x400, 0..0x5F)
buildWidthTable(greekSheet, 0x370, 0..0x5F)
}
}

View File

@@ -0,0 +1 @@
Font implementations for Slick2d

154
demo/.idea/workspace.xml generated
View File

@@ -23,8 +23,8 @@
</component> </component>
<component name="ExecutionTargetManager" SELECTED_TARGET="default_target" /> <component name="ExecutionTargetManager" SELECTED_TARGET="default_target" />
<component name="FileEditorManager"> <component name="FileEditorManager">
<leaf> <leaf SIDE_TABS_SIZE_LIMIT_KEY="300">
<file leaf-file-name="GameFontDemo.kt" pinned="false" current-in-tab="true"> <file leaf-file-name="GameFontDemo.kt" pinned="false" current-in-tab="false">
<entry file="file://$PROJECT_DIR$/src/net/torvald/terrarum/imagefont/GameFontDemo.kt"> <entry file="file://$PROJECT_DIR$/src/net/torvald/terrarum/imagefont/GameFontDemo.kt">
<provider selected="true" editor-type-id="text-editor"> <provider selected="true" editor-type-id="text-editor">
<state relative-caret-position="610"> <state relative-caret-position="610">
@@ -39,8 +39,8 @@
<file leaf-file-name="GameFontBase.kt" pinned="false" current-in-tab="false"> <file leaf-file-name="GameFontBase.kt" pinned="false" current-in-tab="false">
<entry file="file://$PROJECT_DIR$/src/net/torvald/terrarum/imagefont/GameFontBase.kt"> <entry file="file://$PROJECT_DIR$/src/net/torvald/terrarum/imagefont/GameFontBase.kt">
<provider selected="true" editor-type-id="text-editor"> <provider selected="true" editor-type-id="text-editor">
<state relative-caret-position="400"> <state relative-caret-position="202">
<caret line="516" column="36" lean-forward="false" selection-start-line="516" selection-start-column="36" selection-end-line="516" selection-end-column="36" /> <caret line="493" column="0" lean-forward="false" selection-start-line="493" selection-start-column="0" selection-end-line="493" selection-end-column="0" />
<folding> <folding>
<element signature="e#31#171#0" expanded="true" /> <element signature="e#31#171#0" expanded="true" />
</folding> </folding>
@@ -48,31 +48,11 @@
</provider> </provider>
</entry> </entry>
</file> </file>
<file leaf-file-name="config.properties" pinned="false" current-in-tab="false"> <file leaf-file-name="GameFontImpl.kt" pinned="false" current-in-tab="true">
<entry file="file://$PROJECT_DIR$/config.properties">
<provider selected="true" editor-type-id="text-editor">
<state relative-caret-position="0">
<caret line="0" column="10" lean-forward="true" selection-start-line="0" selection-start-column="10" selection-end-line="0" selection-end-column="10" />
<folding />
</state>
</provider>
</entry>
</file>
<file leaf-file-name="text.txt" pinned="false" current-in-tab="false">
<entry file="file://$PROJECT_DIR$/text.txt">
<provider selected="true" editor-type-id="text-editor">
<state relative-caret-position="0">
<caret line="0" column="95" lean-forward="false" selection-start-line="0" selection-start-column="95" selection-end-line="0" selection-end-column="95" />
<folding />
</state>
</provider>
</entry>
</file>
<file leaf-file-name="GameFontImpl.kt" pinned="false" current-in-tab="false">
<entry file="file://$PROJECT_DIR$/src/net/torvald/terrarum/imagefont/GameFontImpl.kt"> <entry file="file://$PROJECT_DIR$/src/net/torvald/terrarum/imagefont/GameFontImpl.kt">
<provider selected="true" editor-type-id="text-editor"> <provider selected="true" editor-type-id="text-editor">
<state relative-caret-position="190"> <state relative-caret-position="356">
<caret line="29" column="0" lean-forward="false" selection-start-line="29" selection-start-column="0" selection-end-line="29" selection-end-column="0" /> <caret line="48" column="26" lean-forward="false" selection-start-line="48" selection-start-column="26" selection-end-line="48" selection-end-column="26" />
<folding> <folding>
<element signature="e#31#108#0" expanded="true" /> <element signature="e#31#108#0" expanded="true" />
</folding> </folding>
@@ -112,21 +92,21 @@
<component name="IdeDocumentHistory"> <component name="IdeDocumentHistory">
<option name="CHANGED_PATHS"> <option name="CHANGED_PATHS">
<list> <list>
<option value="$PROJECT_DIR$/src/net/torvald/terrarum/imagefont/GameFontImpl.kt" />
<option value="$PROJECT_DIR$/text.properties" /> <option value="$PROJECT_DIR$/text.properties" />
<option value="$PROJECT_DIR$/src/net/torvald/terrarum/imagefont/GameFontBase.kt" />
<option value="$PROJECT_DIR$/text.txt" />
<option value="$PROJECT_DIR$/config.properties" /> <option value="$PROJECT_DIR$/config.properties" />
<option value="$PROJECT_DIR$/META-INF/MANIFEST.MF" /> <option value="$PROJECT_DIR$/META-INF/MANIFEST.MF" />
<option value="$PROJECT_DIR$/src/net/torvald/terrarum/imagefont/GameFontDemo.kt" /> <option value="$PROJECT_DIR$/src/net/torvald/terrarum/imagefont/GameFontDemo.kt" />
<option value="$PROJECT_DIR$/src/net/torvald/terrarum/imagefont/GameFontBase.kt" />
<option value="$PROJECT_DIR$/src/net/torvald/terrarum/imagefont/GameFontImpl.kt" />
<option value="$PROJECT_DIR$/text.txt" />
</list> </list>
</option> </option>
</component> </component>
<component name="ProjectFrameBounds"> <component name="ProjectFrameBounds">
<option name="x" value="-8" /> <option name="x" value="-1688" />
<option name="y" value="-8" /> <option name="y" value="-8" />
<option name="width" value="1936" /> <option name="width" value="1696" />
<option name="height" value="1176" /> <option name="height" value="1026" />
</component> </component>
<component name="ProjectView"> <component name="ProjectView">
<navigator currentView="ProjectPane" proportions="" version="1"> <navigator currentView="ProjectPane" proportions="" version="1">
@@ -404,7 +384,7 @@
<servers /> <servers />
</component> </component>
<component name="ToolWindowManager"> <component name="ToolWindowManager">
<frame x="-8" y="-8" width="1936" height="1176" extended-state="6" /> <frame x="-1688" y="-8" width="1696" height="1026" extended-state="6" />
<editor active="true" /> <editor active="true" />
<layout> <layout>
<window_info id="Palette" active="false" anchor="right" auto_hide="false" internal_type="DOCKED" type="DOCKED" visible="false" show_stripe_button="true" weight="0.33" sideWeight="0.5" order="6" side_tool="false" content_ui="tabs" /> <window_info id="Palette" active="false" anchor="right" auto_hide="false" internal_type="DOCKED" type="DOCKED" visible="false" show_stripe_button="true" weight="0.33" sideWeight="0.5" order="6" side_tool="false" content_ui="tabs" />
@@ -417,14 +397,13 @@
<window_info id="Run" active="false" anchor="bottom" auto_hide="false" internal_type="DOCKED" type="DOCKED" visible="false" show_stripe_button="true" weight="0.3292683" sideWeight="0.5" order="1" side_tool="false" content_ui="tabs" /> <window_info id="Run" active="false" anchor="bottom" auto_hide="false" internal_type="DOCKED" type="DOCKED" visible="false" show_stripe_button="true" weight="0.3292683" sideWeight="0.5" order="1" side_tool="false" content_ui="tabs" />
<window_info id="Terminal" active="false" anchor="bottom" auto_hide="false" internal_type="DOCKED" type="DOCKED" visible="false" show_stripe_button="true" weight="0.33" sideWeight="0.5" order="9" side_tool="false" content_ui="tabs" /> <window_info id="Terminal" active="false" anchor="bottom" auto_hide="false" internal_type="DOCKED" type="DOCKED" visible="false" show_stripe_button="true" weight="0.33" sideWeight="0.5" order="9" side_tool="false" content_ui="tabs" />
<window_info id="Designer" active="false" anchor="right" auto_hide="false" internal_type="DOCKED" type="DOCKED" visible="false" show_stripe_button="true" weight="0.33" sideWeight="0.5" order="4" side_tool="false" content_ui="tabs" /> <window_info id="Designer" active="false" anchor="right" auto_hide="false" internal_type="DOCKED" type="DOCKED" visible="false" show_stripe_button="true" weight="0.33" sideWeight="0.5" order="4" side_tool="false" content_ui="tabs" />
<window_info id="Project" active="false" anchor="left" auto_hide="false" internal_type="DOCKED" type="DOCKED" visible="true" show_stripe_button="true" weight="0.17948718" sideWeight="0.5" order="0" side_tool="false" content_ui="combo" /> <window_info id="Project" active="false" anchor="left" auto_hide="false" internal_type="DOCKED" type="DOCKED" visible="true" show_stripe_button="true" weight="0.20833333" sideWeight="0.5" order="0" side_tool="false" content_ui="combo" />
<window_info id="LuaJ" active="false" anchor="right" auto_hide="false" internal_type="DOCKED" type="DOCKED" visible="false" show_stripe_button="true" weight="0.32960597" sideWeight="0.5" order="2" side_tool="false" content_ui="tabs" /> <window_info id="LuaJ" active="false" anchor="right" auto_hide="false" internal_type="DOCKED" type="DOCKED" visible="false" show_stripe_button="true" weight="0.32960597" sideWeight="0.5" order="2" side_tool="false" content_ui="tabs" />
<window_info id="Find" active="false" anchor="bottom" auto_hide="false" internal_type="DOCKED" type="DOCKED" visible="false" show_stripe_button="true" weight="0.33" sideWeight="0.5" order="3" side_tool="false" content_ui="tabs" />
<window_info id="Structure" active="false" anchor="right" auto_hide="false" internal_type="DOCKED" type="DOCKED" visible="false" show_stripe_button="true" weight="0.3054371" sideWeight="0.5" order="11" side_tool="false" content_ui="tabs" /> <window_info id="Structure" active="false" anchor="right" auto_hide="false" internal_type="DOCKED" type="DOCKED" visible="false" show_stripe_button="true" weight="0.3054371" sideWeight="0.5" order="11" side_tool="false" content_ui="tabs" />
<window_info id="Ant Build" active="false" anchor="right" auto_hide="false" internal_type="DOCKED" type="DOCKED" visible="false" show_stripe_button="true" weight="0.25" sideWeight="0.5" order="1" side_tool="false" content_ui="tabs" /> <window_info id="Ant Build" active="false" anchor="right" auto_hide="false" internal_type="DOCKED" type="DOCKED" visible="false" show_stripe_button="true" weight="0.25" sideWeight="0.5" order="1" side_tool="false" content_ui="tabs" />
<window_info id="UI Designer" active="false" anchor="left" auto_hide="false" internal_type="DOCKED" type="DOCKED" visible="false" show_stripe_button="true" weight="0.33" sideWeight="0.5" order="2" side_tool="false" content_ui="tabs" /> <window_info id="UI Designer" active="false" anchor="left" auto_hide="false" internal_type="DOCKED" type="DOCKED" visible="false" show_stripe_button="true" weight="0.33" sideWeight="0.5" order="2" side_tool="false" content_ui="tabs" />
<window_info id="Favorites" active="false" anchor="left" auto_hide="false" internal_type="DOCKED" type="DOCKED" visible="false" show_stripe_button="true" weight="0.33" sideWeight="0.5" order="4" side_tool="true" content_ui="tabs" /> <window_info id="Favorites" active="false" anchor="left" auto_hide="false" internal_type="DOCKED" type="DOCKED" visible="false" show_stripe_button="true" weight="0.33" sideWeight="0.5" order="4" side_tool="true" content_ui="tabs" />
<window_info id="Debug" active="false" anchor="bottom" auto_hide="false" internal_type="DOCKED" type="DOCKED" visible="true" show_stripe_button="true" weight="0.26007676" sideWeight="0.5" order="2" side_tool="false" content_ui="tabs" /> <window_info id="Debug" active="false" anchor="bottom" auto_hide="false" internal_type="DOCKED" type="DOCKED" visible="true" show_stripe_button="true" weight="0.25896862" sideWeight="0.5" order="2" side_tool="false" content_ui="tabs" />
<window_info id="Cvs" active="false" anchor="bottom" auto_hide="false" internal_type="DOCKED" type="DOCKED" visible="false" show_stripe_button="true" weight="0.25" sideWeight="0.5" order="4" side_tool="false" content_ui="tabs" /> <window_info id="Cvs" active="false" anchor="bottom" auto_hide="false" internal_type="DOCKED" type="DOCKED" visible="false" show_stripe_button="true" weight="0.25" sideWeight="0.5" order="4" side_tool="false" content_ui="tabs" />
<window_info id="Message" active="false" anchor="bottom" auto_hide="false" internal_type="DOCKED" type="DOCKED" visible="false" show_stripe_button="true" weight="0.33" sideWeight="0.5" order="0" side_tool="false" content_ui="tabs" /> <window_info id="Message" active="false" anchor="bottom" auto_hide="false" internal_type="DOCKED" type="DOCKED" visible="false" show_stripe_button="true" weight="0.33" sideWeight="0.5" order="0" side_tool="false" content_ui="tabs" />
<window_info id="Commander" active="false" anchor="right" auto_hide="false" internal_type="DOCKED" type="DOCKED" visible="false" show_stripe_button="true" weight="0.4" sideWeight="0.5" order="7" side_tool="false" content_ui="tabs" /> <window_info id="Commander" active="false" anchor="right" auto_hide="false" internal_type="DOCKED" type="DOCKED" visible="false" show_stripe_button="true" weight="0.4" sideWeight="0.5" order="7" side_tool="false" content_ui="tabs" />
@@ -434,6 +413,7 @@
<window_info id="Capture Analysis" active="false" anchor="right" auto_hide="false" internal_type="DOCKED" type="DOCKED" visible="false" show_stripe_button="true" weight="0.33" sideWeight="0.5" order="8" side_tool="false" content_ui="tabs" /> <window_info id="Capture Analysis" active="false" anchor="right" auto_hide="false" internal_type="DOCKED" type="DOCKED" visible="false" show_stripe_button="true" weight="0.33" sideWeight="0.5" order="8" side_tool="false" content_ui="tabs" />
<window_info id="Documentation" active="false" anchor="right" auto_hide="false" internal_type="DOCKED" type="DOCKED" visible="false" show_stripe_button="true" weight="0.1544196" sideWeight="0.4651163" order="10" side_tool="false" content_ui="tabs" x="1380" y="-157" width="1720" height="857" /> <window_info id="Documentation" active="false" anchor="right" auto_hide="false" internal_type="DOCKED" type="DOCKED" visible="false" show_stripe_button="true" weight="0.1544196" sideWeight="0.4651163" order="10" side_tool="false" content_ui="tabs" x="1380" y="-157" width="1720" height="857" />
<window_info id="Inspection" active="false" anchor="bottom" auto_hide="false" internal_type="DOCKED" type="DOCKED" visible="false" show_stripe_button="true" weight="0.4" sideWeight="0.5" order="6" side_tool="false" content_ui="tabs" /> <window_info id="Inspection" active="false" anchor="bottom" auto_hide="false" internal_type="DOCKED" type="DOCKED" visible="false" show_stripe_button="true" weight="0.4" sideWeight="0.5" order="6" side_tool="false" content_ui="tabs" />
<window_info id="Find" active="false" anchor="bottom" auto_hide="false" internal_type="DOCKED" type="DOCKED" visible="false" show_stripe_button="true" weight="0.33" sideWeight="0.5" order="3" side_tool="false" content_ui="tabs" />
<window_info id="Gradle" active="false" anchor="right" auto_hide="false" internal_type="DOCKED" type="DOCKED" visible="false" show_stripe_button="true" weight="0.33" sideWeight="0.5" order="0" side_tool="false" content_ui="tabs" /> <window_info id="Gradle" active="false" anchor="right" auto_hide="false" internal_type="DOCKED" type="DOCKED" visible="false" show_stripe_button="true" weight="0.33" sideWeight="0.5" order="0" side_tool="false" content_ui="tabs" />
</layout> </layout>
</component> </component>
@@ -449,35 +429,19 @@
<option name="FILTER_TARGETS" value="false" /> <option name="FILTER_TARGETS" value="false" />
</component> </component>
<component name="editorHistoryManager"> <component name="editorHistoryManager">
<entry file="file://$PROJECT_DIR$/text.txt"> <entry file="file://$PROJECT_DIR$/src/net/torvald/terrarum/imagefont/GameFontDemo.kt">
<provider selected="true" editor-type-id="text-editor"> <provider selected="true" editor-type-id="text-editor">
<state relative-caret-position="0"> <state relative-caret-position="0">
<caret line="0" column="95" lean-forward="false" selection-start-line="0" selection-start-column="95" selection-end-line="0" selection-end-column="95" /> <caret line="0" column="0" lean-forward="false" selection-start-line="0" selection-start-column="0" selection-end-line="0" selection-end-column="0" />
<folding />
</state>
</provider>
</entry>
<entry file="file://$PROJECT_DIR$/src/net/torvald/terrarum/imagefont/GameFontImpl.kt">
<provider selected="true" editor-type-id="text-editor">
<state relative-caret-position="190">
<caret line="29" column="0" lean-forward="false" selection-start-line="29" selection-start-column="0" selection-end-line="29" selection-end-column="0" />
<folding> <folding>
<element signature="e#31#108#0" expanded="true" /> <element signature="e#40#238#0" expanded="true" />
</folding> </folding>
</state> </state>
</provider> </provider>
</entry> </entry>
<entry file="file://$PROJECT_DIR$/META-INF/MANIFEST.MF">
<provider selected="true" editor-type-id="text-editor">
<state relative-caret-position="28">
<caret line="2" column="57" lean-forward="true" selection-start-line="2" selection-start-column="57" selection-end-line="2" selection-end-column="57" />
<folding />
</state>
</provider>
</entry>
<entry file="file://$PROJECT_DIR$/src/net/torvald/terrarum/imagefont/GameFontBase.kt"> <entry file="file://$PROJECT_DIR$/src/net/torvald/terrarum/imagefont/GameFontBase.kt">
<provider selected="true" editor-type-id="text-editor"> <provider selected="true" editor-type-id="text-editor">
<state relative-caret-position="400"> <state relative-caret-position="7168">
<caret line="516" column="36" lean-forward="false" selection-start-line="516" selection-start-column="36" selection-end-line="516" selection-end-column="36" /> <caret line="516" column="36" lean-forward="false" selection-start-line="516" selection-start-column="36" selection-end-line="516" selection-end-column="36" />
<folding> <folding>
<element signature="e#31#171#0" expanded="true" /> <element signature="e#31#171#0" expanded="true" />
@@ -485,14 +449,6 @@
</state> </state>
</provider> </provider>
</entry> </entry>
<entry file="file://$PROJECT_DIR$/../../Ba-AA/src/net/torvald/aa/demoplayer/BaAA.java">
<provider selected="true" editor-type-id="text-editor">
<state relative-caret-position="273">
<caret line="428" column="8" lean-forward="false" selection-start-line="428" selection-start-column="8" selection-end-line="429" selection-end-column="87" />
<folding />
</state>
</provider>
</entry>
<entry file="file://$PROJECT_DIR$/config.properties"> <entry file="file://$PROJECT_DIR$/config.properties">
<provider selected="true" editor-type-id="text-editor"> <provider selected="true" editor-type-id="text-editor">
<state relative-caret-position="0"> <state relative-caret-position="0">
@@ -501,6 +457,38 @@
</state> </state>
</provider> </provider>
</entry> </entry>
<entry file="file://$PROJECT_DIR$/text.txt">
<provider selected="true" editor-type-id="text-editor">
<state relative-caret-position="0">
<caret line="0" column="95" lean-forward="false" selection-start-line="0" selection-start-column="95" selection-end-line="0" selection-end-column="95" />
<folding />
</state>
</provider>
</entry>
<entry file="file://$PROJECT_DIR$/src/net/torvald/terrarum/imagefont/GameFontImpl.kt">
<provider selected="true" editor-type-id="text-editor">
<state relative-caret-position="392">
<caret line="29" column="0" lean-forward="false" selection-start-line="29" selection-start-column="0" selection-end-line="29" selection-end-column="0" />
<folding>
<element signature="e#31#108#0" expanded="true" />
</folding>
</state>
</provider>
</entry>
<entry file="file://$PROJECT_DIR$/META-INF/MANIFEST.MF">
<provider selected="true" editor-type-id="text-editor">
<state relative-caret-position="28">
<caret line="2" column="57" lean-forward="true" selection-start-line="2" selection-start-column="57" selection-end-line="2" selection-end-column="57" />
</state>
</provider>
</entry>
<entry file="file://$PROJECT_DIR$/../../Ba-AA/src/net/torvald/aa/demoplayer/BaAA.java">
<provider selected="true" editor-type-id="text-editor">
<state relative-caret-position="273">
<caret line="428" column="8" lean-forward="false" selection-start-line="428" selection-start-column="8" selection-end-line="429" selection-end-column="87" />
</state>
</provider>
</entry>
<entry file="file://$PROJECT_DIR$/src/net/torvald/terrarum/imagefont/GameFontDemo.kt"> <entry file="file://$PROJECT_DIR$/src/net/torvald/terrarum/imagefont/GameFontDemo.kt">
<provider selected="true" editor-type-id="text-editor"> <provider selected="true" editor-type-id="text-editor">
<state relative-caret-position="610"> <state relative-caret-position="610">
@@ -511,6 +499,42 @@
</state> </state>
</provider> </provider>
</entry> </entry>
<entry file="file://$PROJECT_DIR$/config.properties">
<provider selected="true" editor-type-id="text-editor">
<state relative-caret-position="0">
<caret line="0" column="10" lean-forward="false" selection-start-line="0" selection-start-column="10" selection-end-line="0" selection-end-column="10" />
<folding />
</state>
</provider>
</entry>
<entry file="file://$PROJECT_DIR$/src/net/torvald/terrarum/imagefont/GameFontBase.kt">
<provider selected="true" editor-type-id="text-editor">
<state relative-caret-position="202">
<caret line="493" column="0" lean-forward="false" selection-start-line="493" selection-start-column="0" selection-end-line="493" selection-end-column="0" />
<folding>
<element signature="e#31#171#0" expanded="true" />
</folding>
</state>
</provider>
</entry>
<entry file="file://$PROJECT_DIR$/text.txt">
<provider selected="true" editor-type-id="text-editor">
<state relative-caret-position="84">
<caret line="6" column="0" lean-forward="true" selection-start-line="6" selection-start-column="0" selection-end-line="6" selection-end-column="0" />
<folding />
</state>
</provider>
</entry>
<entry file="file://$PROJECT_DIR$/src/net/torvald/terrarum/imagefont/GameFontImpl.kt">
<provider selected="true" editor-type-id="text-editor">
<state relative-caret-position="356">
<caret line="48" column="26" lean-forward="false" selection-start-line="48" selection-start-column="26" selection-end-line="48" selection-end-column="26" />
<folding>
<element signature="e#31#108#0" expanded="true" />
</folding>
</state>
</provider>
</entry>
</component> </component>
<component name="masterDetails"> <component name="masterDetails">
<states> <states>

View File

@@ -56,7 +56,9 @@ open class GameFontBase : Font {
private fun isHangul(c: Char) = c.toInt() >= 0xAC00 && c.toInt() < 0xD7A4 private fun isHangul(c: Char) = c.toInt() >= 0xAC00 && c.toInt() < 0xD7A4
private fun isAscii(c: Char) = c.toInt() >= 0x20 && c.toInt() <= 0xFF private fun isAscii(c: Char) = c.toInt() >= 0x20 && c.toInt() <= 0xFF
private fun isRunic(c: Char) = runicList.contains(c)
private fun isExtA(c: Char) = c.toInt() >= 0x100 && c.toInt() < 0x180 private fun isExtA(c: Char) = c.toInt() >= 0x100 && c.toInt() < 0x180
private fun isExtB(c: Char) = c.toInt() >= 0x180 && c.toInt() < 0x250
private fun isKana(c: Char) = c.toInt() >= 0x3040 && c.toInt() < 0x3100 private fun isKana(c: Char) = c.toInt() >= 0x3040 && c.toInt() < 0x3100
private fun isCJKPunct(c: Char) = c.toInt() >= 0x3000 && c.toInt() < 0x3040 private fun isCJKPunct(c: Char) = c.toInt() >= 0x3000 && c.toInt() < 0x3040
private fun isUniHan(c: Char) = c.toInt() >= 0x3400 && c.toInt() < 0xA000 private fun isUniHan(c: Char) = c.toInt() >= 0x3400 && c.toInt() < 0xA000
@@ -66,14 +68,18 @@ open class GameFontBase : Font {
private fun isWenQuanYi1(c: Char) = c.toInt() >= 0x33F3 && c.toInt() <= 0x69FC private fun isWenQuanYi1(c: Char) = c.toInt() >= 0x33F3 && c.toInt() <= 0x69FC
private fun isWenQuanYi2(c: Char) = c.toInt() >= 0x69FD && c.toInt() <= 0x9FDC private fun isWenQuanYi2(c: Char) = c.toInt() >= 0x69FD && c.toInt() <= 0x9FDC
private fun isGreek(c: Char) = c.toInt() >= 0x370 && c.toInt() <= 0x3CE private fun isGreek(c: Char) = c.toInt() >= 0x370 && c.toInt() <= 0x3CE
private fun isRomanian(c: Char) = c.toInt() >= 0x218 && c.toInt() <= 0x21A
private fun isRomanianNarrow(c: Char) = c.toInt() == 0x21B
private fun extAindexX(c: Char) = (c.toInt() - 0x100) % 16 private fun extAindexX(c: Char) = (c.toInt() - 0x100) % 16
private fun extAindexY(c: Char) = (c.toInt() - 0x100) / 16 private fun extAindexY(c: Char) = (c.toInt() - 0x100) / 16
private fun extBindexX(c: Char) = (c.toInt() - 0x180) % 16
private fun extBindexY(c: Char) = (c.toInt() - 0x180) / 16
private fun runicIndexX(c: Char) = runicList.indexOf(c) % 16
private fun runicIndexY(c: Char) = runicList.indexOf(c) / 16
private fun kanaIndexX(c: Char) = (c.toInt() - 0x3040) % 16 private fun kanaIndexX(c: Char) = (c.toInt() - 0x3040) % 16
private fun kanaIndexY(c: Char) = (c.toInt() - 0x3040) / 16 private fun kanaIndexY(c: Char) = (c.toInt() - 0x3040) / 16
@@ -100,19 +106,6 @@ open class GameFontBase : Font {
private fun greekIndexX(c: Char) = (c.toInt() - 0x370) % 16 private fun greekIndexX(c: Char) = (c.toInt() - 0x370) % 16
private fun greekIndexY(c: Char) = (c.toInt() - 0x370) / 16 private fun greekIndexY(c: Char) = (c.toInt() - 0x370) / 16
private fun romanianIndexX(c: Char) = c.toInt() - 0x218
private fun romanianIndexY(c: Char) = 0
private fun thaiIndexX(c: Char) = (c.toInt() - 0xE00) % 16
private fun thaiIndexY(c: Char) = (c.toInt() - 0xE00) / 16
private fun thaiNarrowIndexX(c: Char) = 3
private fun thaiNarrowIndexY(c: Char) = 0
private val narrowWidthSheets = arrayOf(
SHEET_EXTB_ROMANIAN_NARROW
)
private val unihanWidthSheets = arrayOf( private val unihanWidthSheets = arrayOf(
SHEET_UNIHAN, SHEET_UNIHAN,
SHEET_FW_UNI, SHEET_FW_UNI,
@@ -126,7 +119,8 @@ open class GameFontBase : Font {
SHEET_ASCII_VARW, SHEET_ASCII_VARW,
SHEET_CYRILIC_VARW, SHEET_CYRILIC_VARW,
SHEET_EXTA_VARW, SHEET_EXTA_VARW,
SHEET_GREEK_VARW SHEET_GREEK_VARW,
SHEET_EXTB_VARW
) )
@@ -151,8 +145,6 @@ open class GameFontBase : Font {
} }
else if (zeroWidthSheets.contains(ctype)) else if (zeroWidthSheets.contains(ctype))
len += 0 len += 0
else if (narrowWidthSheets.contains(ctype))
len += W_LATIN_NARROW
else if (ctype == SHEET_CJK_PUNCT) else if (ctype == SHEET_CJK_PUNCT)
len += W_ASIAN_PUNCT len += W_ASIAN_PUNCT
else if (ctype == SHEET_HANGUL) else if (ctype == SHEET_HANGUL)
@@ -188,6 +180,11 @@ open class GameFontBase : Font {
for (i in 0..s.length - 1) { for (i in 0..s.length - 1) {
val ch = s[i] val ch = s[i]
if (ch.isColourCode()) {
thisCol = colourKey[ch]!!
continue
}
if (isHangul(ch)) { if (isHangul(ch)) {
val hIndex = ch.toInt() - 0xAC00 val hIndex = ch.toInt() - 0xAC00
@@ -246,6 +243,11 @@ open class GameFontBase : Font {
for (i in 0..s.length - 1) { for (i in 0..s.length - 1) {
val ch = s[i] val ch = s[i]
if (ch.isColourCode()) {
thisCol = colourKey[ch]!!
continue
}
if (isWenQuanYi1(ch)) { if (isWenQuanYi1(ch)) {
val glyphW = getWidth("" + ch) val glyphW = getWidth("" + ch)
wenQuanYi_1.getSubImage(wenQuanYiIndexX(ch), wenQuanYi1IndexY(ch)).drawWithShadow( wenQuanYi_1.getSubImage(wenQuanYiIndexX(ch), wenQuanYi1IndexY(ch)).drawWithShadow(
@@ -263,6 +265,11 @@ open class GameFontBase : Font {
for (i in 0..s.length - 1) { for (i in 0..s.length - 1) {
val ch = s[i] val ch = s[i]
if (ch.isColourCode()) {
thisCol = colourKey[ch]!!
continue
}
if (isWenQuanYi2(ch)) { if (isWenQuanYi2(ch)) {
val glyphW = getWidth("" + ch) val glyphW = getWidth("" + ch)
wenQuanYi_2.getSubImage(wenQuanYiIndexX(ch), wenQuanYi2IndexY(ch)).drawWithShadow( wenQuanYi_2.getSubImage(wenQuanYiIndexX(ch), wenQuanYi2IndexY(ch)).drawWithShadow(
@@ -280,6 +287,11 @@ open class GameFontBase : Font {
for (i in 0..s.length - 1) { for (i in 0..s.length - 1) {
val ch = s[i] val ch = s[i]
if (ch.isColourCode()) {
thisCol = colourKey[ch]!!
continue
}
if (!isHangul(ch) && !isUniHan(ch)) { if (!isHangul(ch) && !isUniHan(ch)) {
// if not init, endUse first // if not init, endUse first
@@ -296,6 +308,10 @@ open class GameFontBase : Font {
sheetX = extAindexX(ch) sheetX = extAindexX(ch)
sheetY = extAindexY(ch) sheetY = extAindexY(ch)
} }
SHEET_EXTB_VARW -> {
sheetX = extBindexX(ch)
sheetY = extBindexY(ch)
}
SHEET_KANA -> { SHEET_KANA -> {
sheetX = kanaIndexX(ch) sheetX = kanaIndexX(ch)
sheetY = kanaIndexY(ch) sheetY = kanaIndexY(ch)
@@ -320,14 +336,6 @@ open class GameFontBase : Font {
sheetX = greekIndexX(ch) sheetX = greekIndexX(ch)
sheetY = greekIndexY(ch) sheetY = greekIndexY(ch)
} }
SHEET_EXTB_ROMANIAN_WIDE -> {
sheetX = romanianIndexX(ch)
sheetY = romanianIndexY(ch)
}
SHEET_EXTB_ROMANIAN_NARROW -> {
sheetX = 0
sheetY = 0
}
else -> { else -> {
sheetX = ch.toInt() % 16 sheetX = ch.toInt() % 16
sheetY = ch.toInt() / 16 sheetY = ch.toInt() / 16
@@ -365,10 +373,7 @@ open class GameFontBase : Font {
} }
private fun getSheetType(c: Char): Int { private fun getSheetType(c: Char): Int {
// EFs if (isHangul(c))
if (isRomanianNarrow(c))
return SHEET_EXTB_ROMANIAN_NARROW
else if (isHangul(c))
return SHEET_HANGUL return SHEET_HANGUL
else if (isKana(c)) else if (isKana(c))
return SHEET_KANA return SHEET_KANA
@@ -378,6 +383,8 @@ open class GameFontBase : Font {
return SHEET_ASCII_VARW return SHEET_ASCII_VARW
else if (isExtA(c)) else if (isExtA(c))
return SHEET_EXTA_VARW return SHEET_EXTA_VARW
else if (isExtB(c))
return SHEET_EXTB_VARW
else if (isCyrilic(c)) else if (isCyrilic(c))
return SHEET_CYRILIC_VARW return SHEET_CYRILIC_VARW
else if (isUniPunct(c)) else if (isUniPunct(c))
@@ -388,8 +395,8 @@ open class GameFontBase : Font {
return SHEET_FW_UNI return SHEET_FW_UNI
else if (isGreek(c)) else if (isGreek(c))
return SHEET_GREEK_VARW return SHEET_GREEK_VARW
else if (isRomanian(c)) else if (c.isColourCode())
return SHEET_EXTB_ROMANIAN_WIDE return SHEET_COLOURCODE
else else
return SHEET_UNKNOWN// fixed width punctuations return SHEET_UNKNOWN// fixed width punctuations
// fixed width // fixed width
@@ -418,6 +425,8 @@ open class GameFontBase : Font {
drawString(x + xoff, y, printedBody, color) drawString(x + xoff, y, printedBody, color)
} }
fun Char.isColourCode() = colourKey.containsKey(this)
fun buildWidthTable(sheet: SpriteSheet, codeOffset: Int, codeRange: IntRange, rows: Int = 16) { fun buildWidthTable(sheet: SpriteSheet, codeOffset: Int, codeRange: IntRange, rows: Int = 16) {
fun Byte.toUint() = java.lang.Byte.toUnsignedInt(this) fun Byte.toUint() = java.lang.Byte.toUnsignedInt(this)
@@ -483,6 +492,7 @@ open class GameFontBase : Font {
internal val asciiWidths: HashMap<Int, Int> = HashMap() internal val asciiWidths: HashMap<Int, Int> = HashMap()
lateinit internal var extASheet: SpriteSheet lateinit internal var extASheet: SpriteSheet
lateinit internal var extBSheet: SpriteSheet
lateinit internal var kanaSheet: SpriteSheet lateinit internal var kanaSheet: SpriteSheet
lateinit internal var cjkPunct: SpriteSheet lateinit internal var cjkPunct: SpriteSheet
// static SpriteSheet uniHan; // static SpriteSheet uniHan;
@@ -492,8 +502,6 @@ open class GameFontBase : Font {
lateinit internal var wenQuanYi_1: SpriteSheet lateinit internal var wenQuanYi_1: SpriteSheet
lateinit internal var wenQuanYi_2: SpriteSheet lateinit internal var wenQuanYi_2: SpriteSheet
lateinit internal var greekSheet: SpriteSheet lateinit internal var greekSheet: SpriteSheet
lateinit internal var romanianSheet: SpriteSheet
lateinit internal var romanianSheetNarrow: SpriteSheet
internal val JUNG_COUNT = 21 internal val JUNG_COUNT = 21
internal val JONG_COUNT = 28 internal val JONG_COUNT = 28
@@ -502,8 +510,7 @@ open class GameFontBase : Font {
internal val W_HANGUL = 11 internal val W_HANGUL = 11
internal val W_KANA = 12 internal val W_KANA = 12
internal val W_UNIHAN = 16 internal val W_UNIHAN = 16
internal val W_LATIN_WIDE = 9 // width of regular letters, including m internal val W_LATIN_WIDE = 9 // width of regular letters
internal val W_LATIN_NARROW = 5 // width of letter f, t, i, l
internal val H = 20 internal val H = 20
internal val H_HANGUL = 16 internal val H_HANGUL = 16
@@ -512,24 +519,42 @@ open class GameFontBase : Font {
internal val SHEET_ASCII_VARW = 0 internal val SHEET_ASCII_VARW = 0
internal val SHEET_HANGUL = 1 internal val SHEET_HANGUL = 1
internal val SHEET_EXTA_VARW = 2 internal val SHEET_EXTA_VARW = 3
internal val SHEET_KANA = 3 internal val SHEET_EXTB_VARW = 4
internal val SHEET_CJK_PUNCT = 4 internal val SHEET_KANA = 5
internal val SHEET_UNIHAN = 5 internal val SHEET_CJK_PUNCT = 6
internal val SHEET_CYRILIC_VARW = 6 internal val SHEET_UNIHAN = 7
internal val SHEET_FW_UNI = 7 internal val SHEET_CYRILIC_VARW = 8
internal val SHEET_UNI_PUNCT = 8 internal val SHEET_FW_UNI = 9
internal val SHEET_WENQUANYI_1 = 9 internal val SHEET_UNI_PUNCT = 10
internal val SHEET_WENQUANYI_2 = 10 internal val SHEET_WENQUANYI_1 = 11
internal val SHEET_GREEK_VARW = 11 internal val SHEET_WENQUANYI_2 = 12
internal val SHEET_EXTB_ROMANIAN_WIDE = 12 internal val SHEET_GREEK_VARW = 13
internal val SHEET_EXTB_ROMANIAN_NARROW = 13
internal val SHEET_UNKNOWN = 254 internal val SHEET_UNKNOWN = 254
internal val SHEET_COLOURCODE = 255 internal val SHEET_COLOURCODE = 255
lateinit internal var sheetKey: Array<SpriteSheet?> lateinit internal var sheetKey: Array<SpriteSheet?>
/**
* Runic letters list used for game. The set is
* Younger Futhark + Medieval rune 'e' + Punct + Runic Almanac
* BEWARE OF SIMILAR-LOOKING RUNES, especially:
* * Algiz ᛉ instead of Maðr ᛘ
* * Short-Twig Hagall ᚽ instead of Runic Letter E ᛂ
* * Runic Letter OE ᚯ instead of Óss ᚬ
* Examples:
* ᛭ᛋᛁᚴᚱᛁᚦᛦ᛭
* ᛭ᛂᛚᛋᛅ᛭ᛏᚱᚢᛏᚾᛁᚾᚴᚢᚾᛅ᛬ᛅᚱᚾᛅᛏᛅᛚᛋ
*/
internal val runicList = arrayOf('ᚠ', 'ᚢ', 'ᚦ', 'ᚬ', 'ᚱ', 'ᚴ', 'ᚼ', 'ᚾ', '', 'ᛅ', 'ᛋ', 'ᛏ', 'ᛒ', 'ᛘ', 'ᛚ', 'ᛦ', 'ᛂ', '', '᛫', '', 'ᛮ', 'ᛯ', 'ᛰ')
internal var interchar = 0 internal var interchar = 0
internal var scale = 1 internal var scale = 1
set(value) { set(value) {
@@ -537,6 +562,49 @@ open class GameFontBase : Font {
else throw IllegalArgumentException("Font scale cannot be zero or negative (input: $value)") else throw IllegalArgumentException("Font scale cannot be zero or negative (input: $value)")
} }
val colourKey = hashMapOf(
Pair(0x10.toChar(), Color(0xFFFFFF)), //*w hite
Pair(0x11.toChar(), Color(0xFFE080)), //*y ellow
Pair(0x12.toChar(), Color(0xFFB020)), //o range
Pair(0x13.toChar(), Color(0xFF8080)), //*r ed
Pair(0x14.toChar(), Color(0xFFA0E0)), //f uchsia
Pair(0x15.toChar(), Color(0xE0A0FF)), //*m agenta (purple)
Pair(0x16.toChar(), Color(0x8080FF)), //*b lue
Pair(0x17.toChar(), Color(0x80FFFF)), //c yan
Pair(0x18.toChar(), Color(0x80FF80)), //*g reen
Pair(0x19.toChar(), Color(0x008000)), //v iridian
Pair(0x1A.toChar(), Color(0x805030)), //x (khaki)
Pair(0x1B.toChar(), Color(0x808080)) //*k
//* marked: commonly used
)
val colToCode = hashMapOf(
Pair("w", 0x10.toChar()),
Pair("y", 0x11.toChar()),
Pair("o", 0x12.toChar()),
Pair("r", 0x13.toChar()),
Pair("f", 0x14.toChar()),
Pair("m", 0x15.toChar()),
Pair("b", 0x16.toChar()),
Pair("c", 0x17.toChar()),
Pair("g", 0x18.toChar()),
Pair("v", 0x19.toChar()),
Pair("x", 0x1A.toChar()),
Pair("k", 0x1B.toChar())
)
val codeToCol = hashMapOf(
Pair("w", colourKey[0x10.toChar()]),
Pair("y", colourKey[0x11.toChar()]),
Pair("o", colourKey[0x12.toChar()]),
Pair("r", colourKey[0x13.toChar()]),
Pair("f", colourKey[0x14.toChar()]),
Pair("m", colourKey[0x15.toChar()]),
Pair("b", colourKey[0x16.toChar()]),
Pair("c", colourKey[0x17.toChar()]),
Pair("g", colourKey[0x18.toChar()]),
Pair("v", colourKey[0x19.toChar()]),
Pair("x", colourKey[0x1A.toChar()]),
Pair("k", colourKey[0x1B.toChar()])
)
}// end of companion object }// end of companion object
} }

View File

@@ -16,6 +16,8 @@ class GameFontImpl : GameFontBase() {
"./assets/graphics/fonts/ascii_variable.tga", 15, 19, 1) "./assets/graphics/fonts/ascii_variable.tga", 15, 19, 1)
GameFontBase.extASheet = SpriteSheet( GameFontBase.extASheet = SpriteSheet(
"./assets/graphics/fonts/LatinExtA_variable.tga", 15, 19, 1) "./assets/graphics/fonts/LatinExtA_variable.tga", 15, 19, 1)
GameFontBase.extBSheet = SpriteSheet(
"./assets/graphics/fonts/LatinExtB_variable.tga", 15, 19, 1)
GameFontBase.kanaSheet = SpriteSheet( GameFontBase.kanaSheet = SpriteSheet(
"./assets/graphics/fonts/kana.tga", GameFontBase.W_KANA, GameFontBase.H_KANA) "./assets/graphics/fonts/kana.tga", GameFontBase.W_KANA, GameFontBase.H_KANA)
GameFontBase.cjkPunct = SpriteSheet( GameFontBase.cjkPunct = SpriteSheet(
@@ -43,15 +45,13 @@ class GameFontImpl : GameFontBase() {
"./assets/graphics/fonts/wenquanyi_11pt_part2.tga", 16, 18, 2) "./assets/graphics/fonts/wenquanyi_11pt_part2.tga", 16, 18, 2)
GameFontBase.greekSheet = SpriteSheet( GameFontBase.greekSheet = SpriteSheet(
"./assets/graphics/fonts/greek_variable.tga", 15, 19, 1) "./assets/graphics/fonts/greek_variable.tga", 15, 19, 1)
GameFontBase.romanianSheet = SpriteSheet(
"./assets/graphics/fonts/romana_wide.tga", GameFontBase.W_LATIN_WIDE, GameFontBase.H)
GameFontBase.romanianSheetNarrow = SpriteSheet(
"./assets/graphics/fonts/romana_narrow.tga", GameFontBase.W_LATIN_NARROW, GameFontBase.H)
val shk = arrayOf( val shk = arrayOf(
GameFontBase.asciiSheet, GameFontBase.asciiSheet,
GameFontBase.hangulSheet, GameFontBase.hangulSheet,
null, // here was customised runic sheet
GameFontBase.extASheet, GameFontBase.extASheet,
GameFontBase.extBSheet,
GameFontBase.kanaSheet, GameFontBase.kanaSheet,
GameFontBase.cjkPunct, GameFontBase.cjkPunct,
null, // Full unihan, filler because we're using WenQuanYi null, // Full unihan, filler because we're using WenQuanYi
@@ -60,16 +60,24 @@ class GameFontImpl : GameFontBase() {
GameFontBase.uniPunct, GameFontBase.uniPunct,
GameFontBase.wenQuanYi_1, GameFontBase.wenQuanYi_1,
GameFontBase.wenQuanYi_2, GameFontBase.wenQuanYi_2,
GameFontBase.greekSheet, GameFontBase.greekSheet
GameFontBase.romanianSheet,
GameFontBase.romanianSheetNarrow
) )
GameFontBase.sheetKey = shk GameFontBase.sheetKey = shk
buildWidthTable(asciiSheet, 0, 0..0xFF) buildWidthTable(asciiSheet, 0, 0..0xFF)
buildWidthTable(extASheet, 0x100, 0..0x7F) buildWidthTable(extASheet, 0x100, 0..0x7F)
buildWidthTable(cyrilic, 0x400, 0..0x5F) buildWidthTable(extBSheet, 0x180, 0..0xCF)
buildWidthTable(cyrilic, 0x400, 0..0x5F)
buildWidthTable(greekSheet, 0x370, 0..0x5F) buildWidthTable(greekSheet, 0x370, 0..0x5F)
} }
fun reload() {
GameFontBase.cyrilic = SpriteSheet(
when (GameFontDemo.gameLocale.substring(0..1)) {
"bg" -> "./assets/graphics/fonts/cyrilic_bulgarian_variable.tga"
"sr" -> "./assets/graphics/fonts/cyrilic_serbian_variable.tga"
else -> "./assets/graphics/fonts/cyrilic_variable.tga"
}, 15, 19, 1)
}
} }

Binary file not shown.

Before

Width:  |  Height:  |  Size: 53 KiB

After

Width:  |  Height:  |  Size: 55 KiB

Binary file not shown.

Before

Width:  |  Height:  |  Size: 22 KiB

After

Width:  |  Height:  |  Size: 22 KiB