Chcete používat ve svých programech FreeType Fonty i s českými znaky? Pokud ano, jste na správném místě. Tento článek doplňuje NeHe Tutoriál 43, ve kterém bylo popsáno použití FreeType s OpenGL, ale bohužel bez českých znaků. Použito s laskavým svolením tvorbaher.bonusweb.cz .
Asi první, co vás napadne, aby kód podporoval české znaky, bude záměna datového typu char za unsigned char a všude, kde se nachází číslo 128, napsat 256. Bohužel tato úvaha není správná, FreeType používá kódování, ve kterém se české znaky nacházejí na vyšších indexech než 256. Záchranou tedy bude typ wchar_t, který má velikost 2 byty a je určen právě pro takové účely.
Hlavičkový soubor FreeType.h necháme téměř nezměněný. Pouze řádek s using std::string; upravíme na
using std::wstring;
díky čemuž budeme moci používat 16-bitové znaky.
Ve zdrojovém souboru FreeType.cpp uděláme změn trochu více. Nejdříve přepíšeme ve funkci make_dlist() char ch na wchar_t ch. Dále nahradíme číslo 128 za 383, které bude specifikovat počet jednotlivých display listů potřebných pro uložení všech písmen. Znak ž, který se nachází v abecedě jako poslední, používá kód 382, nezapomeňte, že pole v C/C++ začíná od nuly. Konkrétně se jedná o následující řádky
textures = new GLuint[383];
list_base = glGenLists(383);
glGenTextures(383, textures);
for(unsigned char i=0; i<383; i++)
...
glDeleteLists(list_base, 383);
glDeleteTextures(383, textures);
Při renderingu textu v print() umístíme za sekci
if (fmt == NULL)
*text=0;
else
{
va_start(ap, fmt);
vsprintf(text, fmt, ap);
va_end(ap);
}
cyklus, který konvertuje všechny znaky do správného kódování. Znaky bez háčků a čárek zůstanou nezměněné. Znaky s háčky se nahradí předepsaným kódem a znaky s čárkami se zkonvertují z char (záporné hodnoty) na unsigned char. Kódy znaků s čárkami jsou stejné pro obě kódování.
wchar_t NEWtext[256];
wchar_t znak;
for(int loop1=0; loop1<256; loop1++)
{
switch(text[loop1])// V text je uložen tištěný řetězec, který je v původním kódování
{
case 'Č':
znak=268;
break;
case 'č':
znak=269;
break;
case 'Ď':
znak=270;
break;
case 'ď':
znak=271;
break;
case 'Ě':
znak=282;
break;
case 'ě':
znak=283;
break;
case 'Ň':
znak=327;
break;
case 'ň':
znak=328;
break;
case 'Ř':
znak=344;
break;
case 'ř':
znak=345;
break;
case 'Š':
znak=352;
break;
case 'š':
znak=353;
break;
case 'Ť':
znak=356;
break;
case 'ť':
znak=357;
break;
case 'Ů':
znak=366;
break;
case 'ů':
znak=367;
break;
case 'Ž':
znak=381;
break;
case 'ž':
znak=382;
break;
default :
znak=(unsigned char) text[loop1];
break;
}
NEWtext[loop1]=znak;
}
// const char *start_line=text;// Tento řádek zaměníme za:
const wchar_t *start_line = NEWtext;// Přiřazujeme předpřipravený řetězec ve správném kódování
Na následujících několika řádcích, podobně jako v hlavičkovém souboru, zaměníme třikrát string za wstring. A také const char na const wchar_t a text za NEWtext.
Kvůli rozdílné velikosti char a wchar_t musíme ještě upravit glCallLists(lines[i].length(), GL_UNSIGNED_BYTE, lines[i].c_str()); na glCallLists(lines[i].length(), GL_UNSIGNED_SHORT, lines[i].c_str());. Typ wchar_t odpovídá unsigned short int.
Nakonec nezapomeňte přidat k výslednému .EXE souboru český font.
napsal: Lukáš Beran - Berka <sysel001 (zavináč) seznam.cz>, 22.10.2004