Какую реальную проблему вы хотите решить?
Неужели строка в кодировке UTF-8 занимает три байта на символ?Если да, переключитесь на UTF-16.В противном случае не вините UTF-8.(Объяснение: UTF-8 - это просто алгоритм для преобразования последовательности целых чисел в последовательность байтов. Он не имеет ничего общего с группировкой символов в кодовых страницах. Это, в свою очередь, то, что кодовые точки Unicode являютсяfor.)
Неужели кодовые точки Unicode распределены по многим «кодовым страницам» (где «кодовая страница» означает блок из 256 смежных кодовых точек Unicode)?Если да, придумайте отображение из кодовых точек Unicode (0x000000 - 0x10FFFF) в меньший набор целых чисел.С точки зрения памяти это должно стоить не более 4 байтов, умноженных на количество символов, которое вам действительно нужно.Время поиска составило бы приблизительно 24 обращения к памяти, 24 целочисленных сравнения и 24 инструкции ветвления.(На самом деле это будет бинарный поиск в древовидной карте.) И если это слишком дорого, вы можете использовать отображение на основе хеш-таблицы.
Это что-то еще?Затем, пожалуйста, приведите несколько примеров, чтобы лучше понять вашу проблему.
Насколько я понимаю, вам, вероятно, следует написать небольшую служебную программу, которая принимает в качестве входных данных набор кодовых точек Unicode, которые вы хотите использовать в своемприложение, а затем генерирует код и данные для отображения текстов.Возникают вопросы:
- Приходится ли вам использовать определенный формат растрового шрифта или вы сами напишите функцию
displayText
? - Есть ли какая-либо причина против использования Юникода для всехстрок и преобразовать их в оптимизированную для растровых изображений кодировку только для того времени, когда вы визуализируете текст?Преобразование кодировки, конечно, будет внутренним по отношению к методу
displayText
и не будет видимым для нормального кода приложения. - Просто не представляет интереса: специфична ли проблема для определенного языка программирования или среды?
Обновление :
Я предполагаю, что вашей основной проблемой является какая-то функция, подобная этой:
Rectangle position(int codepoint)
Если бы мне пришлось это сделать, я быначать с одного растрового изображения для каждого символа.Именем файла растрового изображения будет кодовая точка, так что «большая картинка» может быть легко восстановлена, на случай, если вы найдете еще несколько символов, которые вам нужны.Подготовка состоит из следующих шагов:
- Загрузка всех растровых изображений и определение их размеров.Результатом этого шага является карта из целых чисел в пары (ширина, высота).
- Вычислите правильную компоновку для изображений персонажей на большой картинке и запомните, где был размещен каждый символ.Сохранить большую картинку.Сохраните отображение из кодовых точек в (x, y, ширина, высота) в другой файл.Это может быть текстовый файл или, если у вас нет места на диске, бинарный файл.Детали не имеют значения.
Функция displayText
будет тогда работать следующим образом:
void displayText(int x, int y, String s) {
for (char c : s.toCharArray()) { // TODO: handle code points correctly
int codepoint = c;
Rectangle position = positions.get(codepoint);
if (position != null) {
// draw bitmap
x += position.width;
}
}
}
Map<Integer, Rectangle> positions = loadPositionsFromFile();
Теперь единственная оставшаяся проблема - как эта карта может быть представленав памяти, используя как можно меньше памяти, и при этом быть достаточно быстрым.Это, конечно, зависит от вашего языка программирования.
Представление в памяти может быть несколькими массивами, которые содержат x, y, width, height.Для каждого элемента должно быть достаточно 16-битного целого числа.И, вероятно, вам нужно всего лишь 8 бит для ширины и высоты в любом случае.Затем другой массив отобразит кодовую точку на индекс в positionData
(или какое-то специальное значение, если кодовая точка недоступна).Это будет массив из 20000 16-битных целых чисел, так что в итоге вы получите:
- 2000 * (2 + 2 + 1 + 1) = 12000 байт для
positionX
, positionY
, positionWidth
и positionHeight
- 20000 * 2 = 40000 байт для
codepointToIndexInPositionArrays
, если вместо карты используется массив.
По сравнению с размером самого растрового изображенияэто должно быть достаточно мало.А поскольку массивы не меняются, они могут находиться в постоянной памяти.