creating borders in ncurses with unicode characters - c++

Currently coding in C++ in WSL2 with ncursesw.
For the box() or border() functions/macros in ncurses, is it possible to use unicode characters with them, or do they not fit in the category of chtype?
I'm trying to create a border using the double line box drawing characters.
If not, do I have to create a border manually with other functions such as addstr() in for loops?

box and border use chtype's which provide only A_CHARTEXT bits for characters (8 bits in ncurses). To go beyond that, use box_set and border_set. Those use cchar_t structures, which you would initialize with setcchar.

Related

Adjusting line height in C++

I am attempting to put the final touches on a maze program I have been writing. I have used Unicode to delimit the walls and paths however because of the (horizontal) line spacing I can't quite get it to look compact enough. I have attached two screenshots. I'm just escaping the newline "\n" in order to print each row. Can the distance between lines be adjusted or am I stuck with this "gappy" representation?
My output:
What I am trying to closely represent:
Assuming you aren't printing double newlines, this is outside the scope of standard C++, it does not provide facilities for controlling terminal in a standard way.
Solutions:
You could provide a launcher script, which opens a new terminal window with specific font and runs your app in it.
You could use some platform specific method to change background color (ANSI codes work in unixy terminals, or use Win32 API for Windows terminal, ncurses library on Unix-like environments) and print just spaces in different colors.
Use a GUI library/framework to get complete control on what is drawn (I'd use Qt for C++ GUI app).
TBH if you want pixel-accurate rendering use a proper rendering API, such as OpenGL.
From a text rendering point of view you don't say what you are rendering to. Assuming something like a terminal console or shell window then the layout beyond characters and newlines is nothing to do with your program; the visual representation is entirely determined by the shell you are rendering to.
Firstly, check that you are genuinely printing a line per maze scan line, and not interleaving with spurious newlines. Assuming that is ruled out, the problem is that the unicode glyph is not a full block. So you must somehow set the font or choose another glyph which is a full block.
Usually console windows are 80 characters wide by 22 or 24 characters high, and characters are 8 pixels wide by 19 pixels high. So it's very far from a square grid, and you might want to bias the maze to reflect that and provide a better visual appearance (eg make 2 pixel-wide vertical corridors much more common than 2-pievel wide horizontal corridors).
Do check the binary image library fonts, you might find them useful.
https://github.com/MalcolmMcLean/binaryimagelibrary

How to display Unicode values in the little boxes?

In the pluma editor (on Linux) and sometimes in a web browser, for unrecognized characters, I see a little box with the Unicode value inside. I have seen 4 digit and 6 digit code boxes.
I WANT these little boxes with numbers (as appropriate.) How do I get these to display in a C++ Qt program?
Can you get a two digit box?
Here is an example, as shown in the pluma editor:
These glyphs are produced by the default fallback font for the system/platform – they are not inherently a feature of Qt.
If you want all characters to be rendered this way, you can use the Unicode BMP Fallback font, which has glyphs for all code points in the basic multilingual plane as hex digits in a box.

Print chess unicode characters in C++, and make characters square sized

I'd like to ask what's the simplest way of writing the chess unicode characters in a console window in C++? (♙♘♗♖♕♔♟♞♝♜♛♚) They are part of the "Miscellaneous Symbols" block in unicode. https://en.wikipedia.org/wiki/Chess_symbols_in_Unicode
I also want to print characters with square size, right now my chess board is not square, because each character is a rectangle and not a square.
It'd also be good to be able to write with ordinary non-square characters below the chess board, but that might be impossible? To mix different fonts/formattings in the same console window?
Ok, thanks in advance! :)
The first part of your question, outputting those characters, is platform-dependent. Linux consoles often use UTF-8, if that is the case you can encode the characters as UTF-8 and write them to standard output. On Windows you can use the Console API (the WriteConsole function):
HANDLE handle = GetStandardHandle(STD_OUTPUT_HANDLE);
DWORD written = 0;
// explicitly call the wide version (which always accepts UTF-16)
WriteConsoleW(handle, L"\u2658", 1, &written, NULL);
One caveat which is hard to work around is that you need a console font containing those characters.
For getting square cells, this is dependent on a lot of specifics about the way the console renders text. If it uses font substitution, then there is a chance the text will not actually be monospaced.
Now, if you have a console font with these characters, and if that font is monospaced, then you may be able to draw a square board by adding some spacing between the characters. You can use block elements like ▌ U+258C — LEFT HALF BLOCK to draw the chequerboard: ▌♘▐█▌ ▐.

How to get correct position in the std::string?

I am creating a custom single line edit control, with a custom font in win32 api on windows 7, the font is not a fixed width font, and I need to move caret according to the mouse click, The edit control is not empty and if I know the horizontal position of the mouse click within the window, how do I calculate the number of characters after which I need to move caret to ?
I really am out of ideas, if it was a fixed width font, I would have divided the horizontal mouse click position with average character width, that would have been simpler, doing the same with not a fixed width font, is prone to errors.
Given that it's a single-line control, you probably don't plan on working with immensely long input (at least normally). That being the case, one possibility would be to just store the character positions in an array (or vector, etc.) Then you can use (for example) a binary search in that array to find character positions. Of course, you can do the same even for longer strings--though it can increase storage requirements quite a bit.
This is a familiar problem. You are in essence trying to do hit testing on text and for that you need the location on the screen of each character of the text.
My preferred strategy is to calculate an array of RECT, one for each character of displayed text. The array needs to be updated when text is added or deleted, but it easily handles single or multiple lines. The function GetCharWidth32 retrieves all the widths for a string of text in a particular font selected into a DC. For single line one call is enough, and calculating the array of RECTs is simple. It's not much harder to do multiline.
Handle the mouse down message, loop through the array and find the right character. A brute force search is plenty fast enough.
This method is simple and easily generalises to a range of similar problems.

word wrapping block of text with variable font/formatting using winapi

I need to draw an arbitrary string directly on the screen (not inside a rich text control) using MFC and/or the Windows API. Characters within the string can vary in font face or color, and can be bold, italic, underlined, or any combination of the two. Additionally, users can choose to wrap the text within bounds of their choosing, with an option to force it to fit by adjusting the font size.
I'm thinking of doing something along the lines of:
parsing it into a vector of substrings and their formats
using GetCharABCWidthsFloat to calculate the widths of all the substrings
manually calculating where the line breaks need to fall
repeating the above iteratively with smaller fonts if necessary to make the text fit
drawing each of the substrings individually with DrawTextW, determining their locations using the widths of the preceding substrings and the line break points
Is there a better approach? If not, are there any gotchas or tricks I should be aware of when implementing this?
(I'm aware of the DT_CALCRECT | DT_WORDBREAK flags for DrawText, but I don't think that'll work for me because a) it assumes consistent font/formatting across the whole string and b) I saw some message board posts stating that it doesn't calculate the widths of italic characters correctly. True?)
XAML is your friend. Not natively supported without .NET, but there are 3rd party libraries for that (e.g. Xtreme Toolkit Pro). Here's a demonstration of the XAML Markup feature:
http://www.codejock.com/download/win32/markupsample.zip
Been using it for years. Can't complain.