Модераторы: javastic, AntonSaburov

Поиск:

Ответ в темуСоздание новой темы Создание опроса
> Использование Windows шрифтов в J2ME, Использование Windows шрифтов в J2ME  
:(
    Опции темы
magdelphi
  Дата 17.6.2008, 21:12 (ссылка) | (нет голосов) Загрузка ... Загрузка ... Быстрая цитата Цитата


Новичок



Профиль
Группа: Участник
Сообщений: 13
Регистрация: 5.3.2007
Где: г. Иваново

Репутация: 2
Всего: 2



Magdelphi 2008                     Использование Windows шрифтов в J2ME   

Предоставляемые возможности вывода текста в MIDP не позволяют в полной возможности воплотить задуманные решения. Столкнувшись в очередной раз с этим ограничением и не найдя готового решения написал небольшое приложение на Delphi  и java класс позволяющий использовать всё многообразие шрифтов Windows.
Утилита  FontGen.exe  позволяет создать образы шрифтов с учётом размеров и стилей который сохраняется  в файле font.png  . Также создается файл font.dat   с описанием расположения символов и служебной информацией. 
 

Рассмотрим формат файла font.dat   
Цитата

Первые 3 байта служебная информация
0 – высота символов (в пикселах)
1 – флаг  равен 1 если шрифт italic
2 – зарезервирован
Дальше каждый символ описывает 3 байта
1- младший байт смешения(в пикселах)  нахождения символа в image созданной из font.png
2 – старший байт  смешения(в пикселах)  нахождения символа в image созданной из font.png
3 –ширина символа


Дальше поместив эти файлы в папку res  j2me приложения используйте класс FontClass

Код

/*
 * FontClass.java
 *
 *  created June 16 2008
 *  author  magdelphi
 *  [email protected]
 *
 */
import java.io.InputStream;
import javax.microedition.lcdui.Graphics;
import javax.microedition.lcdui.Image;
import java.io.IOException;

public class FontClass {
    private byte buff[] = new byte[768];//данные  таблицы символов из файла xxxxx.dat
    private static Image fontImage = null;
    private static int[] buf;//данные одного символа
    private int width = 0;
    private int Color = 0;
    int h_char;//высота символов
    int italic =0;//флаг стиля символов italic

    /** конструктор  FontClass */
    public FontClass()
    { }

    //Возвращает значение цвета из составляющих a-фльфа, RGB
    private int toBGR(int a, int r, int g, int b){
        return (b|(g<<8)|(r<<16)|(a<<24));
    }

    //Устанавливает текущий цвет отображения букв по составляющим  a-aфльфа, RGB
    public void setColor(int a, int r, int g, int b){
        Color=toBGR(a,r,g,b);
    }


//*******************   Выводит на экран один символ   *************************
public int drawChar(Graphics g, char c, int left, int top) {
        int result=0;
        if (fontImage != null) {
          String s=String.valueOf©;
/*  unicode to ansi  */
          int ch = s.charAt(0) ;
                    ch = ch == 0x400 ? 0xa7 : ch == 0x450 ? 0xb7 : ch;
                    ch = ch > 0x400 ? ch - 0x350 : ch;

            int ind = ((int)(ch)-0x20)*3;//смещение данных в таблице xxxxx.dat

            int len=0;//смещение в таблице xxxxx.png

            int hlen = (buff[ind+1] & 0x00ff)<<8;//старший байт

            len=(buff[ind] & 0x00ff)+hlen;  //смещение в таблице xxxxx.png

            int width_char= buff[ind+2]+italic;//ширина символа


            fontImage.getRGB(buf, 0, width_char, len-2, 0,width_char, h_char);//считать в буфер

                   for(int i=0;i<buf.length;i++)
                   {
                        int color = (buf[i] &0x00ffffff);//читаем только RGB
                        if (color == 0) color =  Color;//если черный красим в цвет
                        buf[i] = color;
                    }

              g.drawRGB(buf, 0, width_char, left, top, width_char, h_char, true);
              if (c==' '){width_char=h_char>>2;}//если пробел
                result=width_char;
         }
        return result;
    }


//*****   Выводит строку символов  **********************************************
    public void drawString(Graphics g, String s, int left, int top) {
        int len = left;
        int w = 0;
        int max_width =g.getClipWidth();
        for (int i = 0; i < s.length(); i++) {
//          if s.charAt(i) == " "
            w=drawChar(g, s.charAt(i), len, top);
            len=len+w;
//            if (len >= max_width-1) return;
        }
        width=len;
    }

//**************   Инициализация, создание объектов и буферов   ****************
    public void Init(String name_font){

        try {//-----  загрузка image символов  ---------------
            fontImage = Image.createImage("/"+name_font+".png");

        } catch (IOException ioe) {
            ioe.printStackTrace();
        }
//*************   загрузка таблицы расположения символов  *********************
        InputStream is = getClass().getResourceAsStream("/"+name_font+".dat");
         //System.out.println("f2s8.dat загружено");
        int off = 0;
        int readBytes = 0;
       int n_buf;
        try
        {
          while ( (readBytes = is.read(buff, off, buff.length)) > -1) {}//копируем в буфер
          h_char=buff[0];//высота символов

          if  (buff[1] ==1) {italic=h_char/4;}//если fontstyle = [italic] увеличиваем ширину символа
        }
        catch (Exception e)
        {
          System.out.println("Exception: " + e.toString());
        }

   n_buf =h_char*h_char;// кол-во байт 1 знакоместо

       buf = new int[n_buf];

    }

    //Удаление объектов
    public void Destroy(){
        buff = null;
        buf = null;
        fontImage = null;
    }

}



Пример использования
 
Архив с FontGen.exe,  FontClass и примером прилагаю 


Это сообщение отредактировал(а) W0LF - 18.6.2008, 13:28

Присоединённый файл ( Кол-во скачиваний: 59 )
Присоединённый файл  winfont.zip 364,13 Kb
PM MAIL WWW   Вверх
Samuil
Дата 18.6.2008, 10:12 (ссылка) | (нет голосов) Загрузка ... Загрузка ... Быстрая цитата Цитата


в(Job)ываю
**


Профиль
Группа: Участник
Сообщений: 705
Регистрация: 26.4.2006
Где: Uzbekistan.Tashke nt

Репутация: 5
Всего: 6



magdelphi, Молодец! Я думаю эту тему надо дабавить в ФАК! Информация Важна для начинающих и не только!  


--------------------
Выбор уже сделан, остается его только осознать   
smile    smile 
      smile  

user posted image
PM MAIL ICQ   Вверх
eugine_s
Дата 18.6.2008, 12:52 (ссылка) | (нет голосов) Загрузка ... Загрузка ... Быстрая цитата Цитата


Опытный
**


Профиль
Группа: Участник
Сообщений: 581
Регистрация: 14.11.2007
Где: Киев

Репутация: 17
Всего: 17



Нормальная утилита. 
Вот возможные доработки:

1) На выходной картинке слишком большие отступы между символами. Они не нужны - только место занимают. (Создал шрифт MSSansSerif 10 жирный - размер получился 3680 x 16 - имхо, это очень много для шрифта.) 
Символы нужно рисовать на картинке в плотную, без всяких пробелов. А в программе, если нужно будет, то можешь сам добавить нужный отступ между символами.

2) Часть символов реально никогда не используется. На картинке они располагаются между английскими и русскими буквами. Их можно "выбросить".

3) Ну и еще такое: чем отличается английская А от русской А, английская B от русской B, C от С, а от а ...?
Реально - ничем. Соотвественно на выходном картинке шрифта часть символов можно отбросить.

PM MAIL   Вверх
magdelphi
Дата 18.6.2008, 18:29 (ссылка) | (нет голосов) Загрузка ... Загрузка ... Быстрая цитата Цитата


Новичок



Профиль
Группа: Участник
Сообщений: 13
Регистрация: 5.3.2007
Где: г. Иваново

Репутация: 2
Всего: 2



Для этого большие интервалы между символами и сделал чтобы можно было легко выбрасывать и всталять, 
но меняя расположение символов не забудь изменить и логику работы в классе FontClass и без того работающего
достаточно медленно. Зачем экономить память в ушеб быстродействию? Тем более 48кбайт по Memory monitor для моего примера
это не много, а там шрифт ArialBlack 36.
PM MAIL WWW   Вверх
eugine_s
Дата 18.6.2008, 19:15 (ссылка) | (нет голосов) Загрузка ... Загрузка ... Быстрая цитата Цитата


Опытный
**


Профиль
Группа: Участник
Сообщений: 581
Регистрация: 14.11.2007
Где: Киев

Репутация: 17
Всего: 17



Цитата(magdelphi @  18.6.2008,  18:29 Найти цитируемый пост)
Для этого большие интервалы между символами и сделал чтобы можно было легко выбрасывать и всталять


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

Цитата(magdelphi @  18.6.2008,  18:29 Найти цитируемый пост)
Зачем экономить память в ушеб быстродействию? 

 
В j2mе есть смысл экономить память, тем более на таких вещах и тем более я не вижу как это сказывается на быстродействии.

Цитата(magdelphi @  18.6.2008,  18:29 Найти цитируемый пост)
Тем более 48кбайт по Memory monitor для моего примера
это не много, а там шрифт ArialBlack 36. 


Nokia 7070 Prism S40 DP5 heap = 600 кб. Как ты думаешь 50 кб для такого телефона существенно?

Я конечно не знаю, что у тебя монитор показывает, но вот сколько занимает в памяти только одна картинка твоего шрифта ArialBlack 36: 

ширина * высоту * 2 (внутренее представление картинки в памяти Java - 2 байта на один пиксель) = 5000 (точно не помню, где-то столько пикселей) * 36 * 2 = 350 кб 

Т.е. 350 кб только под одну картинку шрифта и это не просто много, А ОЧЕНЬ МНОГО.

(48 кб у тебя могло показать, так как в некоторых телефонах есть кроме heap памяти еще память для картинок).

Цитата(eugine_s @  18.6.2008,  12:52 Найти цитируемый пост)
шрифт MSSansSerif 10 жирный - размер получился 3680 x 16


тут 110 кб - это тоже многовато.





PM MAIL   Вверх
magdelphi
Дата 18.6.2008, 19:50 (ссылка) | (нет голосов) Загрузка ... Загрузка ... Быстрая цитата Цитата


Новичок



Профиль
Группа: Участник
Сообщений: 13
Регистрация: 5.3.2007
Где: г. Иваново

Репутация: 2
Всего: 2



Можно конечно создать png для каждого символа. Тогда с памятью будет всё очень хорошо, но скорость?
PM MAIL WWW   Вверх
eugine_s
Дата 18.6.2008, 20:42 (ссылка) | (нет голосов) Загрузка ... Загрузка ... Быстрая цитата Цитата


Опытный
**


Профиль
Группа: Участник
Сообщений: 581
Регистрация: 14.11.2007
Где: Киев

Репутация: 17
Всего: 17



Цитата(magdelphi @  18.6.2008,  19:50 Найти цитируемый пост)
Тогда с памятью будет всё очень хорошо, но скорость? 


Я думаю это шутка была? Так как с памятью еще хуже будет.


Советы я тебе дал, объяснил почему нужно это сделать. Твое дело прислушаться или нет.

PM MAIL   Вверх
magdelphi
Дата 18.6.2008, 22:51 (ссылка) | (нет голосов) Загрузка ... Загрузка ... Быстрая цитата Цитата


Новичок



Профиль
Группа: Участник
Сообщений: 13
Регистрация: 5.3.2007
Где: г. Иваново

Репутация: 2
Всего: 2



Нет не шутка, я имел ввиду можно к примеру, сделать не один а 4 файла для каждого шрифта 1-латиница 2-цифры 3-спецсимволы 4-кириллица, которые будут загружаться по мере необходимости. Единственная проблема скорость.
PM MAIL WWW   Вверх
smke444
Дата 21.7.2008, 09:56 (ссылка) | (нет голосов) Загрузка ... Загрузка ... Быстрая цитата Цитата


Новичок



Профиль
Группа: Участник
Сообщений: 12
Регистрация: 11.6.2007

Репутация: нет
Всего: нет



Вот нарыл еще одну утилиту для создания автоматически PNG файла с любой последовательностью букв используя Windows шрифты, думаю многим пригодится  smile 
user posted image

Присоединённый файл ( Кол-во скачиваний: 20 )
Присоединённый файл  font4mobile_025.zip 666,65 Kb
PM MAIL   Вверх
igorka
  Дата 19.9.2009, 23:08 (ссылка) | (нет голосов) Загрузка ... Загрузка ... Быстрая цитата Цитата


Новичок



Профиль
Группа: Участник
Сообщений: 38
Регистрация: 28.6.2007

Репутация: нет
Всего: нет



Классная штука. Удобно. 
Но, есть однО бОльшое нО!
Сони-эрики выкидывают java.lang.OutOfMemoryError при использовании шрифтов размером от 28 и больше((.
А мне надо именно такой шрифт (28-й и 48-й).
И еще если мне надо только 0-9 зачем мне в ресурсах держать весь алфавит?
Автор, хелп!!!

PM MAIL   Вверх
eugine_s
Дата 21.9.2009, 13:39 (ссылка) | (нет голосов) Загрузка ... Загрузка ... Быстрая цитата Цитата


Опытный
**


Профиль
Группа: Участник
Сообщений: 581
Регистрация: 14.11.2007
Где: Киев

Репутация: 17
Всего: 17



Цитата(igorka @  19.9.2009,  23:08 Найти цитируемый пост)
И еще если мне надо только 0-9 зачем мне в ресурсах держать весь алфавит?


Возьми .png  (который программа генерируте), открой в фотошопе и скопируй нужные символы (0-9) в новую картинку. Сохрани png. 
Сгенерируй описание png (можно сгенерировать или можно в программе захардкодить).

Или smke444  выложил утилиту, которой можно ввести любую последовательность символов.

Это сообщение отредактировал(а) eugine_s - 21.9.2009, 13:40
PM MAIL   Вверх
igorka
Дата 21.9.2009, 15:01 (ссылка) | (нет голосов) Загрузка ... Загрузка ... Быстрая цитата Цитата


Новичок



Профиль
Группа: Участник
Сообщений: 38
Регистрация: 28.6.2007

Репутация: нет
Всего: нет



Я просто обрезал пнг файл, оставил часть только до цифр. 
как сгенерить описание не разбирался, поэтому сделал именно так.
Заработало.
Утилита которую выложил smke444 упорно отказывается работать... ну и ладно.
Кста, время отрисовки этих шрифтов просто жесть, даше на шустреньких SE очень медленно, 
представляю что  будет на сименсах и моторах. Надо будет где-то оптимизировать.
Как разберусь где, отпишусь.
PM MAIL   Вверх
eugine_s
Дата 21.9.2009, 16:45 (ссылка) | (нет голосов) Загрузка ... Загрузка ... Быстрая цитата Цитата


Опытный
**


Профиль
Группа: Участник
Сообщений: 581
Регистрация: 14.11.2007
Где: Киев

Репутация: 17
Всего: 17



Цитата(igorka @  21.9.2009,  15:01 Найти цитируемый пост)
Кста, время отрисовки этих шрифтов просто жесть, даше на шустреньких SE очень медленно, 


Какой размер картинки (.png) в пикселях? 

Это сообщение отредактировал(а) eugine_s - 21.9.2009, 16:45
PM MAIL   Вверх
smke444
Дата 24.9.2009, 17:26 (ссылка) | (нет голосов) Загрузка ... Загрузка ... Быстрая цитата Цитата


Новичок



Профиль
Группа: Участник
Сообщений: 12
Регистрация: 11.6.2007

Репутация: нет
Всего: нет



Хорошая новость – нарыл другую утилиту, на много лучше прежней, сие чудо называется PopCap Games Framework v1.3, качаем здесь http://sourceforge.net/projects/popcapframework/
Особенности :
- рисует любую последовательность букв
- работает коректно ( в font4mobile – были замечены глюки)
- утилита проверки фонта / png картинки на валидность
- пространство между буквами в картинке -  1 пикселЬ !
- и самое главное – прога генерирует dat файл со смешениями, ширинами  букв в картинке !!!
Пользуюсь только ей.

 smile 


Это сообщение отредактировал(а) smke444 - 24.9.2009, 17:28
PM MAIL   Вверх
aRixx
Дата 26.10.2009, 10:51 (ссылка) | (нет голосов) Загрузка ... Загрузка ... Быстрая цитата Цитата


Новичок



Профиль
Группа: Участник
Сообщений: 36
Регистрация: 2.11.2007

Репутация: нет
Всего: нет



Развивая тему шрифтов. Статья про использование собственных векторных шрифтов:
http://www.mobilab.ru/articles/113/
PM MAIL   Вверх
Ответ в темуСоздание новой темы Создание опроса

  • Прежде чем задать вопрос прочтите это!
  • Литература по Java находится здесь.
  • Литературу по Java обсуждаем здесь.
  • Используйте теги [code=java][/code] для подсветки кода. Используйтe чекбокс "транслит" (возле кнопок кодов) если у Вас нет русских шрифтов.
  • Действия модераторов можно обсудить здесь
  • С просьбами о написании курсовой, реферата и т.п. обращаться сюда

  • FAQ раздела лежит здесь!
 
1 Пользователей читают эту тему (1 Гостей и 0 Скрытых Пользователей)
0 Пользователей:
« Предыдущая тема | Java ME (J2ME) | Следующая тема »


 




[ Время генерации скрипта: 0.2300 ]   [ Использовано запросов: 22 ]   [ GZIP включён ]


Реклама на сайте     Информационное спонсорство

 
По вопросам размещения рекламы пишите на vladimir(sobaka)vingrad.ru
Отказ от ответственности     Powered by Invision Power Board(R) 1.3 © 2003  IPS, Inc.