DirectWrite GDI interop: Simple way to draw text using an `IDWriteFontFace` - c++

I have a device context which has some font selected into it, and I would like to DrawText on an ID2D1RenderTarget.
Currently, I go the following route to acchieve this:
Obtain an IDWriteFontFace via CreateFontFaceFromHdc.
Obtain an IDWriteFont from the IDWriteFontFace via the default system font collection (which I get via GetSystemFontCollection - see the next step).
Obtain an IDWriteTextFormat via CreateTextFormat, supplying the parameters specified in the IDWriteFont and specifying nullptr as fontCollection, indicating that I would like to use the default system font collection.
Pass the IDWriteTextFormat to DrawText.
What I find strange about this is that I already have an IDWriteFontFace in the first step, and apparently have to "go back" and ask a font collection for an IDWriteFont, just to pass that to a DrawTextFormat, which can then be used to DrawText. This seems unnecessarily complicated - especially since to draw the text, the system probably has to go down to a IDWriteFontFace anyway, right?
I found DrawGlyphRun, but this takes e.g. a baselineOrigin, which I would have to compute beforehand (not to mention the glyphRun itself).
Isn't there a simpler way to draw text onto an ID2D1RenderTarget if I already have an IDWriteFontFace?

That's the only way, like you described. You go back to construct text format instance, and then use it for DirectWrite-style rendering. DrawGlyphRun is a low level method, you can use it of course, but you'll have to implement a lot of layout logic yourself, and that's something to avoid. Generally speaking DrawText is the least efficient method of rendering with Direct2D, better way is to create layout object once and use it every time you need to redraw.

Related

How to extend the existing mouse cursor in Windows app with some additional little image indications (may be multiple ones) based on the context?

As an example, imagine a complex snap operation, consisting of two active snappings in a context. Here two indicators on the second image show, that we are snapping perpendicularly and that we are snapping to any point of the line. When we drag out from the snapping intersection, we are not snapping to a point anymore, but we are still snapping perpendicularly to the reference line. For such and similar situations I would like to extend the cursor with different indicators, based on the context, like on these images.
Is it possible in MFC? Or otherwise in a Windows application?
Extending the cursor is not supported, you can only load one. So the best approach is to create all the cursors as .CUR files and then load them as needed.
Cursors can be created programmatically in Win32. The CreateCursor() function creates a cursor taking its dimensions, its hot spot and its AND (black) and XOR (invert) masks as parameters. Therefore you can create or load the basic pointer cursor masks and then add the indicators (either draw them using GDI, if they are simple, or load them from resources), creating the additional cursors you may need. I think it's a quite heavy job to do all these on the fly, so it would best to create all possible indicators during initialization.
The CreateCursor() function seems to create only monochrome cursors, maybe the CreateIconIndirect() function can create color cursors. Also take a look into this Win32 documentation topic: Using Cursors.
Of course this is quite an amount of work. You decide if it's worth or not...

What is necessary to toggle fullscreen in DirectX 11?

I've just started learning DX so I know almost nothing about it although I do know OpenGL (to certain extent). I'm follow a tutorial (http://www.rastertek.com/tutdx11.html) and I have a working window rendering just a white background (clear).
Now - how do I actually switch from windowed mode to fullscreen and vice versa? I know there are many tutorials, some even provide a code for doing that but since I'm a newbie that's not really helpful. Why? Because every code sample is different and trying to find a pattern in all of them is apparently too difficult for me.
So I don't ask for code - instead I would like you to tell me what things I need to release/recreate/change to toggle correctly (and all of them). I know I need to change the display settings, I know I have to change something about the swap chain and release/recreate some buffers - but not really sure which exactly.
You can use SetFullScreenState on your swap chain:
swapChain->SetFullScreenState(true, NULL);
MSDN
The main thing you have to do is release all reference to the IDXGISwapChain, call ResizeBuffers, then re-create everything.
Since Win32 throws the WM_SIZE message upon window initialization, it's entirely possible to:
Clear the previous window-size-specific context
If the swap chain already exists, resize it, otherwise create one
Obtain the backbuffer for this window which will be the final 3D rendertarget.
Create a view interface on the rendertarget to use on bind.
Allocate a 2-D surface as the depth/stencil buffer and create a DepthStencil view on this surface to use on bind.
Create a viewport descriptor of the full window size.
Set the current viewport using the descriptor.
inside a static function (unless WinMain has an object from which to call), and call that function when the WM_SIZE message is triggered.
You can check out how the DirectXTK does it here:
https://directxtk.codeplex.com/

How to implement zooming in GDI-drawn MFC's CScrollView

I'm drawing some graphics and text with GDI in my CScrollView. I need to implement the zooming functionality. I only need the zoom out functionality, no need to zoom in more than what is normally rendered.
Here are my best ideas:
Use MM_ANISOTROPIC mapping mode with SetWindowExt/SetViewportExt... The problem with this approach is that it does not scale text. Is there any way to force MFC to scale the text as well? Only thing I can think of is to set text font size according to the selected zoom value, but I'm not sure whether this will look well after all...
Draw to memory DC, and use StretchBlt to blit to the client area of appropriate size (set with SetScrollSizes...). This will solve the text scaling issue.
Also it is desirable to have antialiasing effect in the process. I think both methods above should accomplish this per se, but I don't know which will look better. Also I will have to implement printing/print-preview functionality later (using MFC's standard implementation from doc/view architecture), so I need the method to be compatible with that.
Need your advice please. Which way to go and why. Maybe other options exist too?..
You really don't want to mess with the mapping mode when you use MFC -- MFC itself already uses it for (at least) the print preview functionality.
I'd see if SetWorldTransform will work for you. At least with vector/TrueType fonts, it will scale the text along with everything else. Note that before SetWorldTransform will work, you need to call SetGraphicsMode with GM_ADVANCED.
I ended up using the second method I proposed in the question, but used DIBs instead of DDBs (and StretchDIBits() instead of StretchBlt()) because it proved to cause less problems, especially when using big bitmaps, and when printing.

How do I read the image currently on the framebuffer in Qt/C?

Is there any way I can read the content of the framebuffer in Qt or anyway in C? I read it is possible to write the content of /dev/fb0 to a file and then load it. But is it possible to avoid saving it to memory and simply copy to a new memory location to use in Qt?
Thanks!
The ordinary Qt distribution is not likely to have special support for reading a framebuffer on Linux. It layers on top of X11 and is trying to provide cross-platform capability (as things like /dev/fb0 won't have meaning on Windows, for instance). So you would use higher level abstractions, such as the QPixmap::grabWindow() that #BerkDemirkir points out...probably a lot of hops through layers before the framebuffer.
(Note: If you are writing an ordinary cross platform Qt app intended to run in a windowed environment, that's certainly the route you want to go for a simple screen capture task!!)
On the other hand, Qt/Embedded is designed for Linux and to work with the QWS instead of X11. The mindset is that there's no windowing system and your app owns the whole screen. It writes directly to the framebuffer through a QScreen object, which has a base() method that can actually give you a pointer to the underlying memory:
http://doc.qt.nokia.com/4.7-snapshot/qscreen.html#base
Those are probably the only "Qt" ways to do these kinds of things. If you want an API instead of going through to /dev/fb0 directly you might investigate something like EZFB. (I didn't dig deep enough to know if it's useful or not, just found it with a query something like "linux framebuffer API")
http://freshmeat.net/projects/ezfb/
You can look this example to take a screenshot from any window (even desktop). Example uses QScreen::grabWindow() function to take screenshot.

The DrawItem() method is performed repeatedly

I used the owner-drawn strategy on CMyListBox class which derives from CListBox. I only want the DrawItem() method to perform when I insert an item in the listbox. But the method is invoked many times. How can I change to invoke it whenever I need.
You could always cache the initial drawing by outputting the content to an in-memory bitmap and then drawing that, it does mean you need to track when something has changed so you can run the actual rending code agaain. It does save running through your render code everytime if there's a lot of it.
I've done exactly what Kieron suggests by caching bitmaps, but only in very expensive rendering code. I actually have to keep multiple cached "states" depending on if an item is highlighted, disabled, normal, etc (this is for toolbar buttons, not listitem - but I think it applies). I only cache the pre-rendered image when I first need it - that way I only cache "states" that I actually need.
My drawing was pure GDI calls. Mostly bitmap manipulations and other drawing that just takes time, plus I was being redrawn much too often (for no good reason - long story).
Changing the fundamentals in the framework I was using (MFC and Stingray) was just not an option. The caching was a last resort after all other optimizations weren't good enough (damn slow virtual machines!!).
Normally drawing is fast enough to do when you're invalidated (DrawItem in this case). I would take a look at what exactly you're doing in DrawItem. I would look into caching data and calculations that are needed by rendering and not the rendering itself (eg the final bitmaps) unless there are no other options.
Also, I read the Vista rending is more optimized, they cache what you've drawn on your window to reduce the contain invalidate/redraw cycle when, for example, a window is moved from behind another.
The DrawItem() method is called whenever there is a requirement to draw any given item in the listbox. If you do not respond to it you are likely to get a blank area in your list box, where the drawn data has been erased and you have not refreshed it. If you really do not think the drawing is necessary, you could do something like
void CMyListBox::DrawItem( LPDRAWITEMSTRUCT lpDrawItemStruct )
{
if (!m_DrawingEnabled)
return;
}
Where m_DrawingEnabled is a member you maintain to stop unnecessary draws,