I need to convert some text-to-bitmap rendering routines in existing C++ code that is using GDI and GDI+ to use DirectWrite (CFF support and OTF-feature support required).
I'm new to DirectWrite. Spending some time on research on what's required for the migration of existing functionality and doing some prototyping, I encountered an issue:
My problem is that DirectWrite (out of the box) doesn't support character spacing adjustment (which is a requirement for the existing app), at least not on Windows 7. I know it comes with Windows 8, but another requirement for this existing app is to run on Windows 7, unfortunately.
What I found in my research so far is that the way to go seems to implement a custom DirectWrite Text Layout, but I haven't found any good guideline on how to do this, especially in regards for character spacing (the documentation/examples on MSDN in regards of how to create a custom Text Layout are a little vague for my taste).
As I figure this must have been done before, before spending days and/or weeks of research and developement on re-inventing the wheel, does anybody here know a sample implementation of a DirectWrite text layout with custom character spacing I could use as a starting point or tutorial?
UPDATE1: Not an answer but - I found out that the IDWriteTextLayout1 interface (which supports setting the Character spaces) not only comes with Windows 8, but also with "Windows 7 Platform Update for SP1" (KB 2670838) on Windows 7. as I can require that for out app to run properly, this solves my issue, although it doesn't answer my question.
A custom layout is pretty complex due to bidi and line wrapping and the need to call the lower level API's, but a sample is here [https://msdn.microsoft.com/en-us/library/windows/desktop/dd941711(v=vs.85).aspx]. As for character spacing, once you have the array of glyph advances back from the shaping process (IDWriteTextAnalyzer::GetGlyphs), just add a delta onto all the advances. In the linked SDK sample, you would add a for loop inside FlowLayout::ShapeGlyphRuns so that it happens before line wrapping and drawing.
STDMETHODIMP FlowLayout::ShapeGlyphRuns(IDWriteTextAnalyzer* textAnalyzer)
{
...
hr = ShapeGlyphRun(textAnalyzer, runIndex, glyphStart);
...
// Add additional character spacing to each trailing edge of each glyph.
for (auto& advance : glyphAdvances_)
{
advance += 5.0f;
}
...
}
Note an API ApplyCharacterSpacing was also added to Windows 8 which is more robust than adding it manually yourself because it considers more complex scripts with multiple glyphs per cluster (but of course if you have that API, then you also already have IDWriteTextLayout::SetCharacterSpacing).
Related
My goto font for code text editing, in my own editor, has, for years, been Consolas.
I thought its coverage was good but then I discovered that W10 was adding an automatic fallback so even my Ancient Egyptian hieroglyphics font (U+13000 et al) would appear.
Now my editor (internally UTF-8 multi-byte but switching to WCHAR for display including packing two part 21 bit Unicode which the SDK handles nicely) has offered a pop-up box that provided a quick and easy access to characters not on my keyboard and that used GetFontUnicodeRanges() to determine the coverage.
This is obviously now woefully inadequate. I've searched but not found a way to determine what character codes will result in a character on the display and yet Windows is doing it effortlessly at runtime. I can ask about any individual font I want to load but not what will happen.
I must be missing something. I really don't want to resort to writing whole blocks of text to an HDC to a bitmap and then pattern matching on that for the old rectangle or the ? in a box we all know so well.
Has somebody already done this?
Is there a magic trick I am missing?
I am retired now so I have time to delve but I've run out of ideas.
Title says pretty much everything. Once upon a time when I was under 13, my older bro did in BorlandPascal a thing which amazed me. He defined kind of table [8][8] with values of 1 and 0, meaning respectively foreground and background. Having several of such tables he could somehow redefine default ASCII characters to look like in these tables. I have no idea how it was done, but it worked.
My question is: can I do similar thing in ncurses, and if I can then how to do it?
The short answer is no. What ncurses does is generating ANSI escape codes which are interpreted by the terminal. There are no codes for altering the font. (Althou there have been extensions propesed no commonly used terminal supports them, neither does ncurses.) And there is no generic way of communicating with the terminal through some kind of side channel for changing the font. But there might ways in some specific situations.
If you have direct access to a Linux console for example you could could do all sorts of things, much like in Borland Pascal. But it will likely be more messy and less impressive.
As the selected answer explains, this is not possible for NCurses to render custom glyphs. ncurses only manipulates the terminal screen state via escape codes (Clearing and rewriting lines to achieve interactivity).
However it should be noted that's very possible to use custom glyphs in the terminal via custom fonts.
This is what Powerline does (a popular terminal UI status line for vim, tmux and friends): https://github.com/powerline/fonts
By patching the fonts, you can inject your glyphs into the existing font being used by the terminal, which then you can access and render via ncurses as any other character.
Of course this is not ideal solution, but with some auto patching of the fonts, and careful testing, it makes it possible to build an app that uses custom glyphs—when your really in a pinch for more expressive UI tools than ncurses can offer.
Further reading: https://apw-bash-settings.readthedocs.io/en/latest/fontpatching.html
actually i'm thinking of creating a cool interface for my programming assignment , so i go around searching on how to do it so that such an effect can be create , below is the image .
The Question
1.)What is needed in order to create a program that run pseudographic(semigraphic or whatever they called it) that has menu like BIOS wizard did??I always see some program run in console but it could have graphical-like looking , for example blue environment , and user can use keyboard to choose a list of setting in a menu.
Thanks for spending time reading my question.
It's called Text-based user interface. There're several libraries for doing this. I think this is what you're looking for. :)
Cross platform, Interactive text-based interface with command completion
http://www.gnu.org/s/ncurses/
Ncurses(or maybe pdcurses) is probably what you need.
In the days of 16-bit Windows console windows used to support ANSI escape sequences (via the ansi.sys driver), but they no longer do.
For the apparent line graphics you need to use a platform specific solution anyway, so I recommend just writing an abstraction (functions, class) over the Windows APIs console functions.
The line graphics is done by using characters from the original IBM PC character set, codepage 437. At first you can just hardcode the various patterns. In order to make it seem more like line drawing to the code, or from the code's perspective, so to speak, you'll have to abstract things again. As I remember there is some partial but not complete system in the original codepage 437 character codes. But for Windows console you will need to use the Unicode character codes, which probably do not preserve the original system, so perhaps just define a map where these graphics characters are placed more systematically.
Possibly that already exists.
If you don't care about portability, the Windows API for this can be found here. It will supply all the functions you need, without the need to pack additional libraries with your application.
You can also look in to graphics.h, a non-standard Borland extension that a lot of older graphical games used to use. It goes far beyond the normal limits of the console, but is only supported by 16 bit systems, of which Microsoft has all but removed support for from Windows. You'd also need an ancient Borland compiler, or an emulation, though you probably want the original look and feel.
I am doing an exercise from The C++ Programming language (page 325, exercise 12.7, question 2).
It says:
Implement a simple graphics system using whatever graphics facilities
are available on your system (if you dont have a good graphics system
or have no experience with one, you might consider a simple "Huge bit
ASCII implementation" where a point is a character position and you
write by placing a suitable container, such as * in a position)
Now, what I gather from that, is that if I dont want to use GDI+ or Direct X then I can do this in a console app using chars like _,*, or -.
Am I thinking about this the right way?
If I am, am I right in thinking that I need to be able to draw a character anywhere on the console?
If so, how do I draw a char anywhere on the console?
Or I could be wrong and you can tell he what I might want to try (not GDI+ / DirectX if possible)
In order to draw a character anywhere to the console you really need to use an operating system specific library for console access, or a cross-platform console library.
If you were doing this for Windows you would use the Windows Console API (MSDN), a function that could draw a character to a specific location is FillConsoleOutputCharacter (MSDN).
It used to be that ANSI escape sequences could be used, but having read your question and investigated here, it seems these no longer exist.
The best option appears to be to use the windows console APIs, documented here.
There looks to be a pretty good example of how you might proceed here.
Good luck with this, it sounds interesting!
Fond memories of doing this in computer class, back when we had chaarcter sets with ▄ ▀ █. Double-resolution graphics ;). If you wanted one in column 8, you'd print 7 spaces in front of it. And if you wanted it at line 3, you'd print two \n in front. But yes, you'd have to consider up front what you were going to draw. To redraw one character, you'd have to redraw everything.
I am writing a windows program (no mfc) and need to output a status line to the operator every few seconds or so. I tried using rich text boxes but after so many hours it seems to hang up. Does anybody have an suggestions on what I can use instead?
People mentioned that my buffers might have been exhausted. I thought I had planned for that. After I had about 1000 lines displayed I would take the first 500 and remove them using the select and cut options in rich text boxes. I still ran into the same problem.
This question appears relevant, and this one too. But they don't give any concrete recommendations for an alternative to rich text boxes.
You might try the Scintilla control (scintilla.org) which does not appear to have any hard limitations on text size. It has a permissive license. It is used by many text editors such as Notepad++, Notepad2, Code::Blocks, FlashDevelop. I haven't tried it personally but there from the documentation it looks easy to use it in a Windows API application. Of course, it might be overkill for your purposes.
If you keep appending to the text in the control every few seconds for hours then you are probably running into some memory constraint on the control or the process. I think you would have this problem with any control you choose given update frequence and how long you're running the program.
Have you considered implementing a simple circular buffer for the content of the text box? Say only keep the last hour's messages. You could maintain a separate log file for history if the operator needed to go back in time for hours.
I ended up writing my own control to do this, essentially duplicating the Output window in Visual Studio. It was a success, but it ended up being much more code than I thought it would be when I started - I insisted on features such as auto-scrolling when the cursor was on the last line, select/copy, bold text, etc. It was backed by a std::deque so I could limit the number of lines stored for the window.
Unfortunately the code belongs to a former employer so I can't share it here.