diff --git a/CONTRIBUTING.md b/CONTRIBUTING.md index c846d38..c99529e 100755 --- a/CONTRIBUTING.md +++ b/CONTRIBUTING.md @@ -7,7 +7,7 @@ Font Spritesheets are stored in ```assets/graphics/fonts``` directory. Image for #### Before getting started, you did read our design goals, right? Good. Now you may continue your awesome work. -### Ascenders, descenders, width informations (aka Glyph Tags) +## Ascenders, descenders, width informations (aka Glyph Tags) ![Alas, use more modern browser or get better internet connexion!](glyph_height_pos_annotation.png) @@ -26,11 +26,11 @@ Each cell is 16 px wide, and any glyph you draw **must be contained within lefts -### Font Metrics +## Font Metrics for variable-width font sheets 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 +### Parsing Glyph Tags ![Sample of Font Spritesheet with annotation](width_bit_encoding_annotated.png) @@ -61,26 +61,28 @@ Rightmost vertical column (should be 20 px tall) contains the tags. Tags are def D --Diacritics Type Bit (see below; not all diacritics are marked as one on the spritesheet) S -,_ 0 Stack 1 Stack 0 Before 1 Up & (MSB) S -' 0 up 0 down 1 &After 1 Down (e.g. U+0C48) +``` - -* Nudging Bits Encoding: +#### Nudging Bits Encoding SXXXXXXX SYYYYYYY 00000000 Each X and Y numbers are Signed 8-Bit Integer. -X-positive: nudges towards left -Y-positive: nudges towards up -* Diacritics Anchor Point Encoding: +X-positive: nudges towards left +Y-positive: nudges towards up + +#### Diacritics Anchor Point Encoding 4 Pixels are further divided as follows: -(LSB) -Y - Anchor point Y for undefined, undefined, undefined -X - Anchor point X for undefined, undefined, undefined -Y - Anchor point Y for (unused), undefined, undefined -X - Anchor point X for Type-0 (centre-aligned) diacritics, undefined, undefined -(MSB) +| LSB | | | | | +| ------------ | ------------ | ------------ | ------------ | ------------ | +| Y | Anchor point Y for: | undefined | undefined | undefined | +| X | Anchor point X for: | undefined | undefined | undefined | +| Y | Anchor point Y for: | (unused) | (unused) | (unused) | +| X | Anchor point X for: | Type-0 | Type-1 | Type-2 | +| MSB | | | | | 1Y1Y1Y1Y 1Y2Y2Y2Y 1Y3Y3Y3Y 1X1X1X1X 1X2X2X2X 1X3X3X3X @@ -89,38 +91,31 @@ where Red is first, Green is second, Blue is the third diacritics. MSB for each word must be set so that the pixel would appear brighter on the image editor. (the font program will only read low 7 bits for each RGB channel) -* Diacritics Type Bit Encoding: +#### Diacritics Type Bit Encoding FFFFFFFF FFFFFFFF FFFFFFFF (For Type-0) TTTT0000 00000000 00000000 (For Type-1 to Type-15) -Right now, only the type-0 diacritics and its anchor point is used by the font. +Certain types of diacritics have predefined meanings: -* Compiler Directives: +* Type-0: Above +* Type-1: Below (when it should be separated from being above) +* Type-2: Overlaid (will shift down 2 pixels for lowheight glyphs instead of the default of 4 pixels) + + +#### Compiler Directives [Opcode] [arg1] [arg2] Currently supported opcodes: - - 00000000: No-operation; does not use the Compiler Directive system. +*00000000: No-operation; does not use the Compiler Directive system. - - 10000xxx: Replace a character with xxx subchars (yes, number 0 can be used). - Replacement characters are encoded vertically from X-zero, bit by bit - (colour of the pixel doesn't matter) with LSB sitting on Y-zero. +*10000xxx: Replace a character with xxx subchars (yes, number 0 can be used). + Replacement characters are encoded vertically from X-zero, bit by bit + (colour of the pixel doesn't matter) with LSB sitting on Y-zero. - --= NOTE =- - -The code has remnants of one old HACK: using 0th diacritics' X-anchor pos as a type selector -This hack applied only when write-on-top bit is set. Relevant codes are currently commented out instead of -being completely removed for future debugging. -Interpretation: - DIA_OVERLAY = 1 - DIA_JOINER = 2 - -``` - #### Stack Up/Down When the tag is stack-up, it'll be drawn 4 px lower if the underlying @@ -157,13 +152,13 @@ Also note that the font compiler will not "stack" these diacritics. (fun fact: it was drawn on Rhodia memopad with Lamy 2000, then photographed and edited on my iPhone. Letter used is a Cherokee WE Ꮺ) -### Technical Limitations +## Technical Limitations - Each spritesheet is 4096x4096 maximum, which is a size of 4K Texture. However it is recommended to be smaller or equal to 1024x1024. - Glyphs exceeding 15px of width needs to be broken down with 2 or more characters. Wider sheets WILL NOT BE IMPLEMENTED, can't waste much pixels just for few superwide glyphs. - Due to how the compiler is coded, actual glyph must have alpha value of 255, the tags must have alpha values LESS THAN 255 (and obviously greater than zero). RGB plane of the TGA image doesn't do anything, keep it as #FFFFFF white. -### Implementing the Korean writing system +## Implementation of 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. diff --git a/assets/ascii_variable.tga b/assets/ascii_variable.tga index d7a0dfe..4b0d226 100755 --- a/assets/ascii_variable.tga +++ b/assets/ascii_variable.tga @@ -1,3 +1,3 @@ version https://git-lfs.github.com/spec/v1 -oid sha256:677781e28cfb0892fda6902e47477fd7c5495e931010b0109079906e806d4232 +oid sha256:3491d4b10b0341e1a8b875162381694e587dff4d2e8f0cb6a95da479c8956d41 size 327698 diff --git a/assets/diacritical_marks_variable.tga b/assets/diacritical_marks_variable.tga index 36d06d9..c9542a3 100755 Binary files a/assets/diacritical_marks_variable.tga and b/assets/diacritical_marks_variable.tga differ diff --git a/assets/ipa_ext_variable.tga b/assets/ipa_ext_variable.tga index caa8b61..4ce33de 100755 --- a/assets/ipa_ext_variable.tga +++ b/assets/ipa_ext_variable.tga @@ -1,3 +1,3 @@ version https://git-lfs.github.com/spec/v1 -oid sha256:3aee9600478b6d531ea5a43590d002bc1ecdec600ecc325e997032b51c4214da +oid sha256:4f76c223c431d3f8da64a76aa4d0b77e4f2b4c0895e593f52615baa2add6079f size 225298 diff --git a/assets/thai_variable.tga b/assets/thai_variable.tga index 065fbc9..4783b52 100755 --- a/assets/thai_variable.tga +++ b/assets/thai_variable.tga @@ -1,3 +1,3 @@ version https://git-lfs.github.com/spec/v1 -oid sha256:a4794221096551311bdddd5b11167c52401dec48ea1f629300ad39f40eccbc82 +oid sha256:134e9efce4e298b623bb3f977c5a8d65d05bdc3924e4be0564cebb4683ee5692 size 122898 diff --git a/src/net/torvald/terrarumsansbitmap/GlyphProps.kt b/src/net/torvald/terrarumsansbitmap/GlyphProps.kt index 14ce5cc..11a0b24 100755 --- a/src/net/torvald/terrarumsansbitmap/GlyphProps.kt +++ b/src/net/torvald/terrarumsansbitmap/GlyphProps.kt @@ -46,8 +46,8 @@ data class GlyphProps( const val STACK_BEFORE_N_AFTER = 2 const val STACK_UP_N_DOWN = 3 - const val DIA_OVERLAY = 1 - const val DIA_JOINER = 2 + const val DIA_OVERLAY = 2 +// const val DIA_JOINER = 2 private fun Boolean.toInt() = if (this) 1 else 0 } diff --git a/src/net/torvald/terrarumsansbitmap/gdx/TerrarumSansBitmap.kt b/src/net/torvald/terrarumsansbitmap/gdx/TerrarumSansBitmap.kt index 7010233..6aa5fbf 100755 --- a/src/net/torvald/terrarumsansbitmap/gdx/TerrarumSansBitmap.kt +++ b/src/net/torvald/terrarumsansbitmap/gdx/TerrarumSansBitmap.kt @@ -739,14 +739,14 @@ class TerrarumSansBitmap( val nudgeY = nudgingBits.ushr(16).toByte().toInt() // signed 8-bit int val diacriticsAnchors = (0..5).map { - val yPos = 11 + (it / 3) * 2 + val yPos = 13 - (it / 3) * 2 val shift = (3 - (it % 3)) * 8 val yPixel = pixmap.getPixel(codeStartX, codeStartY + yPos).tagify() val xPixel = pixmap.getPixel(codeStartX, codeStartY + yPos + 1).tagify() - val y = (yPixel ushr shift) and 127 - val x = (xPixel ushr shift) and 127 - val yUsed = (yPixel ushr shift) >= 128 - val xUsed = (yPixel ushr shift) >= 128 + val yUsed = (yPixel ushr shift) and 128 != 0 + val xUsed = (xPixel ushr shift) and 128 != 0 + val y = if (yUsed) (yPixel ushr shift) and 127 else 0 + val x = if (xUsed) (xPixel ushr shift) and 127 else 0 DiacriticsAnchor(it, x, y, xUsed, yUsed) }.toTypedArray() @@ -754,18 +754,22 @@ class TerrarumSansBitmap( val alignWhere = (0..1).fold(0) { acc, y -> acc or ((pixmap.getPixel(codeStartX, codeStartY + y + 15).and(255) != 0).toInt() shl y) } var writeOnTop = pixmap.getPixel(codeStartX, codeStartY + 17) // NO .tagify() - if (writeOnTop and 255 == 0) writeOnTop = -1 + if (writeOnTop and 255 == 0) writeOnTop = -1 // look for the alpha channel else { - writeOnTop = writeOnTop.ushr(8) - if (writeOnTop == 0xFFFFFF) writeOnTop = 0 + if (writeOnTop.ushr(8) == 0xFFFFFF) writeOnTop = 0 + else writeOnTop = writeOnTop.ushr(28) and 15 } val stackWhere = (0..1).fold(0) { acc, y -> acc or ((pixmap.getPixel(codeStartX, codeStartY + y + 18).and(255) != 0).toInt() shl y) } glyphProps[code] = GlyphProps(width, isLowHeight, nudgeX, nudgeY, diacriticsAnchors, alignWhere, writeOnTop, stackWhere, IntArray(15), hasKernData, isKernYtype, kerningMask, directiveOpcode, directiveArg1, directiveArg2) + + // Debug prints // // if (nudgingBits != 0) dbgprn("${code.charInfo()} nudgeX=$nudgeX, nudgeY=$nudgeY, nudgingBits=0x${nudgingBits.toString(16)}") // if (writeOnTop >= 0) dbgprn("WriteOnTop: ${code.charInfo()} (Type-${writeOnTop})") +// if (diacriticsAnchors.any { it.xUsed || it.yUsed }) dbgprn("${code.charInfo()} ${diacriticsAnchors.filter { it.xUsed || it.yUsed }.joinToString()}") + // extra info val extCount = glyphProps[code]?.requiredExtInfoCount() ?: 0 @@ -834,7 +838,10 @@ class TerrarumSansBitmap( /** - * posXbuffer's size is greater than the string, last element marks the width of entire string. + * THE function to typeset all the letters and their diacritics + * + * @return Pair of X-positions and Y-positions, of which the X-position's size is greater than the string + * and the last element marks the width of entire string. */ private fun buildPosMap(str: List): Pair { val posXbuffer = IntArray(str.size + 1) { 0 } @@ -900,6 +907,7 @@ class TerrarumSansBitmap( if (isHangul(thisChar) && !isHangulChoseong(thisChar) && !isHangulCompat(thisChar)) { posXbuffer[charIndex] = posXbuffer[nonDiacriticCounter] } + // is this glyph NOT a diacritic? else if (thisProp.writeOnTop < 0) { posXbuffer[charIndex] = -thisProp.nudgeX + when (itsProp.alignWhere) { @@ -929,15 +937,19 @@ class TerrarumSansBitmap( } }*/ + // is this glyph a diacritic? else { + val diacriticsType = thisProp.writeOnTop // set X pos according to alignment information posXbuffer[charIndex] = when (thisProp.alignWhere) { GlyphProps.ALIGN_LEFT, GlyphProps.ALIGN_BEFORE -> posXbuffer[nonDiacriticCounter] GlyphProps.ALIGN_RIGHT -> { - posXbuffer[nonDiacriticCounter] - (W_VAR_INIT - itsProp.width) + val alignXPos = if (!itsProp.diacriticsAnchors[diacriticsType].xUsed) itsProp.width else itsProp.diacriticsAnchors[diacriticsType].x + + posXbuffer[nonDiacriticCounter] - W_VAR_INIT + alignXPos } GlyphProps.ALIGN_CENTRE -> { - val alignXPos = if (itsProp.diacriticsAnchors[0].x == 0) itsProp.width.div(2) else itsProp.diacriticsAnchors[0].x + val alignXPos = if (!itsProp.diacriticsAnchors[diacriticsType].xUsed) itsProp.width.div(2) else itsProp.diacriticsAnchors[diacriticsType].x if (itsProp.alignWhere == GlyphProps.ALIGN_RIGHT) { posXbuffer[nonDiacriticCounter] + alignXPos + (itsProp.width + 1).div(2) @@ -966,7 +978,7 @@ class TerrarumSansBitmap( //dbgprn("AAARRRRHHHH for character ${thisChar.toHex()}") //dbgprn("lastNonDiacriticChar: ${lastNonDiacriticChar.toHex()}") //dbgprn("cond: ${thisProp.alignXPos == GlyphProps.DIA_OVERLAY}, charIndex: $charIndex") - if (thisProp.diacriticsAnchors[0].x == GlyphProps.DIA_OVERLAY) + if (diacriticsType == GlyphProps.DIA_OVERLAY) posYbuffer[charIndex] -= H_OVERLAY_LOWERCASE_SHIFTDOWN * (!flipY).toSign() // if minus-assign doesn't work, try plus-assign else posYbuffer[charIndex] -= H_STACKUP_LOWERCASE_SHIFTDOWN * (!flipY).toSign() // if minus-assign doesn't work, try plus-assign diff --git a/testing.PNG b/testing.PNG index 1df16e7..5dd3bb0 100755 Binary files a/testing.PNG and b/testing.PNG differ diff --git a/testtext.txt b/testtext.txt index f9588b9..481a614 100755 --- a/testtext.txt +++ b/testtext.txt @@ -1,16 +1,4 @@ -ถูกตำรว -ถูกตรว -aำ -แป้นพิมพ์เกษมณี แป้นพิมพ์ปัตตะโชติ -คำเตือน-อนามัยและความปลอดภัย -UIJTuijt + A ดุ ตี ปู่ พี่ ป่ ม่ ปั มั พีุ -দৌ ষৌ - -Mℂ℄ℇ℀℈jℊ№℗CKℵ℡Z℥ -ℵ₀ - -🄅🄵🅅🄕🄩🄪🄭🅭🄏🄎🅯🅮🆞🆠🆐🄯🆒🆓 - -도ᄋ해 무ᄅ과 배ᄀ두사ᄂ 하느니ᄆ이 보우하사 \ No newline at end of file + U̸ u̸ \ No newline at end of file diff --git a/work_files/ascii_variable.psd b/work_files/ascii_variable.psd index 3a3048a..de9b286 100644 --- a/work_files/ascii_variable.psd +++ b/work_files/ascii_variable.psd @@ -1,3 +1,3 @@ version https://git-lfs.github.com/spec/v1 -oid sha256:f2a33657d6df816821ad8991515c4da297b1053966cdb0fc23e09168c70c9299 -size 317663 +oid sha256:1b80ce3760208ed5fd3ccd2dadbd2c6e6ab433c4c7058648e87df89dbe08b7b3 +size 317679 diff --git a/work_files/diacritical_marks_variable.psd b/work_files/diacritical_marks_variable.psd index 4bec8ee..b0f1aeb 100644 Binary files a/work_files/diacritical_marks_variable.psd and b/work_files/diacritical_marks_variable.psd differ diff --git a/work_files/ipa_ext_variable.psd b/work_files/ipa_ext_variable.psd index e35d1de..cd0db25 100644 --- a/work_files/ipa_ext_variable.psd +++ b/work_files/ipa_ext_variable.psd @@ -1,3 +1,3 @@ version https://git-lfs.github.com/spec/v1 -oid sha256:59d023d16fd70a8d1bef17cda3fdf04b9607608d8083fc0fe4f326194a49623f -size 271689 +oid sha256:8c0e41fe4e68560498509f9e29a467457408b63fd7c28bc9067cc97402c819b9 +size 271693 diff --git a/work_files/thai_variable.psd b/work_files/thai_variable.psd index 3834931..3a4f11b 100644 --- a/work_files/thai_variable.psd +++ b/work_files/thai_variable.psd @@ -1,3 +1,3 @@ version https://git-lfs.github.com/spec/v1 -oid sha256:e2e9745f9e505a926c4f036d5538b4ab5a20aed6c87aa2fdc28214ebf919d1c2 -size 122328 +oid sha256:b68e8c5f51f896fd24f4c93db2bc8488acb3959da791599733d9333f26117dd7 +size 122981