Skip to content

Instantly share code, notes, and snippets.

@ReiFan49
Created May 25, 2021 02:51
Show Gist options
  • Save ReiFan49/989c4c285711eaca294bc2466e995569 to your computer and use it in GitHub Desktop.
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.
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