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

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

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

Image of Char192


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


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

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

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

Для интеграции шрифта в свою программу достаточно включить его содержимое в основной класс мидлета и задать ширину и высоту шрифта в переменных FSizeX и FSizeY. К примеру так.
   
public class TestFont extends MIDlet {
    public int FSizeX=7;public int FSizeY=8;
    public String InkFnt[]={"Z","Z","Z","Z","Z","Z","Z","Z","Z"......,"434723432314142525452517Z"};

Все, на этом загрузка ресурса завершена, со шрифтом можно работать используя массив строк 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.rar находится исходникTestFont.java содержащий несколько подобных процедур.

Печать символаПечать строкиПример
PrintInkCharNPrintInkLineN
PrintInkCharBPrintInkLineB
PrintInkCharIPrintInkLineI
PrintInkCharAPrintInkLineA

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

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

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


Автор:Shadowsshot




Наши соцсети

Подписаться Facebook Подписаться Вконтакте Подписаться Twitter Подписаться Google Подписаться Telegram

Популярное

Ссылки

Новости [1] [2] [3]... Android/ iOS/ J2ME[1] [2] [3]) Android / Архив

Рейтинг@Mail.ru Яндекс.Метрика
MobiLab.ru © 2005-2018
При использовании материалов сайта ссылка на www.mobilab.ru обязательна