Версия для печати темы
Нажмите сюда для просмотра этой темы в оригинальном формате
Форум программистов > Java ME (J2ME) > Пример работы со шрифтами


Автор: shomer 12.11.2007, 22:57
Выкладываю вариант отрисовки своих шрифтов.
-------------------------------------------
Шрифт - png файл - белые буквы на прозрачной основе вида
для примера символы О и Р
где о-прозрачный пиксел х-белый

OOOOOOOOOO
OOXOOXXXOO
OXOXOXOOXO
OXOXOXXXOO
OOXOOXOOOO
OOOOOOOOOO
OOOXOOOOXO  линия меток конца символа

конструктор загружает шрифт из файла и по строке меток определяет ширину каждого символа
записывая в массив начало отображения каждого символа и его ширину.
Представлено три метода: отрисовка строки белым цветом, заданным цветом и цветом фона
и метод многострочной отрисовки текса с использованием \n и \t (перенос, табуляция).

пример мидлета на моем TS2050 выдает 7 fps.

Автор: javastic 13.11.2007, 11:06
Эмулятор от SE закрывается намертво после запуска мидлета.

Автор: eugine_s 14.11.2007, 18:26
Запустилось на эмуляторе K700.

Давай разбирать ошибки:

1. Бросается в глаза Demo.java 
Метод run(): 
            try{ Thread.sleep(20);}
            catch (Exception ex) {};

Зачем поток усыплять? 

2. Зачем используешь float ? Это далеко не тот случай когда нужно использовать флоат (вычисления с плавающей точкой занимают больше времени чем целочисленое исчисление).

3. Сам фпс как-то кривова-то считается, лучше в run() делать вот так:

засек время()
отрисовал экран: DrawScreen();
опять засек время и вывел фпс;

4. Собственно пункты 1-3 это лирическое отступление, а по теме вопроса:
Скажи, зачем тебе getRGB() от твоего шрифта? точнее доступ к каждой точке твоего шрифта? Это не правильно решение, если тебе нужно использовать в программе несколько шрифтов, то лучше в джарник закинуть два(или сколько надо) шрифтов. 
Соотвественно не нужно будет потом делать g.drawRGB() когда потребуется отрисовка буквы.

Что тебе нужно сделать, чтобы быстро работала отрисовка своего шрифта:
1. Сделать описание для каждой буквы(точнее каждого символа из твоего шрифта) в таком формате
(x,y,w), где х - х-координата, у - у-координата символа на картинке, w - ширина символа
а также для всех символов достаточно одной h = высоты (у всех же одинаковая высота?)
Это описание занеси в файл и в конструкторе твоего шрифта считай из файла в массив(ы), или создай 
final массивы в коде Font.java.

2. Конструктор шрифта делает: 
 - загружает картинку
 - если требуется инициализирует массив(ы) координат и размеров символов шрифта

3. Теперь твой DrawStr(String str, int x, int y) превращается в:
находим координаты символа, который нужно отрисовать и методом
g.drawRegion() рисуем твой символ. 
(вместо drawRegion можно использовать setClip + drawImage)



Автор: shomer 14.11.2007, 19:27
javastic-у
Пример запускал на Wireless Toolkit 2.5.1 эмуляторе. Работает почему то медленней чем на реальном телефоне раза в три четыре. 

eugine_s-у
1. без Thread.sleep(20) на тефоне не обрабатывает клавиатуру (реакция на нажатия отсутствует, пришлось вытаскивать аккумулятор). 
2. float для точности  
3. FPS кривой - точно.
4. в данном случае дань универсальности ( имеем потерю в скорости)
    получая меньший размер мидлета получаем больший расход памяти

Есть одна задумка   smile ( возможно изобретение колеса smile )...
нужно опробовать с   замером fPs... на разных телефонах

setClip + drawImage и drawRegion, пока не интересно.
Надо немного время размышлять однако

Автор: Samuil 15.11.2007, 07:37
Прозрачные пикселы на старых телефонах будут?

Автор: eugine_s 15.11.2007, 13:40
Цитата(shomer @  14.11.2007,  19:27 Найти цитируемый пост)
4. в данном случае дань универсальности ( имеем потерю в скорости)


Нет, нет тут никакой универсальности и не нужна она вообще в этом случае.
Сколько нужно будет шрифтов в программе? 


Цитата(shomer @  14.11.2007,  19:27 Найти цитируемый пост)
setClip + drawImage и drawRegion, пока не интересно.


А как же тогда картинки рисовать? 

Цитата(shomer @  14.11.2007,  19:27 Найти цитируемый пост)
нужно опробовать с   замером fPs... на разных телефонах


Ничего не нужно пробовать, если на эмуляторе тормозит, то на девайсах точно будет.

Проблема в вашей "дани универсальности". Убрать getRGB() и drawRGB() + оптимизировать саму картинку шрифта (не нужно делать для каждого символа одинаковые отступы, если символ "."(точка) занимает 1 пиксель в ширину, то и нужно оставлять 1 пиксель а не 6.


Автор: shomer 15.11.2007, 21:51
Samuil-у:
прозрачность от староватости телефона имеет нелинейную зависимость smile
лучше пользовать int numAlphaLevels() для любопытства

eugine_s-у:
setClip + drawImage и drawRegion - бью им челом
Интересно почему на Wireless Toolkit 2.5.1 эмуляторе fps в счетыре раза ниже чем на телефоне
а Sjboy Emulator вообще мидлет не берет.
Точка - пиксел, а сможет и нет  smile - масштабированием шрифта еще не занималсся 

Имхо drawImage и drawRGB равнозначны ( хотя реализации не видел ( как посмотреть smile ) JAD нам в помощь).
Есть желание сформировать растровый массив строки для последующей обработки
альфа_цветом с одной отрисовкой а не посимвольно как сейчас. Угнетает мысль о new и таймингах массива... 

Автор: shomer 15.11.2007, 23:49
Старый метод
Код

 // отрисовка строки цветом - f_acolor на фоне - b_acolor с учетом прозрачности, формат AARRGGBB
    public void DrawStr( Graphics g, String str, int x, int y, int f_acolor, int b_acolor )
    {
        if ( f_load)
        {
            int key;
            int l = str.length();
            int z = w_font * font_height;
            int[] color_f = new int[z];
            java.lang.System.arraycopy( obr_f, 0, color_f, 0, z);
            for ( int i=0; i<z; i++)
                if ( color_f[i] != blanc)
                    color_f[i] = f_acolor;
                else
                    color_f[i] = b_acolor;                
            for (int i=0; i<l; i++)
            { 
                key = (int)str.charAt(i);
                if ( key >= 1000) 
                    key -= 880;
                else 
                    key -= 32;
                g.drawRGB( color_f, of_sym[key], w_font, x, y, w_sym[key], font_height,  true);
                x += w_sym[key]; 
            }
        }
    }


Новый метод
Код

    public void DrawStr_A( Graphics g, String str, int x, int y, int f_acolor, int b_acolor )
    {
        if ( f_load)
        {
            int key = 0;
            int l = str.length();
            int size = w_font * font_height; // тут недоработочка w_font
            int wy = 0;
            int wx = 0;
            int width = 0;
            int[] color_f = new int[size];
            for ( int j=0; j<font_height; j++)
            {
                wx = 0;
                for (int i=0; i<l; i++)
                {
                    key = (int)str.charAt(i);
                    if ( key >= 1000) 
                        key -= 880;
                    else 
                        key -= 32;
                    java.lang.System.arraycopy( obr_f, of_sym[key] + w_font*j, color_f, wx + wy*j, w_sym[key]);
                    wx += w_sym[key];
                }
                wy = wx;
            }
            size = wx * font_height;
            for ( int i=0; i<size; i++)
                if ( color_f[i] != blanc)
                    color_f[i] = f_acolor;
                else
                    color_f[i] = b_acolor;                
            g.drawRGB( color_f, 0, wx, x, y, wx, font_height,  true);
        }
    }
    

Скорость вывода выросла и даже в .. раз. А я боялась smile 
Оказывается посимвольная отрисовка хорошо подтормаживает smile 
Особенно заметно при многострочном выводе ( хотя может и открыл Америку)

Powered by Invision Power Board (http://www.invisionboard.com)
© Invision Power Services (http://www.invisionpower.com)