Справочник функций

Ваш аккаунт

Войти через: 
Забыли пароль?
Регистрация
Информацию о новых материалах можно получать и без регистрации:

Последние темы форума

Показать новые сообщения »

Почтовая рассылка

Подписчиков: 11634
Последний выпуск: 19.06.2015

Создание моноширинного векторного шрифта для Java2ME

Источник: MobiLab.ru
Автор: Shadowsshot
Дата: 21 октября 2009 года

Начав более-менее активно писать для сотовых телефонов на Java 2 ME я быстро обнаружил, что выводить на экран растровые шрифты не слишком удобно. Причин несколько - при смене размера экрана шрифт получается или слишком маленьким или слишком большим, его нельзя повернуть или нормально масштабировать. Кроме того так как шрифт храниться в виде картинки - для вывода затрачиваются довольно много ресурсов. Решением может стать простой векторный шрифт, созданию которого посвящена данная статья. В связи с ориентацией на freeware использоваться будут только бесплатные продукты.

Начнем мы с рисования символов в редакторе Inkspace. Каждый символ будет рисоваться отдельно на листе с сеткой максимального размера 9 на 9.

Никаких ограничений на точность символов нет, просто алгоритм вывода придется немного подкорректировать. Шаблоном нам послужит буква А русского алфавита с кодом 192. Для этого распакуем архив InkFontSVG.zip в отдельную папку и в подпапке Font откроем Char192.svg.

Создание моноширинного векторного шрифта для Java2ME

Для правки нужно запомнить несколько важных правил. При рисовании пользоваться только инструментом Рисовать произвольные контуры, при этом рисуем отрезками, это значит после проведения каждой линии нажимаем Esc и только потом чертим следующий отрезок. Прямые рисуются только с привязкой к узлам сетки.

Рисовать произвольные контуры (F6) Рисовать произвольные контуры (F6)

После перерисовки символа можно приступить к правке любого другого символа из стандартной кодовой таблицы. Для этого из той же папки Font открывается любой другой символ и правится согласно вашим потребностям. Если в папке Font отсутствует файл с кодом нужного символа в результирующем шрифте это будет пустое место (пробел). В представленном архиве  InkFontSVG.zip лежит типичный шрифт без засечек в кодировке Windows 1251, без символов с кодами от 0 до 29, наиболее удобный при программировании под Windows.

Для использования шрифта в своих программах на сотовом телефоне, его необходимо конвертировать. Для этого используется утилита InkToFont.exe работающая из командной строки. Для конвертации запускаем ее из того же каталога  в котором лежит набор символов в формате SVG, а на выходе получаем файл InkFont.txt. В зависимости от количества и сложности символов результирующий файл будет занимать от 1 до 10 килобайт, мой шрифт занимает 5.

Утилиту можно запускать из Windows двойным щелчком, но лучше это делать из окна командной строки, из-за возможных сообщений об ошибках конвертации. При этом утилита сообщает в каком файле и в какой строке обнаружилась ошибка. Типичные ошибки это рисование кривых вместо линий и рисование не по точкам сетки, об этих ошибках программа рапортует ошибкой Err0 но конвертировать продолжает, просто в этом символе не будет ошибочно нарисованной линии.

Для интеграции шрифта в свою программу достаточно включить его содержимое в основной класс мидлета и задать ширину и высоту шрифта в переменных FSizeX и FSizeY. К примеру так.

 //Печать символа нормальной толщины
    public void PrintInkCharN(Graphics gg, int cchar,int cdx,int cdy,int mdx,int mdy)
    {
        int i=0;
        while(InkFnt[cchar].charAt(i)!='Z')
        {
        gg.drawLine(cdx+((((int)InkFnt[cchar].charAt(i))-48)*mdx/FSizeX),
                    cdy+((((int)InkFnt[cchar].charAt(i+1))-48)*mdy/FSizeY),
        cdx+((((int)InkFnt[cchar].charAt(i+2))-48)*mdx/FSizeX),
        cdy+((((int)InkFnt[cchar].charAt(i+3))-48)*mdy/FSizeY)); 
        i=i+4;
        }
    }

Все, на этом загрузка ресурса завершена, со шрифтом можно работать используя массив строк InkFnt. Формат его предельно прост, всего в нем 256 строк, каждая из которых соответствует символу на экране. Внутри строки может быть всего два вида данных: четыре цифры определяющие начало и конец линии в сетке от 9 на 9 и признак конца строки - английская буква Z. Формат можно неограниченно расширять, но именно в таком виде он максимально прост в использовании.

Теперь достаточно написать процедуры для вывода его на экран, они предельно просты и понятны. К примеру вывод символа в заданную точку экрана с заданными размерами. На вход процедуре предается контекст графики, код символа, координаты x и y левого верхнего угла прямоугольника в который будет выведен символ, размер символа по ширине и высоте (масштабный коэффициент).

  //Печать символа нормальной толщины
    public void PrintInkCharN(Graphics gg, int cchar,int cdx,int cdy,int mdx,int mdy)
    {
        int i=0;
        while(InkFnt[cchar].charAt(i)!='Z')
        {
        gg.drawLine(cdx+((((int)InkFnt[cchar].charAt(i))-48)*mdx/FSizeX),
                    cdy+((((int)InkFnt[cchar].charAt(i+1))-48)*mdy/FSizeY),
        cdx+((((int)InkFnt[cchar].charAt(i+2))-48)*mdx/FSizeX),
        cdy+((((int)InkFnt[cchar].charAt(i+3))-48)*mdy/FSizeY)); 
        i=i+4;
        }
    }

Процедура печати строки символов еще проще, на вход надо задать контекст графики, строку символов, координаты x и y левого верхнего угла прямоугольника в который будет выведен текст и размер символа по ширине и высоте.

//Печать строки нормальной толщины
    public void PrintInkLineN(Graphics gg,String cline,int cdx,int cdy,int mdx,int mdy)
    {
        for(int j=0;j<cline.length();j++){PrintInkCharN(gg,cline.charAt(j),(j*mdx)+cdx,cdy,mdx,mdy);}
    }

Используя несложные преобразования легко написать вывод утолщенного шрифта, курсива или вывод символа повернутого на произвольный угол. Внутри архива InkFontSVG.zip находится исходник TestFont.java содержащий несколько подобных процедур.

Печать символа Печать строки Пример
PrintInkCharN PrintInkLineN Создание моноширинного векторного шрифта для Java2ME
PrintInkCharB PrintInkLineB Создание моноширинного векторного шрифта для Java2ME
PrintInkCharI PrintInkLineI Создание моноширинного векторного шрифта для Java2ME
PrintInkCharA PrintInkLineA Создание моноширинного векторного шрифта для Java2ME

В папке Java2ME находится мидлет FontTest.jar готовый к загрузке в телефон, он выводит на экран все 256 символов шрифтом 8 на 8.

Создание моноширинного векторного шрифта для Java2ME

Так как размер шрифта напрямую зависит от количества задействованных в нем символов, а сложные диакритические знаки с кодами от 128 до 191 используются редко, выбросив их мы получим шрифт размером 3 килобайта, добавив смещение кода на 29 первых неиспользованных символа мы выиграем еще 4х29=116 байт. В общем просторы для оптимизации безграничны, но для тестового примера достаточно и этого, тем более что о существовании 1024 Demo Compo на Java2ME я не слышал.

P.S. Проект создавался и тестировался в NetBean, поэтому все русскоязычные комментарии в кодировке UTF-8.

Оставить комментарий

Комментарий:
можно использовать BB-коды
Максимальная длина комментария - 4000 символов.
 
Реклама на сайте | Обмен ссылками | Ссылки | Экспорт (RSS) | Контакты
Добавить статью | Добавить исходник | Добавить хостинг-провайдера | Добавить сайт в каталог