more hangul improvements

This commit is contained in:
minjaesong
2020-05-01 17:12:13 +09:00
parent 0c5b7c8b70
commit 34903b10d4
5 changed files with 363 additions and 331 deletions

Binary file not shown.

Before

Width:  |  Height:  |  Size: 1.5 MiB

After

Width:  |  Height:  |  Size: 2.6 MiB

View File

@@ -37,7 +37,6 @@ import java.security.MessageDigest
import java.util.*
import java.util.zip.CRC32
import java.util.zip.GZIPInputStream
import kotlin.NullPointerException
import kotlin.math.roundToInt
import kotlin.math.sign
@@ -106,218 +105,7 @@ class GameFontBase(
val debug: Boolean = false
) : BitmapFont() {
// Hangul Implementation Specific //
private fun getWanseongHanChoseong(hanIndex: Int) = hanIndex / (JUNG_COUNT * JONG_COUNT)
private fun getWanseongHanJungseong(hanIndex: Int) = hanIndex / JONG_COUNT % JUNG_COUNT
private fun getWanseongHanJongseong(hanIndex: Int) = hanIndex % JONG_COUNT
// ㅗ ㅛ ㅜ ㅠ ㅡ etc
private val jungseongWide: Array<Int> = arrayOf(9,13,14,18,19,34,35,39,45,51,53,54,62,64,66,80,83)
// ㅘ ㅙ ㅚ etc
private val jungseongComplex: Array<Int> = arrayOf(10,11,12,15,16,17,20) + (22..33).toList() + arrayOf(36,37,38) + (40..44).toList() + arrayOf(46,47,48,49,50,52) + (55..60).toList() + arrayOf(63,65) + (67..79).toList() + arrayOf(81,82) + (84..93).toList()
// ㅓ ㅔ ㅕ etc
private val jungseongRightie: Array<Int> = arrayOf(2,4,6,8,11,16,32,33,37,42,44,48,50,71,72,75,78,79,83,86,87,88,94)
private fun isJungseongWide(hanIndex: Int) = jungseongWide.binarySearch(hanIndex) >= 0
private fun isJungseongComplex(hanIndex: Int) = jungseongComplex.binarySearch(hanIndex) >= 0
private fun isJungseongRighie(hanIndex: Int) = jungseongRightie.binarySearch(hanIndex) >= 0
/**
* @param i Initial (Choseong)
* @param p Peak (Jungseong)
* @param f Final (Jongseong)
*/
private fun getHanInitialRow(i: Int, p: Int, f: Int): Int {
val ret =
if (isJungseongWide(p)) 3
else if (isJungseongComplex(p)) 5
else 1
return if (f == 0) ret else ret + 1
}
private fun getHanMedialRow(i: Int, p: Int, f: Int) = if (f == 0) 7 else 8
private fun getHanFinalRow(i: Int, p: Int, f: Int): Int {
return if (isJungseongRighie(p))
10
else
9
}
private fun isHangulChoseong(c: CodePoint) = c in (0x1100..0x115F) || c in (0xA960..0xA97F)
private fun isHangulJungseong(c: CodePoint) = c in (0x1160..0x11A7) || c in (0xD7B0..0xD7C6)
private fun isHangulJongseong(c: CodePoint) = c in (0x11A8..0x11FF) || c in (0xD7CB..0xD7FB)
private fun toHangulChoseongIndex(c: CodePoint) =
if (!isHangulChoseong(c)) throw IllegalArgumentException("This Hangul sequence does not begin with Choseong (${c.toHex()})")
else if (c in 0x1100..0x115F) c - 0x1100
else c - 0xA960 + 96
private fun toHangulJungseongIndex(c: CodePoint) =
if (!isHangulJungseong(c)) 0
else if (c in 0x1160..0x11A7) c - 0x1160
else c - 0xD7B0 + 72
private fun toHangulJongseongIndex(c: CodePoint) =
if (!isHangulJongseong(c)) 0
else if (c in 0x11A8..0x11FF) c - 0x11A8 + 1
else c - 0xD7CB + 88 + 1
/**
* X-position in the spritesheet
*
* @param iCP Code point for Initial (Choseong)
* @param pCP Code point for Peak (Jungseong)
* @param fCP Code point for Final (Jongseong)
*/
private fun toHangulIndex(iCP: CodePoint, pCP: CodePoint, fCP: CodePoint): IntArray {
val indexI = toHangulChoseongIndex(iCP)
val indexP = toHangulJungseongIndex(pCP)
val indexF = toHangulJongseongIndex(fCP)
return intArrayOf(indexI, indexP, indexF)
}
/**
* @param iCP 0x1100..0x115F, 0xA960..0xA97F, 0x3130..0x318F
* @param pCP 0x00, 0x1160..0x11A7, 0xD7B0..0xD7CA
* @param fCP 0x00, 0x11A8..0x11FF, 0xD7BB..0xD7FF
*
* @return IntArray pair representing Hangul indices and rows (in this order)
*/
private fun toHangulIndexAndRow(iCP: CodePoint, pCP: CodePoint, fCP: CodePoint): Pair<IntArray, IntArray> {
if (isHangulCompat(iCP)) {
return intArrayOf(iCP - 0x3130, 0, 0) to intArrayOf(0, 7, 9)
}
else {
val (indexI, indexP, indexF) = toHangulIndex(iCP, pCP, fCP)
val rowI = getHanInitialRow(indexI, indexP, indexF)
val rowP = getHanMedialRow(indexI, indexP, indexF)
val rowF = getHanFinalRow(indexI, indexP, indexF)
return intArrayOf(indexI, indexP, indexF) to intArrayOf(rowI, rowP, rowF)
}
}
// END Hangul //
private fun isHangul(c: CodePoint) = c in codeRange[SHEET_HANGUL] || c in 0x3130..0x318F
private fun isAscii(c: CodePoint) = c in codeRange[SHEET_ASCII_VARW]
private fun isRunic(c: CodePoint) = c in codeRange[SHEET_RUNIC]
private fun isExtA(c: CodePoint) = c in codeRange[SHEET_EXTA_VARW]
private fun isExtB(c: CodePoint) = c in codeRange[SHEET_EXTB_VARW]
private fun isKana(c: CodePoint) = c in codeRange[SHEET_KANA]
private fun isCJKPunct(c: CodePoint) = c in codeRange[SHEET_CJK_PUNCT]
private fun isUniHan(c: CodePoint) = c in codeRange[SHEET_UNIHAN]
private fun isCyrilic(c: CodePoint) = c in codeRange[SHEET_CYRILIC_VARW]
private fun isFullwidthUni(c: CodePoint) = c in codeRange[SHEET_FW_UNI]
private fun isUniPunct(c: CodePoint) = c in codeRange[SHEET_UNI_PUNCT_VARW]
private fun isGreek(c: CodePoint) = c in codeRange[SHEET_GREEK_VARW]
private fun isThai(c: CodePoint) = c in codeRange[SHEET_THAI_VARW]
/*private fun isDiacritics(c: CodePoint) = c in 0xE34..0xE3A
|| c in 0xE47..0xE4E
|| c == 0xE31*/
private fun isCustomSym(c: CodePoint) = c in codeRange[SHEET_CUSTOM_SYM]
private fun isArmenian(c: CodePoint) = c in codeRange[SHEET_HAYEREN_VARW]
private fun isKartvelian(c: CodePoint) = c in codeRange[SHEET_KARTULI_VARW]
private fun isIPA(c: CodePoint) = c in codeRange[SHEET_IPA_VARW]
private fun isLatinExtAdd(c: CodePoint) = c in 0x1E00..0x1EFF
private fun isBulgarian(c: CodePoint) = c in 0x400..0x45F
private fun isColourCode(c: CodePoint) = c == 0x100000 || c in 0x10F000..0x10FFFF
private fun isCharsetOverride(c: CodePoint) = c in 0xFFFC0..0xFFFFF
private fun isCherokee(c: CodePoint) = c in codeRange[SHEET_TSALAGI_VARW]
private fun isInsular(c: CodePoint) = c == 0x1D79
private fun isNagariBengali(c: CodePoint) = c in codeRange[SHEET_NAGARI_BENGALI_VARW]
private fun isKartvelianCaps(c: CodePoint) = c in codeRange[SHEET_KARTULI_CAPS_VARW]
private fun isDiacriticalMarks(c: CodePoint) = c in codeRange[SHEET_DIACRITICAL_MARKS_VARW]
private fun isPolytonicGreek(c: CodePoint) = c in codeRange[SHEET_GREEK_POLY_VARW]
private fun isExtC(c: CodePoint) = c in codeRange[SHEET_EXTC_VARW]
private fun isExtD(c: CodePoint) = c in codeRange[SHEET_EXTD_VARW]
private fun isHangulCompat(c: CodePoint) = c in codeRangeHangulCompat
// underscored name: not a charset
private fun _isCaps(c: CodePoint) = Character.isUpperCase(c) || isKartvelianCaps(c)
private fun extAindexX(c: CodePoint) = (c - 0x100) % 16
private fun extAindexY(c: CodePoint) = (c - 0x100) / 16
private fun extBindexX(c: CodePoint) = (c - 0x180) % 16
private fun extBindexY(c: CodePoint) = (c - 0x180) / 16
private fun runicIndexX(c: CodePoint) = (c - 0x16A0) % 16
private fun runicIndexY(c: CodePoint) = (c - 0x16A0) / 16
private fun kanaIndexX(c: CodePoint) = (c - 0x3040) % 16
private fun kanaIndexY(c: CodePoint) =
if (c in 0x31F0..0x31FF) 12
else if (c in 0x1B000..0x1B00F) 13
else (c - 0x3040) / 16
private fun cjkPunctIndexX(c: CodePoint) = (c - 0x3000) % 16
private fun cjkPunctIndexY(c: CodePoint) = (c - 0x3000) / 16
private fun cyrilicIndexX(c: CodePoint) = (c - 0x400) % 16
private fun cyrilicIndexY(c: CodePoint) = (c - 0x400) / 16
private fun fullwidthUniIndexX(c: CodePoint) = (c - 0xFF00) % 16
private fun fullwidthUniIndexY(c: CodePoint) = (c - 0xFF00) / 16
private fun uniPunctIndexX(c: CodePoint) = (c - 0x2000) % 16
private fun uniPunctIndexY(c: CodePoint) = (c - 0x2000) / 16
private fun unihanIndexX(c: CodePoint) = (c - 0x3400) % 256
private fun unihanIndexY(c: CodePoint) = (c - 0x3400) / 256
private fun greekIndexX(c: CodePoint) = (c - 0x370) % 16
private fun greekIndexY(c: CodePoint) = (c - 0x370) / 16
private fun thaiIndexX(c: CodePoint) = (c - 0xE00) % 16
private fun thaiIndexY(c: CodePoint) = (c - 0xE00) / 16
private fun symbolIndexX(c: CodePoint) = (c - 0xE000) % 16
private fun symbolIndexY(c: CodePoint) = (c - 0xE000) / 16
private fun armenianIndexX(c: CodePoint) = (c - 0x530) % 16
private fun armenianIndexY(c: CodePoint) = (c - 0x530) / 16
private fun kartvelianIndexX(c: CodePoint) = (c - 0x10D0) % 16
private fun kartvelianIndexY(c: CodePoint) = (c - 0x10D0) / 16
private fun ipaIndexX(c: CodePoint) = (c - 0x250) % 16
private fun ipaIndexY(c: CodePoint) = (c - 0x250) / 16
private fun latinExtAddX(c: CodePoint) = (c - 0x1E00) % 16
private fun latinExtAddY(c: CodePoint) = (c - 0x1E00) / 16
private fun cherokeeIndexX(c: CodePoint) = (c - 0x13A0) % 16
private fun cherokeeIndexY(c: CodePoint) = (c - 0x13A0) / 16
private fun insularIndexX(c: CodePoint) =
if (c == 0x1D79) 0 else (c - 0xA770) % 16
private fun insularIndexY(c: CodePoint) =
if (c == 0x1D79) 0 else (c - 0xA770) / 16
private fun nagariIndexX(c: CodePoint) = (c - 0x900) % 16
private fun nagariIndexY(c: CodePoint) = (c - 0x900) / 16
private fun kartvelianCapsIndexX(c: CodePoint) = (c - 0x1C90) % 16
private fun kartvelianCapsIndexY(c: CodePoint) = (c - 0x1C90) / 16
private fun diacriticalMarksIndexX(c: CodePoint) = (c - 0x300) % 16
private fun diacriticalMarksIndexY(c: CodePoint) = (c - 0x300) / 16
private fun polytonicGreekIndexX(c: CodePoint) = (c - 0x1F00) % 16
private fun polytonicGreekIndexY(c: CodePoint) = (c - 0x1F00) / 16
private fun extCIndexX(c: CodePoint) = (c - 0x2C60) % 16
private fun extCIndexY(c: CodePoint) = (c - 0x2C60) / 16
private fun extDIndexX(c: CodePoint) = (c - 0xA720) % 16
private fun extDIndexY(c: CodePoint) = (c - 0xA720) / 16
/**
@@ -437,101 +225,11 @@ class GameFontBase(
return col
}
private val colourBuffer = HashMap<CodePoint, ARGB8888>()
private val unihanWidthSheets = arrayOf(
SHEET_UNIHAN,
SHEET_FW_UNI
)
private val variableWidthSheets = arrayOf(
SHEET_ASCII_VARW,
SHEET_EXTA_VARW,
SHEET_EXTB_VARW,
SHEET_CYRILIC_VARW,
SHEET_UNI_PUNCT_VARW,
SHEET_GREEK_VARW,
SHEET_THAI_VARW,
SHEET_HAYEREN_VARW,
SHEET_KARTULI_VARW,
SHEET_IPA_VARW,
SHEET_LATIN_EXT_ADD_VARW,
SHEET_BULGARIAN_VARW,
SHEET_SERBIAN_VARW,
SHEET_TSALAGI_VARW,
SHEET_INSUAR_VARW,
SHEET_NAGARI_BENGALI_VARW,
SHEET_KARTULI_CAPS_VARW,
SHEET_DIACRITICAL_MARKS_VARW,
SHEET_GREEK_POLY_VARW,
SHEET_EXTC_VARW,
SHEET_EXTD_VARW
)
private val autoShiftDownOnLowercase = arrayOf(
SHEET_DIACRITICAL_MARKS_VARW
)
private val fontParentDir = if (fontDir.endsWith('/') || fontDir.endsWith('\\')) fontDir else "$fontDir/"
private val fileList = arrayOf( // MUST BE MATCHING WITH SHEET INDICES!!
"ascii_variable.tga",
"hangul_johab.tga",
"latinExtA_variable.tga",
"latinExtB_variable.tga",
"kana.tga",
"cjkpunct.tga",
"wenquanyi.tga.gz",
"cyrilic_variable.tga",
"fullwidth_forms.tga",
"unipunct_variable.tga",
"greek_variable.tga",
"thai_variable.tga",
"hayeren_variable.tga",
"kartuli_variable.tga",
"ipa_ext_variable.tga",
"futhark.tga",
"latinExt_additional_variable.tga",
"puae000-e0ff.tga",
"cyrilic_bulgarian_variable.tga",
"cyrilic_serbian_variable.tga",
"tsalagi_variable.tga",
"insular_variable.tga",
"devanagari_bengali_variable.tga",
"kartuli_allcaps_variable.tga",
"diacritical_marks_variable.tga",
"greek_polytonic_xyswap_variable.tga",
"latinExtC_variable.tga",
"latinExtD_variable.tga"
)
private val codeRange = arrayOf( // MUST BE MATCHING WITH SHEET INDICES!!
0..0xFF, // SHEET_ASCII_VARW
(0x1100..0x11FF) + (0xA960..0xA97F) + (0xD7B0..0xD7FF), // SHEET_HANGUL, because Hangul Syllables are disassembled prior to the render
0x100..0x17F, // SHEET_EXTA_VARW
0x180..0x24F, // SHEET_EXTB_VARW
(0x3040..0x30FF) + (0x31F0..0x31FF) + (0x1B000..0x1B001), // SHEET_KANA
0x3000..0x303F, // SHEET_CJK_PUNCT
0x3400..0x9FFF, // SHEET_UNIHAN
0x400..0x52F, // SHEET_CYRILIC_VARW
0xFF00..0xFF1F, // SHEET_FW_UNI
0x2000..0x209F, // SHEET_UNI_PUNCT_VARW
0x370..0x3CE, // SHEET_GREEK_VARW
0xE00..0xE5F, // SHEET_THAI_VARW
0x530..0x58F, // SHEET_HAYEREN_VARW
0x10D0..0x10FF, // SHEET_KARTULI_VARW
0x250..0x2FF, // SHEET_IPA_VARW
0x16A0..0x16FF, // SHEET_RUNIC
0x1E00..0x1EFF, // SHEET_LATIN_EXT_ADD_VARW
0xE000..0xE0FF, // SHEET_CUSTOM_SYM
0xF00000..0xF0005F, // SHEET_BULGARIAN_VARW; assign them to PUA
0xF00060..0xF000BF, // SHEET_SERBIAN_VARW; assign them to PUA
0x13A0..0x13F5, // SHEET_TSALAGI_VARW
0xA770..0xA787, // SHEET_INSULAR_VARW; if it work, don't fix it (yet--wait until Latin Extended C)
0x900..0x9FF, // SHEET_NAGARI_BENGALI_VARW
0x1C90..0x1CBF, // SHEET_KARTULI_CAPS_VARW
0x300..0x36F, // SHEET_DIACRITICAL_MARKS_VARW
0x1F00..0x1FFF, // SHEET_GREEK_POLY_VARW
0x2C60..0x2C7F, // SHEET_EXTC_VARW
0xA720..0xA7FF // SHEET_EXTD_VARW
)
private val codeRangeHangulCompat = 0x3130..0x318F
/** Props of all printable Unicode points. */
private val glyphProps: HashMap<CodePoint, GlyphProps> = HashMap()
private val sheets: Array<PixmapRegionPack>
@@ -1150,14 +848,14 @@ class GameFontBase(
fun buildWidthTableFixed() {
// fixed-width props
this.codeRange[SHEET_CJK_PUNCT].forEach { glyphProps[it] = GlyphProps(W_ASIAN_PUNCT, 0) }
this.codeRange[SHEET_CUSTOM_SYM].forEach { glyphProps[it] = GlyphProps(20, 0) }
this.codeRange[SHEET_FW_UNI].forEach { glyphProps[it] = GlyphProps(W_UNIHAN, 0) }
this.codeRange[SHEET_HANGUL].forEach { glyphProps[it] = GlyphProps(W_HANGUL, 0) }
codeRange[SHEET_CJK_PUNCT].forEach { glyphProps[it] = GlyphProps(W_ASIAN_PUNCT, 0) }
codeRange[SHEET_CUSTOM_SYM].forEach { glyphProps[it] = GlyphProps(20, 0) }
codeRange[SHEET_FW_UNI].forEach { glyphProps[it] = GlyphProps(W_UNIHAN, 0) }
codeRange[SHEET_HANGUL].forEach { glyphProps[it] = GlyphProps(W_HANGUL, 0) }
codeRangeHangulCompat.forEach { glyphProps[it] = GlyphProps(W_HANGUL, 0) }
this.codeRange[SHEET_KANA].forEach { glyphProps[it] = GlyphProps(W_KANA, 0) }
this.codeRange[SHEET_RUNIC].forEach { glyphProps[it] = GlyphProps(9, 0) }
this.codeRange[SHEET_UNIHAN].forEach { glyphProps[it] = GlyphProps(W_UNIHAN, 0) }
codeRange[SHEET_KANA].forEach { glyphProps[it] = GlyphProps(W_KANA, 0) }
codeRange[SHEET_RUNIC].forEach { glyphProps[it] = GlyphProps(9, 0) }
codeRange[SHEET_UNIHAN].forEach { glyphProps[it] = GlyphProps(W_UNIHAN, 0) }
(0xD800..0xDFFF).forEach { glyphProps[it] = GlyphProps(0, 0) }
(0x100000..0x10FFFF).forEach { glyphProps[it] = GlyphProps(0, 0) }
(0xFFFA0..0xFFFFF).forEach { glyphProps[it] = GlyphProps(0, 0) }
@@ -1634,7 +1332,6 @@ class GameFontBase(
}
private fun Int.toHex() = "U+${this.toString(16).padStart(4, '0').toUpperCase()}"
private fun CharSequence.sha256(): ByteArray {
val digest = MessageDigest.getInstance("SHA-256")
@@ -1728,6 +1425,330 @@ class GameFontBase(
internal val CHARSET_OVERRIDE_SR_SR = 0xFFFC2
private val unihanWidthSheets = arrayOf(
SHEET_UNIHAN,
SHEET_FW_UNI
)
private val variableWidthSheets = arrayOf(
SHEET_ASCII_VARW,
SHEET_EXTA_VARW,
SHEET_EXTB_VARW,
SHEET_CYRILIC_VARW,
SHEET_UNI_PUNCT_VARW,
SHEET_GREEK_VARW,
SHEET_THAI_VARW,
SHEET_HAYEREN_VARW,
SHEET_KARTULI_VARW,
SHEET_IPA_VARW,
SHEET_LATIN_EXT_ADD_VARW,
SHEET_BULGARIAN_VARW,
SHEET_SERBIAN_VARW,
SHEET_TSALAGI_VARW,
SHEET_INSUAR_VARW,
SHEET_NAGARI_BENGALI_VARW,
SHEET_KARTULI_CAPS_VARW,
SHEET_DIACRITICAL_MARKS_VARW,
SHEET_GREEK_POLY_VARW,
SHEET_EXTC_VARW,
SHEET_EXTD_VARW
)
private val autoShiftDownOnLowercase = arrayOf(
SHEET_DIACRITICAL_MARKS_VARW
)
private val fileList = arrayOf( // MUST BE MATCHING WITH SHEET INDICES!!
"ascii_variable.tga",
"hangul_johab.tga",
"latinExtA_variable.tga",
"latinExtB_variable.tga",
"kana.tga",
"cjkpunct.tga",
"wenquanyi.tga.gz",
"cyrilic_variable.tga",
"fullwidth_forms.tga",
"unipunct_variable.tga",
"greek_variable.tga",
"thai_variable.tga",
"hayeren_variable.tga",
"kartuli_variable.tga",
"ipa_ext_variable.tga",
"futhark.tga",
"latinExt_additional_variable.tga",
"puae000-e0ff.tga",
"cyrilic_bulgarian_variable.tga",
"cyrilic_serbian_variable.tga",
"tsalagi_variable.tga",
"insular_variable.tga",
"devanagari_bengali_variable.tga",
"kartuli_allcaps_variable.tga",
"diacritical_marks_variable.tga",
"greek_polytonic_xyswap_variable.tga",
"latinExtC_variable.tga",
"latinExtD_variable.tga"
)
private val codeRange = arrayOf( // MUST BE MATCHING WITH SHEET INDICES!!
0..0xFF, // SHEET_ASCII_VARW
(0x1100..0x11FF) + (0xA960..0xA97F) + (0xD7B0..0xD7FF), // SHEET_HANGUL, because Hangul Syllables are disassembled prior to the render
0x100..0x17F, // SHEET_EXTA_VARW
0x180..0x24F, // SHEET_EXTB_VARW
(0x3040..0x30FF) + (0x31F0..0x31FF) + (0x1B000..0x1B001), // SHEET_KANA
0x3000..0x303F, // SHEET_CJK_PUNCT
0x3400..0x9FFF, // SHEET_UNIHAN
0x400..0x52F, // SHEET_CYRILIC_VARW
0xFF00..0xFF1F, // SHEET_FW_UNI
0x2000..0x209F, // SHEET_UNI_PUNCT_VARW
0x370..0x3CE, // SHEET_GREEK_VARW
0xE00..0xE5F, // SHEET_THAI_VARW
0x530..0x58F, // SHEET_HAYEREN_VARW
0x10D0..0x10FF, // SHEET_KARTULI_VARW
0x250..0x2FF, // SHEET_IPA_VARW
0x16A0..0x16FF, // SHEET_RUNIC
0x1E00..0x1EFF, // SHEET_LATIN_EXT_ADD_VARW
0xE000..0xE0FF, // SHEET_CUSTOM_SYM
0xF00000..0xF0005F, // SHEET_BULGARIAN_VARW; assign them to PUA
0xF00060..0xF000BF, // SHEET_SERBIAN_VARW; assign them to PUA
0x13A0..0x13F5, // SHEET_TSALAGI_VARW
0xA770..0xA787, // SHEET_INSULAR_VARW; if it work, don't fix it (yet--wait until Latin Extended C)
0x900..0x9FF, // SHEET_NAGARI_BENGALI_VARW
0x1C90..0x1CBF, // SHEET_KARTULI_CAPS_VARW
0x300..0x36F, // SHEET_DIACRITICAL_MARKS_VARW
0x1F00..0x1FFF, // SHEET_GREEK_POLY_VARW
0x2C60..0x2C7F, // SHEET_EXTC_VARW
0xA720..0xA7FF // SHEET_EXTD_VARW
)
private val codeRangeHangulCompat = 0x3130..0x318F
private fun Int.toHex() = "U+${this.toString(16).padStart(4, '0').toUpperCase()}"
// Hangul Implementation Specific //
private fun getWanseongHanChoseong(hanIndex: Int) = hanIndex / (JUNG_COUNT * JONG_COUNT)
private fun getWanseongHanJungseong(hanIndex: Int) = hanIndex / JONG_COUNT % JUNG_COUNT
private fun getWanseongHanJongseong(hanIndex: Int) = hanIndex % JONG_COUNT
// ㅣ
private val jungseongI: Array<Int> = arrayOf(21,61)
// ㅗ ㅛ ㅜ ㅠ
private val jungseongOU: Array<Int> = arrayOf(9,13,14,18,34,35,39,45,51,53,54,64,80,83)
// ㅘ ㅙ ㅝ ㅞ
private val jungseongOUComplex: Array<Int> = arrayOf(10,11,15,16) + (22..33).toList() + arrayOf(36,37,38) + (41..44).toList() + arrayOf(46,47,48,49,50) + (56..59).toList() + arrayOf(63) + (67..79).toList() + arrayOf(81,82) + (84..93).toList()
// ㅐ ㅒ ㅔ ㅖ etc
private val jungseongRightie: Array<Int> = arrayOf(2,4,6,8,11,16,32,33,37,42,44,48,50,71,72,75,78,79,83,86,87,88,94)
// ㅚ ㅟ
private val jungseongOEWI: Array<Int> = arrayOf(12,17,40,52,55,89,90,91)
// ㅡ
private val jungseongEU: Array<Int> = arrayOf(19,62,66)
// ㅢ
private val jungseongYI: Array<Int> = arrayOf(20,60,65)
private fun isJungseongI(hanIndex: Int) = jungseongI.binarySearch(hanIndex) >= 0
private fun isJungseongOU(hanIndex: Int) = jungseongOU.binarySearch(hanIndex) >= 0
private fun isJungseongOUComplex(hanIndex: Int) = jungseongOUComplex.binarySearch(hanIndex) >= 0
private fun isJungseongRighie(hanIndex: Int) = jungseongRightie.binarySearch(hanIndex) >= 0
private fun isJungseongOEWI(hanIndex: Int) = jungseongOEWI.binarySearch(hanIndex) >= 0
private fun isJungseongEU(hanIndex: Int) = jungseongEU.binarySearch(hanIndex) >= 0
private fun isJungseongYI(hanIndex: Int) = jungseongYI.binarySearch(hanIndex) >= 0
/**
* @param i Initial (Choseong)
* @param p Peak (Jungseong)
* @param f Final (Jongseong)
*/
private fun getHanInitialRow(i: Int, p: Int, f: Int): Int {
val ret =
if (isJungseongI(p)) 3
else if (isJungseongOUComplex(p)) 7
else if (isJungseongOEWI(p)) 11
else if (isJungseongOU(p)) 5
else if (isJungseongEU(p)) 9
else if (isJungseongYI(p)) 13
else 1
return if (f == 0) ret else ret + 1
}
private fun getHanMedialRow(i: Int, p: Int, f: Int) = if (f == 0) 15 else 16
private fun getHanFinalRow(i: Int, p: Int, f: Int): Int {
return if (!isJungseongRighie(p))
17
else
18
}
private fun isHangulChoseong(c: CodePoint) = c in (0x1100..0x115F) || c in (0xA960..0xA97F)
private fun isHangulJungseong(c: CodePoint) = c in (0x1160..0x11A7) || c in (0xD7B0..0xD7C6)
private fun isHangulJongseong(c: CodePoint) = c in (0x11A8..0x11FF) || c in (0xD7CB..0xD7FB)
private fun toHangulChoseongIndex(c: CodePoint) =
if (!isHangulChoseong(c)) throw IllegalArgumentException("This Hangul sequence does not begin with Choseong (${c.toHex()})")
else if (c in 0x1100..0x115F) c - 0x1100
else c - 0xA960 + 96
private fun toHangulJungseongIndex(c: CodePoint) =
if (!isHangulJungseong(c)) 0
else if (c in 0x1160..0x11A7) c - 0x1160
else c - 0xD7B0 + 72
private fun toHangulJongseongIndex(c: CodePoint) =
if (!isHangulJongseong(c)) 0
else if (c in 0x11A8..0x11FF) c - 0x11A8 + 1
else c - 0xD7CB + 88 + 1
/**
* X-position in the spritesheet
*
* @param iCP Code point for Initial (Choseong)
* @param pCP Code point for Peak (Jungseong)
* @param fCP Code point for Final (Jongseong)
*/
private fun toHangulIndex(iCP: CodePoint, pCP: CodePoint, fCP: CodePoint): IntArray {
val indexI = toHangulChoseongIndex(iCP)
val indexP = toHangulJungseongIndex(pCP)
val indexF = toHangulJongseongIndex(fCP)
return intArrayOf(indexI, indexP, indexF)
}
/**
* @param iCP 0x1100..0x115F, 0xA960..0xA97F, 0x3130..0x318F
* @param pCP 0x00, 0x1160..0x11A7, 0xD7B0..0xD7CA
* @param fCP 0x00, 0x11A8..0x11FF, 0xD7BB..0xD7FF
*
* @return IntArray pair representing Hangul indices and rows (in this order)
*/
private fun toHangulIndexAndRow(iCP: CodePoint, pCP: CodePoint, fCP: CodePoint): Pair<IntArray, IntArray> {
if (isHangulCompat(iCP)) {
return intArrayOf(iCP - 0x3130, 0, 0) to intArrayOf(0, 15, 17)
}
else {
val (indexI, indexP, indexF) = toHangulIndex(iCP, pCP, fCP)
val rowI = getHanInitialRow(indexI, indexP, indexF)
val rowP = getHanMedialRow(indexI, indexP, indexF)
val rowF = getHanFinalRow(indexI, indexP, indexF)
return intArrayOf(indexI, indexP, indexF) to intArrayOf(rowI, rowP, rowF)
}
}
// END Hangul //
private fun isHangul(c: CodePoint) = c in codeRange[SHEET_HANGUL] || c in 0x3130..0x318F
private fun isAscii(c: CodePoint) = c in codeRange[SHEET_ASCII_VARW]
private fun isRunic(c: CodePoint) = c in codeRange[SHEET_RUNIC]
private fun isExtA(c: CodePoint) = c in codeRange[SHEET_EXTA_VARW]
private fun isExtB(c: CodePoint) = c in codeRange[SHEET_EXTB_VARW]
private fun isKana(c: CodePoint) = c in codeRange[SHEET_KANA]
private fun isCJKPunct(c: CodePoint) = c in codeRange[SHEET_CJK_PUNCT]
private fun isUniHan(c: CodePoint) = c in codeRange[SHEET_UNIHAN]
private fun isCyrilic(c: CodePoint) = c in codeRange[SHEET_CYRILIC_VARW]
private fun isFullwidthUni(c: CodePoint) = c in codeRange[SHEET_FW_UNI]
private fun isUniPunct(c: CodePoint) = c in codeRange[SHEET_UNI_PUNCT_VARW]
private fun isGreek(c: CodePoint) = c in codeRange[SHEET_GREEK_VARW]
private fun isThai(c: CodePoint) = c in codeRange[SHEET_THAI_VARW]
/*private fun isDiacritics(c: CodePoint) = c in 0xE34..0xE3A
|| c in 0xE47..0xE4E
|| c == 0xE31*/
private fun isCustomSym(c: CodePoint) = c in codeRange[SHEET_CUSTOM_SYM]
private fun isArmenian(c: CodePoint) = c in codeRange[SHEET_HAYEREN_VARW]
private fun isKartvelian(c: CodePoint) = c in codeRange[SHEET_KARTULI_VARW]
private fun isIPA(c: CodePoint) = c in codeRange[SHEET_IPA_VARW]
private fun isLatinExtAdd(c: CodePoint) = c in 0x1E00..0x1EFF
private fun isBulgarian(c: CodePoint) = c in 0x400..0x45F
private fun isColourCode(c: CodePoint) = c == 0x100000 || c in 0x10F000..0x10FFFF
private fun isCharsetOverride(c: CodePoint) = c in 0xFFFC0..0xFFFFF
private fun isCherokee(c: CodePoint) = c in codeRange[SHEET_TSALAGI_VARW]
private fun isInsular(c: CodePoint) = c == 0x1D79
private fun isNagariBengali(c: CodePoint) = c in codeRange[SHEET_NAGARI_BENGALI_VARW]
private fun isKartvelianCaps(c: CodePoint) = c in codeRange[SHEET_KARTULI_CAPS_VARW]
private fun isDiacriticalMarks(c: CodePoint) = c in codeRange[SHEET_DIACRITICAL_MARKS_VARW]
private fun isPolytonicGreek(c: CodePoint) = c in codeRange[SHEET_GREEK_POLY_VARW]
private fun isExtC(c: CodePoint) = c in codeRange[SHEET_EXTC_VARW]
private fun isExtD(c: CodePoint) = c in codeRange[SHEET_EXTD_VARW]
private fun isHangulCompat(c: CodePoint) = c in codeRangeHangulCompat
// underscored name: not a charset
private fun _isCaps(c: CodePoint) = Character.isUpperCase(c) || isKartvelianCaps(c)
private fun extAindexX(c: CodePoint) = (c - 0x100) % 16
private fun extAindexY(c: CodePoint) = (c - 0x100) / 16
private fun extBindexX(c: CodePoint) = (c - 0x180) % 16
private fun extBindexY(c: CodePoint) = (c - 0x180) / 16
private fun runicIndexX(c: CodePoint) = (c - 0x16A0) % 16
private fun runicIndexY(c: CodePoint) = (c - 0x16A0) / 16
private fun kanaIndexX(c: CodePoint) = (c - 0x3040) % 16
private fun kanaIndexY(c: CodePoint) =
if (c in 0x31F0..0x31FF) 12
else if (c in 0x1B000..0x1B00F) 13
else (c - 0x3040) / 16
private fun cjkPunctIndexX(c: CodePoint) = (c - 0x3000) % 16
private fun cjkPunctIndexY(c: CodePoint) = (c - 0x3000) / 16
private fun cyrilicIndexX(c: CodePoint) = (c - 0x400) % 16
private fun cyrilicIndexY(c: CodePoint) = (c - 0x400) / 16
private fun fullwidthUniIndexX(c: CodePoint) = (c - 0xFF00) % 16
private fun fullwidthUniIndexY(c: CodePoint) = (c - 0xFF00) / 16
private fun uniPunctIndexX(c: CodePoint) = (c - 0x2000) % 16
private fun uniPunctIndexY(c: CodePoint) = (c - 0x2000) / 16
private fun unihanIndexX(c: CodePoint) = (c - 0x3400) % 256
private fun unihanIndexY(c: CodePoint) = (c - 0x3400) / 256
private fun greekIndexX(c: CodePoint) = (c - 0x370) % 16
private fun greekIndexY(c: CodePoint) = (c - 0x370) / 16
private fun thaiIndexX(c: CodePoint) = (c - 0xE00) % 16
private fun thaiIndexY(c: CodePoint) = (c - 0xE00) / 16
private fun symbolIndexX(c: CodePoint) = (c - 0xE000) % 16
private fun symbolIndexY(c: CodePoint) = (c - 0xE000) / 16
private fun armenianIndexX(c: CodePoint) = (c - 0x530) % 16
private fun armenianIndexY(c: CodePoint) = (c - 0x530) / 16
private fun kartvelianIndexX(c: CodePoint) = (c - 0x10D0) % 16
private fun kartvelianIndexY(c: CodePoint) = (c - 0x10D0) / 16
private fun ipaIndexX(c: CodePoint) = (c - 0x250) % 16
private fun ipaIndexY(c: CodePoint) = (c - 0x250) / 16
private fun latinExtAddX(c: CodePoint) = (c - 0x1E00) % 16
private fun latinExtAddY(c: CodePoint) = (c - 0x1E00) / 16
private fun cherokeeIndexX(c: CodePoint) = (c - 0x13A0) % 16
private fun cherokeeIndexY(c: CodePoint) = (c - 0x13A0) / 16
private fun insularIndexX(c: CodePoint) =
if (c == 0x1D79) 0 else (c - 0xA770) % 16
private fun insularIndexY(c: CodePoint) =
if (c == 0x1D79) 0 else (c - 0xA770) / 16
private fun nagariIndexX(c: CodePoint) = (c - 0x900) % 16
private fun nagariIndexY(c: CodePoint) = (c - 0x900) / 16
private fun kartvelianCapsIndexX(c: CodePoint) = (c - 0x1C90) % 16
private fun kartvelianCapsIndexY(c: CodePoint) = (c - 0x1C90) / 16
private fun diacriticalMarksIndexX(c: CodePoint) = (c - 0x300) % 16
private fun diacriticalMarksIndexY(c: CodePoint) = (c - 0x300) / 16
private fun polytonicGreekIndexX(c: CodePoint) = (c - 0x1F00) % 16
private fun polytonicGreekIndexY(c: CodePoint) = (c - 0x1F00) / 16
private fun extCIndexX(c: CodePoint) = (c - 0x2C60) % 16
private fun extCIndexY(c: CodePoint) = (c - 0x2C60) / 16
private fun extDIndexX(c: CodePoint) = (c - 0xA720) % 16
private fun extDIndexY(c: CodePoint) = (c - 0xA720) / 16
/*
#!/usr/bin/python3
@@ -1737,9 +1758,7 @@ s = "charseq"
for c in s:
#print(ord(c))
print("0x{0:x}".format(ord(c)))
*/
// acegijmnopqrsuvwxyzɱɳʙɾɽʒʂʐʋɹɻɥɟɡɢʛȵɲŋɴʀɕʑçʝxɣχʁʜʍɰʟɨʉɯuʊøɘɵɤəɛœɜɞʌɔæɐɶɑɒɚɝɩɪʅʈʏʞⱥⱦⱱⱳⱴⱶⱷⱸⱺⱻꜥꜩꜫꜭꜯꜰꜳꜵꜷꜹꜻꜽꜿꝋꝍꝏꝑꝓꝕꝗꝙꝛꝝꝟꝡꝫꝯꝳꝴꝵꝶꝷꝺꝼꝿꞁꞃꞅꞇꞑꞓꞔꞛꞝꞡꞥꞧꞩꞮꞷꟺ\uA7AF\uA7B9\uA7C3\uA7CA
*/ // acegijmnopqrsuvwxyzɱɳʙɾɽʒʂʐʋɹɻɥɟɡɢʛȵɲŋɴʀɕʑçʝxɣχʁʜʍɰʟɨʉɯuʊøɘɵɤəɛœɜɞʌɔæɐɶɑɒɚɝɩɪʅʈʏʞⱥⱦⱱⱳⱴⱶⱷⱸⱺⱻꜥꜩꜫꜭꜯꜰꜳꜵꜷꜹꜻꜽꜿꝋꝍꝏꝑꝓꝕꝗꝙꝛꝝꝟꝡꝫꝯꝳꝴꝵꝶꝷꝺꝼꝿꞁꞃꞅꞇꞑꞓꞔꞛꞝꞡꞥꞧꞩꞮꞷꟺ\uA7AF\uA7B9\uA7C3\uA7CA
private val lowHeightLetters = intArrayOf(0x61,0x63,0x65,0x67,0x69,0x6a,0x6d,0x6e,0x6f,0x70,0x71,0x72,0x73,0x75,0x76,0x77,0x78,0x79,0x7a,0x271,0x273,0x299,0x27e,0x27d,0x292,0x282,0x290,0x28b,0x279,0x27b,0x265,0x25f,0x261,0x262,0x29b,0x235,0x272,0x14b,0x274,0x280,0x255,0x291,0xe7,0x29d,0x78,0x263,0x3c7,0x281,0x29c,0x28d,0x270,0x29f,0x268,0x289,0x26f,0x75,0x28a,0xf8,0x258,0x275,0x264,0x259,0x25b,0x153,0x25c,0x25e,0x28c,0x254,0xe6,0x250,0x276,0x251,0x252,0x25a,0x25d,0x269,0x26a,0x285,0x288,0x28f,0x29e,0x2c65,0x2c66,0x2c71,0x2c73,0x2c74,0x2c76,0x2c77,0x2c78,0x2c7a,0x2c7b,0xa725,0xa729,0xa72b,0xa72d,0xa72f,0xa730,0xa731,0xa733,0xa735,0xa737,0xa739,0xa73b,0xa73d,0xa73f,0xa74b,0xa74d,0xa74f,0xa751,0xa753,0xa755,0xa757,0xa759,0xa75b,0xa75d,0xa75f,0xa761,0xa76b,0xa76f,0xa773,0xa774,0xa775,0xa776,0xa777,0xa77a,0xa77c,0xa77f,0xa781,0xa783,0xa785,0xa787,0xa791,0xa793,0xa794,0xa79b,0xa79d,0xa79f,0xa7a1,0xa7a5,0xa7a7,0xa7a9,0xa7ae,0xa7b7,0xa7fa,0xa7af,0xa7b9,0xa7c3,0xa7ca).toSortedSet()
// TŢŤƬƮȚͲΤТҬᛏṪṬṮṰϮϯⴶꚌꚐ
private val kernTees = intArrayOf(0x54,0x162,0x164,0x1ac,0x1ae,0x21a,0x372,0x3a4,0x422,0x4ac,0x16cf,0x1e6a,0x1e6c,0x1e6e,0x1e70,0x2ca6,0x3ee,0x3ef,0x2d36,0xa68c,0xa690,0x13a2,0x16e0,0xa4d4).toSortedSet()

Binary file not shown.

Before

Width:  |  Height:  |  Size: 48 KiB

After

Width:  |  Height:  |  Size: 59 KiB

View File

@@ -16,21 +16,34 @@ OOO
바람결에 실려온 당신의 nostalgia와 어지러이 섞인 regret의 memories
x86 또는 80x86은 인텔이 개발한 마이크로프로세서 계열을 부르는 말이자, 이들과 호환되는 프로세서들에서 사용한 명령어 집합
구조들을 통칭하는 말이다. x86 아키텍처는 데스크톱 컴퓨터 시장에서 매우 널리 쓰이며, PowerPC 같이 좀 더 근대적인 아키텍처를
사용한 프로세서들이 x86과 경쟁했으나 그다지 많은 시장 점유율을 확보하지는 못했다.
x86 또는 80x86은 인텔이 개발한 마이크로프로세서 계열을 부르는 말이자, 이들과 호환되는 프로세서들에서 사용한
명령어 집합 구조들을 통칭하는 말이다. x86 아키텍처는 데스크톱 컴퓨터 시장에서 매우 널리 쓰이며, PowerPC
같이 좀 더 근대적인 아키텍처를 사용한 프로세서들이 x86과 경쟁했으나 그다지 많은 시장 점유율을 확보하지는 못했다.
x86 또는 80x86이라는 이름은 여기에 속하는 초기의 프로세서들 이름이 모두 80으로 시작해서 86으로 끝났기 때문에 붙여졌다.
여기에는 8086, 80186, 80286, 386, 486이 포함되며, 숫자로 상표를 등록할 수 없었기 때문에 그 뒤로는 펜티엄과 같은 별도의
이름을 사용하게 되었다. 그러나 586, 686과 같은 이름은 아직까지도 (비공식적으로) 사용되며, 전체 아키텍처를 나타내는 말에도
그 흔적이 남아 있다.
x86 또는 80x86이라는 이름은 여기에 속하는 초기의 프로세서들 이름이 모두 80으로 시작해서 86으로 끝났기 때문에
붙여졌다. 여기에는 8086, 80186, 80286, 386, 486이 포함되며, 숫자로 상표를 등록할 수 없었기 때문에 그
뒤로는 펜티엄과 같은 별도의 이름을 사용하게 되었다. 그러나 586, 686과 같은 이름은 아직까지도 (비공식적으로)
사용되며, 전체 아키텍처를 나타내는 말에도 그 흔적이 남아 있다.
x86 아키텍처를 사용하는 최초의 프로세서는 1978년에 발표된 인텔 8086으로, 이전 프로세서인 인텔 8080과 어셈블리어 단에서
호환되도록 설계되었다. 인텔 8086은 3년 후에 IBM PC의 표준 프로세서로 채택되었다. IBM PC는 그 후로 계속 성장하여 개인용 컴퓨터 업계의 표준이 되었으며, 그에 따라 x86 아키텍처는 매우 성공적인 명령 집합 아키텍처가 되었다. 사이릭스, 일본
전기 주식회사(NEC), IBM, 트랜스메타 등의 회사들이 x86 아키텍처를 사용하는 프로세서를 생산했으며, 그중 AMD의 애슬론 계열
프로세서들은 펜티엄에 미치지는 못 하지만 상당한 시장 점유율을 차지하고 있다.
x86 아키텍처를 사용하는 최초의 프로세서는 1978년에 발표된 인텔 8086으로, 이전 프로세서인 인텔 8080과
어셈블리어 단에서 호환되도록 설계되었다. 인텔 8086은 3년 후에 IBM PC의 표준 프로세서로 채택되었다. IBM PC는
그 후로 계속 성장하여 개인용 컴퓨터 업계의 표준이 되었으며, 그에 따라 x86 아키텍처는 매우 성공적인 명령 집합
아키텍처가 되었다. 사이릭스, 일본 전기 주식회사(NEC), IBM, 트랜스메타 등의 회사들이 x86 아키텍처를 사용하는
프로세서를 생산했으며, 그중 AMD의 애슬론 계열 프로세서들은 펜티엄에 미치지는 못 하지만 상당한 시장 점유율을
차지하고 있다.
x86 아키텍처는 가변 길이 명령을 쓰는 CISC 설계를 채용했으며, 하위 호환성에 중점을 두고 있다. x86 아키텍처는 다른 아키텍처와
같이 워드 경계에 맞춰서 메모리를 읽는 것이 효율적이긴 하지만, 워드 경계에 걸치는 메모리도 한 번에 접근할 수 있다. 워드들은
최하위 바이트부터 최상위 바이트까지 순서대로 (리틀 엔디안) 저장된다. 현재의 x86 프로세서들은 명령들을 내부적으로 더 작은
단위로 쪼개서 RISC와 비슷한 내부 아키텍처에서 수행한다.
x86 아키텍처는 가변 길이 명령을 쓰는 CISC 설계를 채용했으며, 하위 호환성에 중점을 두고 있다. x86 아키텍처는
다른 아키텍처와 같이 워드 경계에 맞춰서 메모리를 읽는 것이 효율적이긴 하지만, 워드 경계에 걸치는 메모리도 한
번에 접근할 수 있다. 워드들은 최하위 바이트부터 최상위 바이트까지 순서대로 (리틀 엔디안) 저장된다. 현재의
x86 프로세서들은 명령들을 내부적으로 더 작은 단위로 쪼개서 RISC와 비슷한 내부 아키텍처에서 수행한다.
EVE Online 전문가 펀지 사망했습니다! ㅗㅜㅑ
AVA 고인물 DXFunz 펀즈펀즈파누털 ㅍㅈㅍㅈㅍㄴㅌ
씬춘 썅쑝쑈를 썅그릴라 호텔테서 연 씬찐 썅쑝 가수 쏭쌍썽씨가 쩌끼 쩌 미트 쏘씨찌 쏘쓰 쓰파게티는 깐쑈쌔우 크림
쏘쓰 쏘씨찌 쏘쓰 쓰테이크보다 비싸다며 단식에 들어가 호텔의 빈축을 사고 있습니다
헌 상품을 새 쌍품으로 만들애내는 쌍장사가 저기 가능 쌍짱싸가 쌔 쌍 쌍짱싸냐 헌 쌍 쌍짱싸냐고 쏘릴 질러 찌나가던
씬씬얘씨가 쏘쓰라치게 놀랐다고 합니다
쓰티븐 씨걸씨의 쏘울메이트로 알려진 쑸싸씀이 맨해튼에 쎈쎄이쎤을 쑾쏙을 쌑쌑이
왵 윁 왰 웼