Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

Displaying unicode chess pieces in Windows-console

I've been developing a console Chess-game in C++ (using MVS2010) and I seem to have faced a problem I cannot solve on my own. The matter is that I need to have the following chess pieces displayed in console: http://en.wikipedia.org/wiki/Chess_symbols_in_Unicode

I certainly went through a great amount of forums, articles and documentations and still does not have the task done. I understand that some characters (in particular, the ones I need) cannot be displayed using fonts provided by Windows-console. But console supports only several fonts: consolas and lucida console. The last one is good enought for displaying great amount of characters, but not all of them. The snippet below is one of the closest to my needs:

#include <Windows.h>
#include <wchar.h>
int main()
{
    UINT oldcp = GetConsoleOutputCP();
    SetConsoleOutputCP(CP_UTF8);

    wchar_t s[] = L"\x266B";
    int bufferSize = WideCharToMultiByte(CP_UTF8, 0, s, -1, NULL, 0, NULL, NULL);
    char* m = new char[bufferSize]; 
    WideCharToMultiByte(CP_UTF8, 0, s, -1, m, bufferSize, NULL, NULL);
    wprintf(L"%S", m); 
    delete[] m; 

    SetConsoleOutputCP(oldcp);

    return 0;
}

When using it to display the following character it works: \x266B (only when Lucida console is in use). But when I try to display \x265B it prints an empty square instead of chess piece. Here is a link to chess-characters: http://unicode-table.com/ru/#geometric-shapes

The following code-snipped is even much more clear and small and behaves like the one above:

#include <iostream>
#include <io.h>
#include <fcntl.h>
#include <Windows.h>
int main(){

    //_setmode(_fileno(stdout), _O_U8TEXT);
    //_setmode(_fileno(stdin), _O_U8TEXT);

    _setmode(_fileno(stdout), _O_U16TEXT);
    _setmode(_fileno(stdin), _O_U16TEXT);

    wchar_t * str=L"\x265B\n";
    std::wcout<<str<<std::endl;
    return 0;
}

It seems that all I need now is to find out a font that could display the characters I need, but the question is that can I programmatically configure console when starting application to make it able to display such symbols?

Thanks in advance!

like image 539
anton.vodostoev Avatar asked Dec 15 '14 12:12

anton.vodostoev


1 Answers

I was able to display the chess pieces correctly. The main issue is that the default console font does not include the glyphs for the chess pieces. You can fix that by installing DejaVu Sans Mono as the console font.

After doing that, there are two possible approaches (I am using MinGW-w64).

Using UTF-16

HANDLE cons = GetStdHandle(STD_OUTPUT_HANDLE);
wchar_t p[] = L"Queen: \u265B.\n";
// wprintf(p);
DWORD n;
WriteConsoleW(cons, p, wcslen(p), &n, NULL );

Note that the wprintf doesn't work. I believe this is because MS's console routines are terrible , and MinGW routes through those.

Using UTF-8

SetConsoleOutputCP(65001);        // Command prompt UTF-8 code page
char q[] = "King: \xE2\x99\x94.\n";
printf(q);

Cygwin note: Cygwin seems to behave differently depending on whether you have Raster Font or a TTF font chosen. With DejaVu Sans Mono used for Cygwin also, both options displayed correctly.

like image 183
M.M Avatar answered Sep 19 '22 18:09

M.M