Cyrillic fonts for allegro
Nedjalko Milenkov

I was trying to use the unicode, but it needs spec. fonts. I do not have a cyryllic font. Could anyone give me? I searchd in google, but the tools which I found don not work (ttf2pcx and FontEditor).

Kirr
Nedjalko Milenkov

The url does not help me :(. These are ttf fonts and I am searching fonts for Allegro in pcx, bmp or data file format.

miran

All the basic MS fonts that come with XP (Arial, Times, etc) have cyrillic characters in them. And they do work with both ttf2pcx and the FontEditor, you just need to know what you're doing. Hint: ranges...

Nedjalko Milenkov

After playing with the ranges I found cyrillic from 1024 to 2048 (betwen). I saved the file in fontx.pcx. Loaded it at the grabber and detects 1120 glyphs! After loading the font and puting some text to the screen it show rectan. Why? Should I edit the range and how?

Evert

Or use Glyph Keeper to use the TrueType fonts directly.

EDIT: for font ranges, see Allegro's manual: [url http://alleg.sourceforge.net/onlinedocs/en/index017.html#load_txt_font].
Feel free to ask if you need more information.

(That link is for 4.1.18. If you use 4.0.3, the load_font() family of functions doesn't exist. But the information is still accurate, you'll just have to use the grabber and datafiles to load the font. Or upgrade;))

miran

I don't remember exactly where the cyrillic fonts are but there was a thread with this exact question not very long ago. You might want to do a search.

In FontEditor all you have to do is this: select your colours (if you want multicolour font), load the font, add the range with the cyrillic characters and save as a pcx file. Then you must write a multi-range font script. Take a look at the unifont that comes with Allegro in the examples directory. Basically that will be just a normal text file that will look like this:

unifont.pcx 0x0020 0x007F
- 0x0400 0x047F

Then when you load the font in your code, you load the txt file instead of the pcx. Again check the unicode example...

EDIT: That took me a long time to write ::)

Nedjalko Milenkov

I checked the unicode example and see only \x14\x04 king of stuff. I know that that is the real unicode, but I prefer to write instead of code :). I found an example which works fine, but the cyrillic font is too big. I manage to isolate the eng. and cyr. from arial in 0x20-0x07F (eng) and 0x80 - 0xFF(CYR), but when I write something it takes the empty symbols in the file instead showing the cyr. Any Ideas how to correct?

miran

Did you call set_uformat() before allegro_init()? Or whatever it's called.

Nedjalko Milenkov

miran Yes I run set_uformat( U_UTF8 ); buf after allegro_init();

miran

What does the manual say about that? Last time I checked it recommended you do it before allegro_init()...

gnolam

And is your text input unicode as well? I know from personal experience that Cyrillic encoding is a bitch due to the many conflicting encoding standards...

miran

Oh I just noticed, you're trying to use a Unicode font with extended 8bit ASCII strings. That simply won't work. Either you make or get a font with 8bit ASCII encoding or you format your strings into real 16bit Unicode...

Matt Smith

I would hack a Unicode->CodePage export func into Miran's font editor :D

Has anyone tested what happens when you feed UTF-8 strings through gcc? I expect it will choke.

When you use Allegro's printing functions, they expect UTF-8 by default, so you should set it to 8-bit ASCII with set_uformat(U_ASCII_CP); first. You still need a Cyrillic CodePage font, to match the one in your code editor. (I was wary about using codepages in C code but all the compilers seem to accept it.)

The manual says it should work with ASCII-8 strings and a Unicode font, provided the tables are set up right with void set_ucodepage(const unsigned short *table, const unsigned short *extras);

Nedjalko Milenkov

What a big mess :o. Could anyone post some nice example, because I do not understand how to put it all together. I readed the manual for the ten time, but still having some problems.

Evert
Quote:

What does the manual say about that? Last time I checked it recommended you do it before allegro_init()...

You should, if you only intend to use a single encoding ever. I'm not actually sure if there will be problems if you set it later, but I assume not, since Allegro also allows you to switch encodings on the fly.

This part of Allegro is pretty ugly, by the way.

Matt Smith

The first thing you need to establish is which code page you are using. DOS had the old IBM code pages (Russian was 866) and Windows has 1251 (Slavic) and 1257 (Baltic). There is also iso 8859-5 etc.

Then, you have to hope somebody has made the codepage tables for your chosen encoding, or make it yourself like this

1const unsigned short cp_cyrillic[256]={
2 0,
3 1,
4 ...
5 127, /* first 128 chars map to ASCII */
6 n, /* unicode-16 char (wchar) of codepage char 128 */
7 ...
8};
9 
10char string[] = "Dos Vedanya, Tanya"; <- in Cyrillic codepage
11 
12set_ucodepage(cp_cyrillic, NULL);
13set_uformat(U_ASCII_CP);
14 
15unifont = load_font("unifont.fnt"); /* new function in 4.2 :o) */
16
17textout_ex(screen, unifont, string,x,y,black,white);

Kirr

Here is a table for converting cp-1251 into Unicode.

But I don't suggest working with codepage through all your program. It's better to convert your strings to Unicode (for ex. UTF-16) in the startup of your program. Some libs, like ICU have this conversion functions, but it is trivial anyway, so I suggest to just code it.

DanielH

Nedjalko, look at my unicode example. It comes with a cyrillic font and prints Russian-English pairs.

Nedjalko Milenkov

MattSmith

Quote:

Then, you have to hope somebody has made the codepage tables for your chosen encoding, or make it yourself like this

-> I searched, but do not find some already defined. And if I deside to write it, should I write only number or? Because from your example it seems, that only positions or?

Kirr

Quote:

Here is a table for converting cp-1251 into Unicode.

-> I saw the table, but it only describes the position. I think that I should do the writing :(.

DanielH

Quote:

Nedjalko, look at my unicode example. It comes with a cyrillic font and prints Russian-English pairs.

-> Actually everything began with it :). But the font is too big. How can I resize it, or do you have another cyr. font? And how did you do it?

DanielH

I used TTF2PCX to make the font. You just have to supply the min and max characters of the cyrillic font. Now that I think of it, I was using a font that only had cyrillic characters.

Nedjalko Milenkov

I tried Monochrome from 0x20 to 0x7F and saved it as PCX, but the PCX was empty :(.

DanielH

You have a bad ttf2pcx. Download Matt's

http://www.allegro.cc/misc/ttf2pcx.zip

Here's what you do. Create a font with characters from 0x20 to 0xff
Create another font from 0x410 to 0x44f. Then combine them. copy paste the second one in to the lower portion of the first.

Nedjalko Milenkov

10x. I`v extracted the fonts fon 0x20 to 0x44F and the cyricllic font is fon 0x400 to 0x44F. How can I tell the grabber to extract
testfont.pcx 0x20 0x7F
testfont.pcx 0x400 0x44F
? This lines do not work :(

DanielH

What are you talking about? You have to use ttf2pcx and use a paint program to combine them.

Thomas Fjellstrom

or use grabber's fonst script loading.. Just enter the correct info into a textfile and import as a FONT.

DanielH

Can you do that with two different sets of values?

The font should contain 224 characters:

176: 0x20 - 0xcf
48: 0x410 - 0x44f

Thomas Fjellstrom

Thats what that font loader is for, to load more than one charater range into the same allegro FONT. Unfortunately I don't know the format of the file the grabber wants.. but I'm sure someone around does.

Kirr

Wow, what a mess to just output text. How much easier it is to use TTF directly in your program. Also it lets you change the text size on-the-fly and see how it looks without re-running TTF2PCX, re-grabbing it with grabber etc..

miran

Daniel, Thomas: I already told him all that, but as usual he ignored it.

Evert
Quote:

testfont.pcx 0x20 0x7F
testfont.pcx 0x400 0x44F

Use a dash (-) for the second file name and see if that helps.

Quote:

You have to use ttf2pcx and use a paint program to combine them.

No, you don't.

Quote:

Unfortunately I don't know the format of the file the grabber wants.. but I'm sure someone around does.

I posted the relevant link in my first post in this thread. Miran posted the format as well.

Nedjalko Milenkov

I did not used Paint program, but I think that the Font Editor is good too. Now I have one PCX file with English and Cyrillic, but when I write something and use unicode, I do see some strainght signs. How does allegro understand what part of the picture for an example "A" is?

Evert

Have a look at [url http://alleg.sourceforge.net/onlinedocs/en/index017.html#load_bitmap_font] for a description of how the font should formatted in the bitmap.

Nedjalko Milenkov

Somehow using ttf2pcx and Font Editor I`v managed to make a compilation - see the attached file, but when including it in my program, and print cyr. I see some unrecognized strings althought I have input cyrillic.

miran

How did you write your font script? And how did you enter the text? Extended ASCII or Unicode?

Nedjalko Milenkov
Quote:

How did you write your font script? And how did you enter the text? Extended ASCII or Unicode?

I do not have font script. I just use data file. I use Unicode.

miran

For the millionth time, YOU NEED A FONT SCRIPT!!!!!!!!!!!!!!!!!! Scroll up this thread and pick a random post to see how it's done....

Nedjalko Milenkov

miran - Arrrrrr...how can I explain that I CAN NOT USE A SCRIPT!
I load into the grabber font.txt which contains:
font.pcx 0x0020 0x007F
and the program says Could not load font.pcx. And when I add it manual to the data file it loads it, but in my program there is no cyr :(.
Is it too hard to say how realy is done, not some non working ideas.

P.S. Sorry if I sound too rude, but 4 days for Unicode seems too much!
There must be a way, but I found no tutorial which explaint HOW it is done.

P.S. 1 I do not use load_font because in version 4.0 there is no such function and ver. 4.1 is beta.

Evert
Quote:

Arrrrrr...how can I explain that I CAN NOT USE A SCRIPT!

I don't know, but you should try to say it before shouting.

Quote:

I load into the grabber font.txt which contains:
font.pcx 0x0020 0x007F
and the program says Could not load font.pcx.

That looks ok. Can you post the exact script and font file?

Quote:

P.S. 1 I do not use load_font because in version 4.0 there is no such function and ver. 4.1 is beta.

True, but the description of the font formats is the same as for the grabber, as I said in my first post.

Nedjalko Milenkov

Sorry for the "shouting", but ...
In the zip file is the script and the image.

miran

I found two errors:

1. There needs to be a space between - and the number in the second line
2. The contents of the script must match the contents of the pcx file!

EDIT: Attached is arial.ttf converted to pcx with my FontEditor at size 36 with no antialiasing and two ranges: normal ASCII and the cyrillic characters. Also in the zip is a working font script for this pcx and the whole font packaged as a dat file.

Nedjalko Milenkov

I thought that they match ???
This is an extraction fon ttf2pcx and the range is the hole font. And with the script I want to include only two parts - eng and cyr.
What should I change in the pcx?

miran

I edited while you were posting. See my example in the post above...

Nedjalko Milenkov

Thanks for the file, but again my grabber says that "I can not read arialfonts.pcx", but when I include the arialfonts.pcx direct from the PCX there is no problem at all :(. I`v tested the compiled data.dar and with set_uformat( U_UTF8 ); shows only ^^^ :(

miran
Quote:

my grabber says that "I can not read arialfonts.pcx", but when I include the arialfonts.pcx direct from the PCX there is no problem at all

First of all, the file I made was called arialcyr.pcx. Secondly, you need to put both files, arialcyr.txt and arialcyr.pcx in the same directory. Then load grabber, select object->new->font. Then grab the txt file. There should be no errors. If you do get errors, then your grabber is defected...

Quote:

I`v tested the compiled data.dar and with set_uformat( U_UTF8 ); shows only ^^^ :(

You need to call set_uformat(U_UNICODE) to be able to use that font, just
like the Unicode example.

EDIT:
If you want to continue using U_UTF8 (which btw is the default so you don't have to set it explicitely), you need to remap the glyphs in the font a bit. How exactly depends on the codepage you're using...

Nedjalko Milenkov

It seems that my grabber is full of bugs :(

but with your datafile and with set_uformat(U_UNICODE); does not works
here is the code of a simple program

1/* UltraBlocks ver.:0.1
2 * By the ultimate and unforgiven game TETRIS
3 * Coder Nedjalko Milenkov
4 * e-mail redspace[at]bg-webmaster.com
5 * Just wait to see the final version :)
6 * Whats new: The whole code :)
7 */
8
9#include <allegro.h>
10 
11#include "data.h"
12 
13DATAFILE *data;
14FONT *myfont;
15 
16//The MAIN FUNCTION
17int main(void){
18char buf[512];
19 
20 allegro_init();
21
22 install_keyboard();
23
24 set_color_depth(16);
25
26 if (set_gfx_mode(GFX_AUTODETECT_WINDOWED, 640, 480, 0, 0)!=0)
27 {
28 set_color_depth(15);
29 if (set_gfx_mode(GFX_AUTODETECT_WINDOWED, 640, 480, 0, 0)!=0){
30 allegro_message("Unable initialize graphics module\n%s\n", allegro_error);
31 return -1;
32 }
33 }
34
35
36
37 BITMAP *buffer=create_bitmap(SCREEN_W, SCREEN_H);
38
39 if(buffer==NULL){
40 allegro_message("Sorry, not enough memory.");
41 allegro_exit();
42 exit(2);
43 }
44
45 data=load_datafile("arialcyr.dat");
46
47 if (!data) {
48 allegro_message("Unable to load %s\n");
49 return -1;
50 }
51 
52//set_uformat( U_UTF8 );
53//set_uformat(U_ASCII_CP);
54set_uformat(U_UNICODE);
55 
56
57 uconvert("Ïðîãðàìèðàíå dd", U_ASCII, buf, U_CURRENT, sizeof( buf ));
58 textprintf_centre(screen, data[0].dat, 300, 100, makecol( 255, 255, 255), buf);
59
60 //blit(buffer, screen, 0, 0, 0, 0, SCREEN_W, SCREEN_H);
61
62 readkey();
63
64 return 0;
65}
66END_OF_MAIN()

Thomas Fjellstrom

set_uformat should go BEFORE allegro_init() IIRC.

Nedjalko Milenkov

I tried it but it does not work :(, but when I put to the screen this "\x14\x04" ">\x04" , which is from the allegro example it works, but when I use uconvert("Ïðîãðàìèðàíå", U_ASCII, buf, U_UNICODE, sizeof( buf ));, there is no cyr output. This is 30% solution, because I do not want to write like "\x14\x04" only for one alphabet :(.

miran

You probably need to setup a codepage conversion table:

void set_ucodepage(const unsigned short *table, const unsigned short *extras);

Nedjalko Milenkov

miran I do not think that I am the first man using unicode. Is there something done? And why when I used some already done PCX(from one site for beginers) it works?

Kirr

You would have much better chance to get help here if you include these things with your post:

1. Everything needed to reproduce the problem. Your program code (as short as possible), PCX/script/whatever else you use, steps you took with TTF2PCX and both TTF and PCX, as many details as possible. Also mention your OS and allegro version and anything else you think can be relevant.

2. What you expect your program to do, precisely.

3. What your program is actually doing, precisely.

Then, if someone is willing to help, he will at least have such chance, instead of guessing what you might have done wrong.

Quote:

miran I do not think that I am the first man using unicode.

Most people using unicode don't use codepages at all. Also using unicode does not imply using PCX fonts.

Quote:

And why when I used some already done PCX(from one site for beginers) it works?

What site? Did you try to say they work with the same code, that you posted here? Or with some other code? Or you mean something else? I guess the question is rather why your PCX don't work. Did you actually try Miran's suggestions?

Mark Knopfler said:

But in the communique you know he's gonna come clean
Think what he say, say what he mean
Maybe on Monday he got something to say
Communication
Communique
Communique

Nedjalko Milenkov

Kirr
Here is the full information about my problem

1. I came from Bulgaria and I want my programs to support cyrillic.
2. My Allegro lib is 4.0.3.0 .
3. I saw one example for unicode at http://agdn.pyrosoftware.net/main/showfile.php?request=7 . You can download the hole program from http://agdn.pyrosoftware.net/main/archive/unicode.zip .
4. When I tried it it works, but the font was too big. I wanted to make my own and to make it smaller.
5. I did some googling and found two programs ttf2pcx and Font Editor
6. I had a bad copy of the first program and at the beginning it does not works. Someone gave me the url of a working version.
7. I extracted from arial.ttf (Windows XP, SP2) the cyrillic ranges (0x410 - 0x44F) and tried to put the PCX in my data file. But again it does not work. Then Miran told me to use Font scripts, but after 1 hour of trying I found that my grabber do not work properly even with the Mirian`s example.
8. I tried all of your suggestion (thank you for the attention)
9. I`v posted a simple code. Here is once again:

1/* UltraBlocks ver.:0.1
2 * By the ultimate and unforgiven game TETRIS
3 * Coder Nedjalko Milenkov
4 * e-mail redspace[at]bg-webmaster.com
5 * Just wait to see the final version :)
6 * Whats new: The whole code :)
7 */
8
9#include <allegro.h>
10 
11#include "data.h"
12 
13DATAFILE *data;
14FONT *myfont;
15 
16//The MAIN FUNCTION
17int main(void){
18char buf[512];
19set_uformat(U_UNICODE);
20 
21 allegro_init();
22
23 install_keyboard();
24
25 set_color_depth(16);
26
27 if (set_gfx_mode(GFX_AUTODETECT_WINDOWED, 640, 480, 0, 0)!=0)
28 {
29 set_color_depth(15);
30 if (set_gfx_mode(GFX_AUTODETECT_WINDOWED, 640, 480, 0, 0)!=0){
31 allegro_message("Unable initialize graphics module\n%s\n", allegro_error);
32 return -1;
33 }
34 }
35
36
37 BITMAP *buffer=create_bitmap(SCREEN_W, SCREEN_H);
38
39 if(buffer==NULL){
40 allegro_message("Sorry, not enough memory.");
41 allegro_exit();
42 exit(2);
43 }
44
45 data=load_datafile(uconvert_ascii("arialcyr.dat", buf));
46
47 if (!data) {
48 allegro_message("Unable to load %s\n");
49 return -1;
50 }
51 
52//set_uformat( U_UTF8 );
53//set_uformat(U_ASCII_CP);
54 
55 
56
57 uconvert("Ïðîãðàìèðàíå", U_ASCII, buf, U_UNICODE, sizeof( buf ));
58
59 textprintf_centre(screen, data[0].dat, 300, 100, makecol( 255, 255, 255), buf);
60
61 //blit(buffer, screen, 0, 0, 0, 0, SCREEN_W, SCREEN_H);
62
63 readkey();
64
65 return 0;
66}
67END_OF_MAIN()

The code does not work with the data file from the allegro unicode example and with the Mirian`s data file too, but when I write something like \x14\x04 it works. The problem is that I do not want to write like that :(.
Could anyone help me?

Kirr

OK, now it's better, although you still did not post your datafile, so I had to make that cyrillic font myself. After that and some modifications your code worked for me:

#include "data.h"

You did not post "data.h", so I just commented it out.

uconvert("Ïðîãðàìèðàíå", U_ASCII, buf, U_UNICODE, sizeof( buf ));

Here is your problem. First, when you copy/paste your source into forum reply box, its encoding may be changed. You'd better attach your source file as attachment to the post. I assume that this line has actually some cyrillic characters. So I typed cyrillic "Медитирoвать не надo." indtead of "Ïðîãðàìèðàíå".

Second. Cyrillic is not part of ASCII. You have to use U_ASCII_CP instead of U_ASCII in this function call.

And last, for U_ASCII_CP to work you should specify a cyrillic codepage for ALlegro with set_ucodepage. So, instead of that your one line I typed two lines:

set_ucodepage(cyrcodepage,0);
uconvert("Медитирoвать не надo.", U_ASCII_CP, buf, U_UNICODE, sizeof( buf ));

Of course, for this to work I had to type in a cyrillic codepage earlier:

const unsigned short cyrcodepage[256] = {
.....
};

Then everything worked and the program printed cyrillic text on screen.

One last thing:

Quote:

allegro_message("Unable to load %s\n");

There is not enough arguments in this call.

Nedjalko Milenkov

Seems there is a hope :).
Could you post the hole const unsigned short cyrcodepage[256] = {
.....
};
or rar of the your test program?
In this post is my non working example.

P.S. In the allegro manual there is no second argument in void allegro_message(const char *msg, ...);

Kirr

Actually MattSmith already mentioned in this thread that you need a codepage conversion table, and I posted a link to the codepage data. You could use it long time ago. Anyway, here you go, this is Windows-1251 codepage:

1const unsigned short cyrcodepage[256] = {
2 0x00,0x01,0x02,0x03,0x04,0x05,0x06,0x07,0x08,0x09,0x0A,0x0B,0x0C,0x0D,0x0E,0x0F,
3 0x10,0x11,0x12,0x13,0x14,0x15,0x16,0x17,0x18,0x19,0x1A,0x1B,0x1C,0x1D,0x1E,0x1F,
4 0x20,0x21,0x22,0x23,0x24,0x25,0x26,0x27,0x28,0x29,0x2A,0x2B,0x2C,0x2D,0x2E,0x2F,
5 0x30,0x31,0x32,0x33,0x34,0x35,0x36,0x37,0x38,0x39,0x3A,0x3B,0x3C,0x3D,0x3E,0x3F,
6 0x40,0x41,0x42,0x43,0x44,0x45,0x46,0x47,0x48,0x49,0x4A,0x4B,0x4C,0x4D,0x4E,0x4F,
7 0x50,0x51,0x52,0x53,0x54,0x55,0x56,0x57,0x58,0x59,0x5A,0x5B,0x5C,0x5D,0x5E,0x5F,
8 0x60,0x61,0x62,0x63,0x64,0x65,0x66,0x67,0x68,0x69,0x6A,0x6B,0x6C,0x6D,0x6E,0x6F,
9 0x70,0x71,0x72,0x73,0x74,0x75,0x76,0x77,0x78,0x79,0x7A,0x7B,0x7C,0x7D,0x7E,0x7F,
10 0x0402,0x0403,0x201A,0x0453,0x201E,0x2026,0x2020,0x2021,0x20AC,0x2030,0x0409,0x2039,0x040A,0x040C,0x040B,0x040F,
11 0x0452,0x2018,0x2019,0x201C,0x201D,0x2022,0x2013,0x2014,0x0020,0x2122,0x0459,0x203A,0x045A,0x045C,0x045B,0x045F,
12 0x00A0,0x040E,0x045E,0x0408,0x00A4,0x0490,0x00A6,0x00A7,0x0401,0x00A9,0x0404,0x00AB,0x00AC,0x00AD,0x00AE,0x0407,
13 0x00B0,0x00B1,0x0406,0x0456,0x0491,0x00B5,0x00B6,0x00B7,0x0451,0x2116,0x0454,0x00BB,0x0458,0x0405,0x0455,0x0457,
14 0x0410,0x0411,0x0412,0x0413,0x0414,0x0415,0x0416,0x0417,0x0418,0x0419,0x041A,0x041B,0x041C,0x041D,0x041E,0x041F,
15 0x0420,0x0421,0x0422,0x0423,0x0424,0x0425,0x0426,0x0427,0x0428,0x0429,0x042A,0x042B,0x042C,0x042D,0x042E,0x042F,
16 0x0430,0x0431,0x0432,0x0433,0x0434,0x0435,0x0436,0x0437,0x0438,0x0439,0x043A,0x043B,0x043C,0x043D,0x043E,0x043F,
17 0x0440,0x0441,0x0442,0x0443,0x0444,0x0445,0x0446,0x0447,0x0448,0x0449,0x044A,0x044B,0x044C,0x044D,0x044E,0x044F,
18};

Quote:

P.S. In the allegro manual there is no second argument in void allegro_message(const char *msg, ...);

allegro_message() uses same format with printf(). Please check printf() documentation.

Nedjalko Milenkov

Thanks to all for the help. It works!

Evert
Quote:

One last thing:

On a related note, don't call allegro_message() when you're in graphics mode. It will either not work or cause problems. You should call set_gfx_mode(GFX_TEXT, ...) before allegro_message() if you're in graphics mode.

Thread #463334. Printed from Allegro.cc