contribution guideline on separate md

This commit is contained in:
minjaesong
2018-08-01 08:55:19 +09:00
parent b3174171c4
commit ecac1dc8af
4 changed files with 169 additions and 162 deletions

92
.idea/workspace.xml generated
View File

@@ -7,12 +7,7 @@
</component>
<component name="ChangeListManager">
<list default="true" id="22c5bc80-996c-4846-b173-7dc8c2096fe3" name="Default" comment="">
<change afterPath="$PROJECT_DIR$/FontTestGDX/META-INF/MANIFEST.MF" afterDir="false" />
<change beforePath="$PROJECT_DIR$/.idea/artifacts/FontDemoGDX.xml" beforeDir="false" afterPath="$PROJECT_DIR$/.idea/artifacts/FontDemoGDX.xml" afterDir="false" />
<change beforePath="$PROJECT_DIR$/.idea/workspace.xml" beforeDir="false" afterPath="$PROJECT_DIR$/.idea/workspace.xml" afterDir="false" />
<change beforePath="$PROJECT_DIR$/FontTestGDX/demotext.txt" beforeDir="false" afterPath="$PROJECT_DIR$/FontTestGDX/demotext.txt" afterDir="false" />
<change beforePath="$PROJECT_DIR$/FontTestGDX/lib/TerrarumSansBitmap.jar" beforeDir="false" afterPath="$PROJECT_DIR$/FontTestGDX/lib/TerrarumSansBitmap.jar" afterDir="false" />
<change beforePath="$PROJECT_DIR$/demo.PNG" beforeDir="false" afterPath="$PROJECT_DIR$/demo.PNG" afterDir="false" />
</list>
<ignored path="$PROJECT_DIR$/out/" />
<option name="EXCLUDED_CONVERTED_TO_IGNORED" value="true" />
@@ -32,8 +27,8 @@
<file leaf-file-name="GameFontBase.kt" pinned="false" current-in-tab="true">
<entry file="file://$PROJECT_DIR$/src/net/torvald/terrarumsansbitmap/gdx/GameFontBase.kt">
<provider selected="true" editor-type-id="text-editor">
<state relative-caret-position="568">
<caret line="850" column="12" selection-start-line="850" selection-start-column="12" selection-end-line="850" selection-end-column="12" />
<state relative-caret-position="268">
<caret line="145" column="17" selection-start-line="145" selection-start-column="17" selection-end-line="145" selection-end-column="17" />
</state>
</provider>
</entry>
@@ -41,8 +36,8 @@
<file leaf-file-name="GameFontBase.kt" pinned="false" current-in-tab="false">
<entry file="file://$PROJECT_DIR$/src/net/torvald/terrarumsansbitmap/slick2d/GameFontBase.kt">
<provider selected="true" editor-type-id="text-editor">
<state relative-caret-position="153">
<caret line="523" column="48" selection-start-line="523" selection-start-column="48" selection-end-line="523" selection-end-column="48" />
<state relative-caret-position="3689">
<caret line="531" column="21" selection-start-line="531" selection-start-column="21" selection-end-line="531" selection-end-column="21" />
</state>
</provider>
</entry>
@@ -63,21 +58,30 @@
</provider>
</entry>
</file>
<file leaf-file-name="GameFontBase.kt" pinned="false" current-in-tab="true">
<file leaf-file-name="demotext.txt" pinned="false" current-in-tab="false">
<entry file="file://$PROJECT_DIR$/FontTestGDX/demotext.txt">
<provider selected="true" editor-type-id="text-editor">
<state>
<caret selection-end-line="1" selection-end-column="43" />
</state>
</provider>
</entry>
</file>
<file leaf-file-name="GameFontBase.kt" pinned="false" current-in-tab="false">
<entry file="file://$PROJECT_DIR$/src/net/torvald/terrarumsansbitmap/gdx/GameFontBase.kt">
<provider selected="true" editor-type-id="text-editor">
<state relative-caret-position="-242">
<state relative-caret-position="3211">
<caret line="277" column="5" selection-start-line="277" selection-start-column="5" selection-end-line="277" selection-end-column="5" />
</state>
</provider>
</entry>
</file>
<file leaf-file-name="README.md" pinned="false" current-in-tab="false">
<file leaf-file-name="README.md" pinned="false" current-in-tab="true">
<entry file="file://$PROJECT_DIR$/README.md">
<provider selected="true" editor-type-id="split-provider[text-editor;MarkdownPreviewEditor]">
<state split_layout="FIRST">
<first_editor relative-caret-position="631">
<caret line="241" column="171" selection-start-line="241" selection-start-column="171" selection-end-line="241" selection-end-column="171" />
<state split_layout="SECOND">
<first_editor relative-caret-position="273">
<caret line="11" column="153" selection-start-line="11" selection-start-column="153" selection-end-line="11" selection-end-column="153" />
</first_editor>
<second_editor>
<js_state />
@@ -113,7 +117,6 @@
<find>ө</find>
<find>ď</find>
<find>ñ</find>
<find>fun relo</find>
<find>getSheetT</find>
<find>Unexpected</find>
<find>Unexp</find>
@@ -122,6 +125,7 @@
<find>isHangul</find>
<find></find>
<find>toColo</find>
<find>fun relo</find>
</findStrings>
<replaceStrings>
<replace>.141</replace>
@@ -138,15 +142,15 @@
<option value="$PROJECT_DIR$/src/net/torvald/terrarumsansbitmap/testbed/FontTest.kt" />
<option value="$PROJECT_DIR$/src/net/torvald/terrarumsansbitmap/testbed/FontTestGDX.kt" />
<option value="$PROJECT_DIR$/LICENSE.md" />
<option value="$PROJECT_DIR$/README.md" />
<option value="$PROJECT_DIR$/src/net/torvald/terrarumsansbitmap/slick2d/GameFontBase.kt" />
<option value="$PROJECT_DIR$/src/net/torvald/terrarumsansbitmap/gdx/GameFontBase.kt" />
<option value="$PROJECT_DIR$/FontTestGDX/src/FontTestGDX.kt" />
<option value="$PROJECT_DIR$/FontTestGDX/demotext.txt" />
<option value="$PROJECT_DIR$/README.md" />
</list>
</option>
</component>
<component name="ProjectFrameBounds" extendedState="6">
<component name="ProjectFrameBounds" extendedState="7">
<option name="x" value="1912" />
<option name="y" value="-521" />
<option name="width" value="1936" />
@@ -416,7 +420,7 @@
</todo-panel>
</component>
<component name="ToolWindowManager">
<frame x="1912" y="-521" width="1936" height="1176" extended-state="6" />
<frame x="1912" y="-521" width="1936" height="1176" extended-state="7" />
<editor active="true" />
<layout>
<window_info anchor="right" id="Palette" order="3" />
@@ -429,11 +433,11 @@
<window_info anchor="bottom" id="Version Control" order="7" />
<window_info anchor="bottom" id="Terminal" order="7" />
<window_info id="Designer" order="2" />
<window_info content_ui="combo" id="Project" order="0" visible="true" weight="0.12953092" />
<window_info active="true" content_ui="combo" id="Project" order="0" visible="true" weight="0.12953092" />
<window_info id="Structure" order="1" side_tool="true" weight="0.25" />
<window_info anchor="right" id="Ant Build" order="1" weight="0.25" />
<window_info id="UI Designer" order="2" />
<window_info active="true" anchor="bottom" id="Debug" order="3" visible="true" weight="0.23025048" />
<window_info anchor="bottom" id="Debug" order="3" visible="true" weight="0.23025048" />
<window_info id="Favorites" order="2" side_tool="true" />
<window_info anchor="right" content_ui="combo" id="Hierarchy" order="2" weight="0.25" />
<window_info anchor="bottom" id="Inspection" order="5" weight="0.4" />
@@ -654,28 +658,9 @@
</state>
</provider>
</entry>
<entry file="file://$PROJECT_DIR$/src/net/torvald/terrarumsansbitmap/slick2d/GameFontBase.kt">
<provider selected="true" editor-type-id="text-editor">
<state relative-caret-position="153">
<caret line="523" column="48" selection-start-line="523" selection-start-column="48" selection-end-line="523" selection-end-column="48" />
</state>
</provider>
</entry>
<entry file="file://$USER_HOME$/AppData/Local/Temp/Ихадоу адаҟьа.URL">
<provider selected="true" editor-type-id="text-editor" />
</entry>
<entry file="file://$PROJECT_DIR$/README.md">
<provider selected="true" editor-type-id="split-provider[text-editor;MarkdownPreviewEditor]">
<state split_layout="FIRST">
<first_editor relative-caret-position="631">
<caret line="241" column="171" selection-start-line="241" selection-start-column="171" selection-end-line="241" selection-end-column="171" />
</first_editor>
<second_editor>
<js_state />
</second_editor>
</state>
</provider>
</entry>
<entry file="jar://$PROJECT_DIR$/FontTestGDX/lib/TerrarumSansBitmap.jar!/net/torvald/terrarumsansbitmap/gdx/GameFontBase.class">
<provider selected="true" editor-type-id="text-editor">
<state relative-caret-position="513">
@@ -695,15 +680,34 @@
</entry>
<entry file="file://$PROJECT_DIR$/FontTestGDX/demotext.txt">
<provider selected="true" editor-type-id="text-editor">
<state relative-caret-position="299">
<caret line="23" lean-forward="true" selection-start-line="23" selection-end-line="23" />
<state>
<caret selection-end-line="1" selection-end-column="43" />
</state>
</provider>
</entry>
<entry file="file://$PROJECT_DIR$/src/net/torvald/terrarumsansbitmap/slick2d/GameFontBase.kt">
<provider selected="true" editor-type-id="text-editor">
<state relative-caret-position="3689">
<caret line="531" column="21" selection-start-line="531" selection-start-column="21" selection-end-line="531" selection-end-column="21" />
</state>
</provider>
</entry>
<entry file="file://$PROJECT_DIR$/README.md">
<provider selected="true" editor-type-id="split-provider[text-editor;MarkdownPreviewEditor]">
<state split_layout="SECOND">
<first_editor relative-caret-position="273">
<caret line="11" column="153" selection-start-line="11" selection-start-column="153" selection-end-line="11" selection-end-column="153" />
</first_editor>
<second_editor>
<js_state />
</second_editor>
</state>
</provider>
</entry>
<entry file="file://$PROJECT_DIR$/src/net/torvald/terrarumsansbitmap/gdx/GameFontBase.kt">
<provider selected="true" editor-type-id="text-editor">
<state relative-caret-position="-242">
<caret line="277" column="5" selection-start-line="277" selection-start-column="5" selection-end-line="277" selection-end-column="5" />
<state relative-caret-position="268">
<caret line="145" column="17" selection-start-line="145" selection-start-column="17" selection-end-line="145" selection-end-column="17" />
</state>
</provider>
</entry>

117
CONTRIBUTING.md Normal file
View File

@@ -0,0 +1,117 @@
You can contribute to the font by fixing wrong glyphs, suggesting better ones, extending character set (letters for other writing systems or filling in the blanks on the existing ones), or code for other game frameworks (not limited to Java). Please leave pull request for that.
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.
#### Before getting started, you did read our design goals, right? Good. Now you may continue your awesome work.
### Ascenders, descenders, width informations
![Alas, use more modern browser or get better internet connexion!](glyph_height_pos_annotation.png)
Above image is a reference you can use while you draw some letters. Capital B is drawn as a reference. Orange-tinted area is for lowercase, x-height must be the same as that of said tinted area (lowercase Alpha is also drawn for the reference). NOTE THAT x-height is taller than centre bar (capital A is an exception). Height of the ascender of the lowercase letters must be the same as height of capital letters.
Red-tinted area SHOULD NOT CONTAIN any dots, it's emptied for compatibility. (Slick2d—you can define size of "gaps" of the spritesheet, but you can't define horizontal and vertical gap separately)
Blue-tinted area cotains width of the glyph in binary, uppermost dot is the Least Significant Bit.
Green-tinted area contains extra informations, left blank for most cases. (will be expanded later; no standard has been issued yet)
Tinted-in-magenta shows the height where diacritics should be placed, for both uppercase and lowercase.
Each cell is 16 px wide, and any glyph you draw **must be contained within leftside FIFTEEN pixels**.
### Font metrics
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``` and ```hangul_johab``` has width of 12, ```wenquanyi``` has width of 16.
### Parsing glyph widths for variable font sheets
![Sample of Font Spritesheet with annotation](width_bit_encoding_annotated.png)
Width is encoded in binary bits, on pixels. On the font spritesheet, every glyph has vertical dots on their top-right side (to be exact, every (16k - 1)th pixel on x axis). Above image is a sample of the font, with width information coloured in magenta. From top to bottom, each dot represents 1, 2, 4 and 8. For example, in the above image, ! (exclamation mark) has width of 5, " (double quote) has width of 6, # (octothorp) has width of 8, $ (dollar sign) has width of 9.
### Implementing the Korean writing system
On this font, Hangul letters are printed by assemblying two or three letter pieces. There are 10 sets of Hangul letter pieces on the font. Top 6 are initials, middle 2 are medials, and bottom 2 are finals. On the rightmost side, there's eight assembled glyphs to help you with (assuming you have basic knowledge on the writing system). Top 6 tells you how to use 6 initials, and bottom 2 tells you how to use 2 finals.
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)
jungseongComplex = arrayOf(9, 10, 11, 14, 15, 16, 22)
function 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
}
function isJungseongWide(hanIndex: Int) = jungseongWide.contains(getHanJungseong(hanIndex))
function isJungseongComplex(hanIndex: Int) = jungseongComplex.contains(getHanJungseong(hanIndex))
function 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
}
function getHanMedialRow(hanIndex: Int) = if (getHanJongseong(hanIndex) == 0) 6 else 7
function getHanFinalRow(hanIndex: Int): Int {
val jungseongIndex = getHanJungseong(hanIndex)
return if (jungseongWide.contains(jungseongIndex))
8
else
9
}
function isHangul(c: Char) = c.toInt() >= 0xAC00 && c.toInt() < 0xD7A4
...
for (each Char on the string) {
if (isHangul(Char)) {
val hIndex = Char.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)
// get sub image from sprite sheet
val choseongImage = hangulSheet.getSubImage(indexCho, choRow)
val jungseongImage = hangulSheet.getSubImage(indexJung, jungRow)
val jongseongImage = hangulSheet.getSubImage(indexJong, jongRow)
// actual drawing part
draw choseongImage to somewhere you want
draw jungseongImage on top of choseongImage
draw jongseongImage on top of choseongImage
}
...
}

122
README.md
View File

@@ -107,133 +107,19 @@ On your code (Java):
Color codes are individual unicode characters. While you can somehow make a raw character and paste in on your code, it's certainly not desirable. Fortunately, we're also providing utility functions for the color codes.
GameFontBase.toColorCode(rgba4444: Int) -- returns String
GameFontBase.toColorCode(argb4444: Int) -- returns String
GameFontBase.toColorCode(r: Int, g: Int, b: Int) -- returns String
GameFontBase.toColorCode(r: Int, g: Int, b: Int, a: Int) -- returns String
```rgba4444``` takes whole RGBA as input, that is, from 0x0000 to 0xFFFF. Most significant bits represents Red, and least significant bits represents Alpha (which should be fixed as F for the most time)
```argb4444``` takes whole ARGB (in that order) as input, that is, from 0x0000 to 0xFFFF.
```r, g, b(, a)``` takes RGB and A separately, in the range of 0x0..0xF. Any value exceeding the range **are unchecked and may wreak havoc**, so be careful.
U+100000 is used to disable previously-applied color codes (going back to original colour), although it may seem like RGBA of all zero.
U+100000 is used to disable previously-applied color codes (going back to original colour), even if it looks like ARGB of all zero.
## Contribution guidelines
You can contribute to the font by fixing wrong glyphs, suggesting better ones, extending character set (letters for other writing systems or filling in the blanks on the existing ones), or code for other game frameworks (not limited to Java). Please leave pull request for that.
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.
### Ascenders, descenders, width informations
![Alas, use more modern browser or get better internet connexion!](glyph_height_pos_annotation.png)
Above image is a reference you can use while you draw some letters. Capital B is drawn as a reference. Orange-tinted area is for lowercase, x-height must be the same as that of said tinted area (lowercase Alpha is also drawn for the reference). NOTE THAT x-height is taller than centre bar (capital A is an exception). Height of the ascender of the lowercase letters must be the same as height of capital letters.
Red-tinted area SHOULD NOT CONTAIN any dots, it's emptied for compatibility. (Slick2d—you can define size of "gaps" of the spritesheet, but you can't define horizontal and vertical gap separately)
Blue-tinted area cotains width of the glyph in binary, uppermost dot is the Least Significant Bit.
Green-tinted area contains extra informations, left blank for most cases. (will be expanded later; no standard has been issued yet)
Tinted-in-magenta shows the height where diacritics should be placed, for both uppercase and lowercase.
Each cell is 16 px wide, and any glyph you draw **must be contained within leftside FIFTEEN pixels**.
### Font metrics
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``` and ```hangul_johab``` has width of 12, ```wenquanyi``` has width of 16.
### Parsing glyph widths for variable font sheets
![Sample of Font Spritesheet with annotation](width_bit_encoding_annotated.png)
Width is encoded in binary bits, on pixels. On the font spritesheet, every glyph has vertical dots on their top-right side (to be exact, every (16k - 1)th pixel on x axis). Above image is a sample of the font, with width information coloured in magenta. From top to bottom, each dot represents 1, 2, 4 and 8. For example, in the above image, ! (exclamation mark) has width of 5, " (double quote) has width of 6, # (octothorp) has width of 8, $ (dollar sign) has width of 9.
### Implementing the Korean writing system
On this font, Hangul letters are printed by assemblying two or three letter pieces. There are 10 sets of Hangul letter pieces on the font. Top 6 are initials, middle 2 are medials, and bottom 2 are finals. On the rightmost side, there's eight assembled glyphs to help you with (assuming you have basic knowledge on the writing system). Top 6 tells you how to use 6 initials, and bottom 2 tells you how to use 2 finals.
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)
jungseongComplex = arrayOf(9, 10, 11, 14, 15, 16, 22)
function 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
}
function isJungseongWide(hanIndex: Int) = jungseongWide.contains(getHanJungseong(hanIndex))
function isJungseongComplex(hanIndex: Int) = jungseongComplex.contains(getHanJungseong(hanIndex))
function 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
}
function getHanMedialRow(hanIndex: Int) = if (getHanJongseong(hanIndex) == 0) 6 else 7
function getHanFinalRow(hanIndex: Int): Int {
val jungseongIndex = getHanJungseong(hanIndex)
return if (jungseongWide.contains(jungseongIndex))
8
else
9
}
function isHangul(c: Char) = c.toInt() >= 0xAC00 && c.toInt() < 0xD7A4
...
for (each Char on the string) {
if (isHangul(Char)) {
val hIndex = Char.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)
// get sub image from sprite sheet
val choseongImage = hangulSheet.getSubImage(indexCho, choRow)
val jungseongImage = hangulSheet.getSubImage(indexJung, jungRow)
val jongseongImage = hangulSheet.getSubImage(indexJong, jongRow)
// actual drawing part
draw choseongImage to somewhere you want
draw jungseongImage on top of choseongImage
draw jongseongImage on top of choseongImage
}
...
}
Please refer to [CONTRIBUTING.md](https://github.com/minjaesong/Terrarum-sans-bitmap/blob/master/CONTRIBUTING.md)
## Acknowledgement

BIN
TerrarumSansBitmap.jar Normal file

Binary file not shown.