Created
May 25, 2021 02:51
-
-
Save ReiFan49/989c4c285711eaca294bc2466e995569 to your computer and use it in GitHub Desktop.
text to pixel coordinate for 東方夢終劇. credit to @danmaq for dnh code of this.
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
ImageCache = Struct.new(:filename, :data) do | |
def load | |
return unless File.exists?(self.filename) | |
self.data = nil | |
end | |
end | |
TextCache = Struct.new(:image_id, :x, :y, :width, :height, :kerning, :spacing) | |
module CtC | |
module SJIS | |
GAPPOS = [ | |
0, 62, 108, 115, 122, 137, 145, 146, 156, 182, 208, 291, 354, 378, 401, 425, 458, 473, 491, 523, 553, 576, 577, 606, 700, | |
763, 888, 951, 1076, 1139, 1264, 1327, 1452, 1515, 1640, 1703, 1828, 1891, 2016, 2079, 2204, 2267, 2392, 2455, 2580, 2643, 2768, 2831, 2956, 3019, | |
3144, 3207, 3332, 3395, 3520, 3571, 3665, 3728, 3853, 3916, 4041, 4104, 4229, 4292, 4417, 4480, 4605, 4668, 4793, 4856, 4981, 5044, 5169, 5232, | |
5357, 5420, 5545, 5608, 5733, 5796, 5921, 5984, 6109, 6172, 6297, 6360, 6485, 6548, 6673, 6736, 6861, 6924, 6961, 6996, 7121, 7184, 7309, 7321 | |
].freeze | |
GAPLEN = [ | |
33088, 1, 11, 8, 11, 7, 4, 82, 7, 7, 4, 78, 1, 8, 8, 105, 15, 1, 13, 641, 1, 8, 1, 258, 67, | |
1, 67, 1, 67, 1, 67, 1, 67, 1, 67, 1, 67, 1, 67, 1, 67, 1, 67, 1, 67, 1, 67, 1, 67, 1, | |
67, 1, 67, 1, 67, 44, 67, 1, 67, 1, 67, 1, 67, 1, 67, 1, 67, 1, 67, 1, 16451, 1, 67, 1, | |
67, 1, 67, 1, 67, 1, 67, 1, 67, 1, 67, 1, 67, 1, 67, 1, 67, 1, 4023, 1, 67, 1, 67, 2 | |
].freeze | |
X = 1 | |
WIDTH = 20 | |
HEIGHT = 21 | |
KERNING = 3 | |
SPACING = 1 | |
end | |
module ASCII | |
module Constants | |
SPACE = -1 | |
CRLF = -2 | |
end | |
fontSizeData = Struct.new(:x_table, :x_right_cut, :y, :height, :kerning, :spacing, :line_height) | |
SIZE = { | |
12 => fontSizeData.new( | |
[ | |
7, 25, 44, 66, 88, 111, 134, 152, 171, 190, 212, 235, 253, 275, 293, 319, 340, 358, 380, 401, 423, 445, 466, 487, | |
509, 530, 548, 566, 588, 611, 633, 654, 677, 701, 723, 746, 768, 790, 812, 835, 858, 876, 896, 919, 941, 964, | |
7, 30, 52, 74, 97, 119, 142, 164, 187, 211, 234,256, 279, 297, 320, 338, 358, 384, 404, 424, 445, 466, 487, 508, 529, | |
549, 570, 588, 608, 629, 647, 669, 690, 711, 732, 753, 773, 793, 813, 835, 856, 879, 901, 922, 943, 962, 979, 997, | |
], | |
[ 38, 2], | |
470, 20, 13, 5, 1 | |
), | |
16 => fontSizeData.new( | |
[ | |
8, 25, 43, 66, 87, 111, 134, 151, 169, 187, 210, 232, 249, 272, 289, 316, 337, 354, 375, 396, 419, 440, 462, 483, | |
504, 525, 542, 559, 582, 604, 627, 648, 671, 696, 718, 741, 764, 786, 808, 832, 854, 871, 891, 914, 936, 959, | |
8, 31, 53, 76, 99, 121, 145, 167, 191, 215, 238, 261, 284, 301, 324, 342, 361, 388, 407, 428, 448, 469, 490, 511, 531, | |
551, 572, 588, 607, 629, 645, 668, 688, 709, 730, 750, 770, 790, 810, 831, 852, 875, 897, 918, 939, 957, 973, 990 | |
], | |
[ 44, 7], | |
421, 24, 12, 5, 1 | |
), | |
24 => fontSizeData.new( | |
[ | |
7, 21, 39, 62, 84, 109, 133, 148, 164, 180, 204, 228, 242, 266, 281, 310, 332, 346, 368, 389, 413, 434, 455, 476, | |
498, 519, 533, 548, 572, 595, 619, 640, 664, 690, 713, 737, 761, 783, 806, 831, 855, 869, 889, 912, 935, 959, | |
7, 31, 54, 77, 102, 124, 149, 172, 196, 223, 247, 271, 294, 310, 333, 349, 368, 398, 416, 436, 456, 477, 497, 519, 538, | |
558, 579, 593, 611, 633, 646, 669, 690, 710, 730, 751, 769, 789, 808, 829, 851, 875, 897, 918, 940, 955, 968, 984 | |
], | |
[ 42, 10 ], | |
355, 32, 9, 6, 3 | |
), | |
32 => fontSizeData.new( | |
[ | |
5, 27, 55, 89, 122, 158, 194, 216, 241, 268, 302, 338, 360, 395, 419, 461, 494, 516, 550, 580, 616, 647, 680, 711, 744, 776, 798, 820, 855, 892, 927, 957, | |
5, 43, 77, 112, 148, 182, 214, 252, 287, 309, 340, 374, 407, 443, 477, 514, 546, 583, 618, 652, 688, 723, 759, 797, 833, 869, 902, 926, | |
4, 29, 57, 100, 129, 160, 189, 221, 252, 283, 312, 343, 373, 396, 424, 456, 478, 513, 542, 575, 604, 634, 664, 694, 722, 754, 787, 822, 855, 887, 919, 942, 964, 988 | |
], | |
[ 31, 62, -8 ], | |
230, 40, 15, 6, 3 | |
), | |
48 => fontSizeData.new( | |
[ | |
8, 36, 72, 117, 162, 211, 260, 289, 322, 355, 402, 449, 479, 526, 556, 614, 658, 686, 730, 772, 819, 862, 904, 947, 989, | |
8, 37, 66, 113, 160, 208, 250, 298, 350, 396, 443, 491, 537, 582, 631, 679, 707, 747, 794, 840, 888, 934, 982, | |
8, 56, 104, 149, 198, 244, 293, 346, 394, 442, 489, 520, 567, 598, 636, 696, 732, 773, 813, 855, 895, 938, 976, | |
8, 49, 78, 114, 158, 185, 232, 272, 313, 354, 394, 431, 471, 509, 551, 595, 642, 687, 729, 771, 803, 829, 861 | |
], | |
[ -7, -3, 10, 104 ], | |
-1, 58, 18, 8, 4 | |
), | |
}.freeze | |
end | |
end | |
# x_table, x_cut, spacing, y, height, kerning, spacing | |
def createTextCache(text, size: 24) | |
skip_next = false | |
caches = [] | |
text.size.times do |i| | |
char = text[i].ord | |
# print '>' unless skip_next | |
# print [char].to_s | |
next (skip_next = false) if skip_next | |
cache = nil | |
if char < 128 then | |
# ASCII | |
size_data = CtC::ASCII::SIZE[size] | |
if char <= 32 then | |
x, y, width = CtC::ASCII::Constants::SPACE, CtC::ASCII::Constants::SPACE , size_data.spacing | |
elsif text[i,2] == '\n' then | |
x, y, width = CtC::ASCII::Constants::CRLF, CtC::ASCII::Constants::CRLF, 0 | |
skip_next = true | |
else | |
char_i = char - 32 | |
y_line = 1.upto(char_i).reduce(0) do |x,j| x + (size_data.x_table[j-1]>size_data.x_table[j] ? 1 : 0) end | |
x, y = size_data.x_table[char_i - 1], y_line * size_data.height + size_data.y | |
if (char_i >= size_data.x_table.size) || | |
(size_data.x_table[char_i] - size_data.x_table[char_i - 1] < 0) then | |
width = 1024 - size_data.x_right_cut[y_line] - size_data.x_table[char_i - 1] | |
else | |
width = size_data.x_table[char_i] - size_data.x_table[char_i - 1] | |
end | |
end | |
height = size_data.height | |
kerning = size_data.kerning | |
spacing = size_data.line_height | |
cache = TextCache.new(-1, x, y, width, height, kerning, spacing) | |
else | |
# Shift JIS | |
text[i,2] | |
pos = [text[i].ord * 256 + text[i+1].ord, 0].max | |
CtC::SJIS::GAPPOS.each_index do |j| | |
gap = CtC::SJIS::GAPPOS[j] | |
pos -= CtC::SJIS::GAPLEN[j] if pos > gap | |
end | |
pos = [0, pos].max | |
y = ((pos / 51) * CtC::SJIS::HEIGHT) | |
cache = TextCache.new( | |
1 + (y / 1008), | |
pos % 51 * CtC::SJIS::WIDTH + CtC::SJIS::X, | |
y % 1008, | |
CtC::SJIS::WIDTH, | |
CtC::SJIS::HEIGHT, | |
CtC::SJIS::KERNING, | |
CtC::SJIS::SPACING | |
) | |
skip_next = true | |
end | |
caches << cache if cache | |
end | |
caches | |
end | |
if __FILE__ == $0 then | |
if ARGV.empty? then | |
while line = $stdin.gets | |
next if line.chomp.empty? | |
sjis_line = line.chomp.force_encoding('sjis') | |
createTextCache(sjis_line.b).each do |cache| | |
p cache | |
end | |
end | |
else | |
ARGV.each do |line| | |
next if line.chomp.empty? | |
sjis_line = line.chomp.force_encoding('sjis') | |
p sjis_line | |
createTextCache(sjis_line.b).each do |cache| | |
p cache | |
end | |
end | |
end | |
end |
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment