Java → Использование Windows шрифтов в J2ME
Предоставляемые возможности вывода текста в MIDP не позволяют в полной возможности воплотить задуманные решения. Столкнувшись в очередной раз с этим ограничением и не найдя готового решения написал небольшое приложение на Delphi и java класс позволяющий использовать всё многообразие шрифтов Windows.
Утилита FontGen.exe позволяет создать образы шрифтов с учётом размеров и стилей который сохраняется в файле font.png. Также создается файл font.dat с описанием расположения символов и служебной информацией.
Рассмотрим формат файла font.dat Первые 3 байта служебная информация
высота символов (в пикселах)
флаг равен 1 если шрифт italic
зарезервирован
Дальше каждый символ описывает 3 байта
старший байт смешения(в пикселах) нахождения символа в image созданной из font.png
ширина символа
Дальше поместив эти файлы в папку res j2me приложения используйте класс FontClass
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()
{ }
//Возвращает значение цвета из составляющих alpha-фльфа, RGB
private int toBGR(int a, int r, int g, int b){
return (b(g<<8)(r<<16)(a<<24));
}
//Устанавливает текущий цвет отображения букв по составляющим alpha-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(c);
/ 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_charh_char;// кол-во байт 1 знакоместо
buf = new int[n_buf];
}
//Удаление объектов
public void Destroy(){
buff = null;
buf = null;
fontImage = null;
}
}
Утилита FontGen.exe позволяет создать образы шрифтов с учётом размеров и стилей который сохраняется в файле font.png. Также создается файл font.dat с описанием расположения символов и служебной информацией.
Рассмотрим формат файла font.dat Первые 3 байта служебная информация
высота символов (в пикселах)
флаг равен 1 если шрифт italic
зарезервирован
Дальше каждый символ описывает 3 байта
старший байт смешения(в пикселах) нахождения символа в image созданной из font.png
ширина символа
Дальше поместив эти файлы в папку res j2me приложения используйте класс FontClass
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()
{ }
//Возвращает значение цвета из составляющих alpha-фльфа, RGB
private int toBGR(int a, int r, int g, int b){
return (b(g<<8)(r<<16)(a<<24));
}
//Устанавливает текущий цвет отображения букв по составляющим alpha-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(c);
/ 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_charh_char;// кол-во байт 1 знакоместо
buf = new int[n_buf];
}
//Удаление объектов
public void Destroy(){
buff = null;
buf = null;
fontImage = null;
}
}
Добавил: javavirys ( 2022-02-22 12:22:05 )
Теги:
Просмотров: 210