|
Hi all,
I need some help from you: I try to render an SVG image on the screen (with alpha channel). The problem is, when I try to draw the image on the screen, I see absolutely nothing.
First of all, my SVG image is loaded correctly, and the ATL CImage from the below code, contains a correct image. The problem start when I try to use Gdiplus + alpha channel.
For instance, if I use PixelFormat24bppRGB instead of PixelFormat32bppARGB, the image is drawn correctly, but alpha channel is not preserved - a black halo is shown around my image.
Do you see any problem in my code?
PS: I use Win7, 32 bit + Visual Studio 2013 Ultimate.
Many thanks!
void CAppView::OnDraw(CDC* pDC)
{
int width = 600, height = 600;
GError* pError = NULL;
rsvg_init();
g_my_svg = rsvg_handle_new_from_file("d:\\myImage.svg", &pError);
rsvg_handle_get_dimensions(g_my_svg, &g_dimension);
cairo_surface_t *surface = cairo_win32_surface_create_with_dib(CAIRO_FORMAT_ARGB32, width, height);
cairo_t* cr = cairo_create(surface);
rsvg_handle_render_cairo(g_my_svg, cr);
HDC srcHDC = cairo_win32_surface_get_dc(surface);
CImage image;
image.Create(width, height, 32);
HDC imageHDC = image.GetDC();
TransparentBlt(imageHDC, 0, 0, width, height, srcHDC, 0, 0, width, height, RGB(0, 0, 0));
Gdiplus::GdiplusStartupInput gdiplusStartupInput;
ULONG_PTR gdiplusToken;
Gdiplus::GdiplusStartup(&gdiplusToken, &gdiplusStartupInput, NULL);
Gdiplus::Bitmap bmp(image.GetWidth(), image.GetHeight(), image.GetPitch(), PixelFormat32bppARGB, static_cast<BYTE*>(image.GetBits()));
Gdiplus::Graphics graphics(pDC->GetSafeHdc());
graphics.DrawImage(&bmp, Gdiplus::Rect(0, 0, width, height));
Gdiplus::GdiplusShutdown(gdiplusToken);
image.ReleaseDC();
image.Destroy();
cairo_surface_flush(surface);
cairo_destroy(cr);
cairo_surface_destroy(surface);
}
|
|
|
|
|
Can I first say you have no error checking at all in that code ... really bad programming practice
cairo_win32_surface_get_dc can fail and return NULL ... read the manual.
Why might there not be a win32 surface, well because you have to set a #define CAIRO_HAS_WIN32_SURFACE 1 in the cairo library .... again in the manual.
You code is totally reliant on srcHDC being valid ... Yet inexplicably you don't check it.
Secondly you probably want an alpha channel on the CIMage .. the create should be CreateEx
CImage image;
image.CreateEx(width, height, 32, BI_RGB, 0, 0);
Thirdly read TransparentBlt detail and if we do the Alpha channel it will then copy the source alpha onto the destination alpha ... is that Ok? If not you have to use AlphaBlend function.
Fourth check GDIPlus I seem to remember it had issues with Alpha channels.
Final comment is you seem to be making life difficult for yourself using 3 different systems for reasons that aren't clear. You are moving bitmap data around between systems for no real reason what you want can be done in any of the 3 systems and even natively on the Win32 API. You are even initializing the GDI plus system with a draw process ... like seriously please don't do it are you really hell bent on making the draw as slow as possible. Start the GDIPlus with the window or program and close it when done but not in a draw process ever.
In vino veritas
|
|
|
|
|
Actually the problem was related to the way of copying from srcHDC to ImageHDC. I have done like this:
HDC svgDC = cairo_win32_surface_get_dc(surface);
image.Create(width, height, 32);
image.SetHasAlphaChannel(TRUE);
HDC imageHDC = image.GetDC();
BLENDFUNCTION blend = { AC_SRC_OVER, 0, 255, AC_SRC_ALPHA };
AlphaBlend(imageHDC, 0, 0, width, height, svgDC, 0, 0, width, height, blend);
image.ReleaseDC();
Best regards!
|
|
|
|
|
|
When? How?
Sidenote: Was this meant to be a question, rant or discussion topic?
The sh*t I complain about
It's like there ain't a cloud in the sky and it's raining out - Eminem
~! Firewall !~
|
|
|
|
|
|
|
He might need it, but I doubt that he can get any decent beer in Iran.
(See the guy's profile)
If you have an important point to make, don't try to be subtle or clever. Use a pile driver. Hit the point once. Then come back and hit it again. Then hit it a third time - a tremendous whack.
--Winston Churchill
|
|
|
|
|
I think he has already had a few too many.
Speed of sound - 1100 ft/sec
Speed of light - 186,000 mi/sec
Speed of stupid - instantaneous.
|
|
|
|
|
Hi
I am new to VC++/MFC but have C++ background.
I am using addpage() of CPropertySheet class to add new tabs. My problem is that on click of a radiobutton control all tab pages should be disable except one.
How to solve it?
Vivek
|
|
|
|
|
This is how I've done it when the need arises.
"One man's wage rise is another man's price increase." - Harold Wilson
"Fireproof doesn't mean the fire will never come. It means when the fire comes that you will be able to withstand it." - Michael Simmons
"You can easily judge the character of a man by how he treats those who can do nothing for him." - James D. Miles
|
|
|
|
|
Anybody can please provide the solution?
|
|
|
|
|
I sent you a link to a working solution. I've used it in several projects.
"One man's wage rise is another man's price increase." - Harold Wilson
"Fireproof doesn't mean the fire will never come. It means when the fire comes that you will be able to withstand it." - Michael Simmons
"You can easily judge the character of a man by how he treats those who can do nothing for him." - James D. Miles
|
|
|
|
|
VS2008 unicode mfc project. Heavy use of CString variables. Other than the HMI display of text to the user, all other text is english. So, I might have something like this:
CString stmp;
stmp.Format(_T("%s"), _T("192.168.0"));
displaying in the debugger: stmp.m_pszData ---- 192.168.0
other times, I'll get what I guess is the unicode version --- 㤱⸲㘱⸸⸰
Anyone seen this weird behavior? I can run the program multiple times, and it seems like the debugger's presentation can change. I've not found the pattern yet.
Charlie Gilley
<italic>Stuck in a dysfunctional matrix from which I must escape...
"Where liberty dwells, there is my country." B. Franklin, 1783
“They who can give up essential liberty to obtain a little temporary safety deserve neither liberty nor safety.” BF, 1759
|
|
|
|
|
Have you tried %S instead?
"One man's wage rise is another man's price increase." - Harold Wilson
"Fireproof doesn't mean the fire will never come. It means when the fire comes that you will be able to withstand it." - Michael Simmons
"You can easily judge the character of a man by how he treats those who can do nothing for him." - James D. Miles
|
|
|
|
|
Darn, someone responded before I could delete my silly post. I'm converting strings incorrectly (most of the IP work on Windows uses char and now wchar_t. So, self inflicted injury.
Charlie Gilley
<italic>Stuck in a dysfunctional matrix from which I must escape...
"Where liberty dwells, there is my country." B. Franklin, 1783
“They who can give up essential liberty to obtain a little temporary safety deserve neither liberty nor safety.” BF, 1759
|
|
|
|
|
Hi,
I am sure this is right but I am having a hell of time debugging a multithreading application
When executing the same code/functions each thread has its own set of registers and local
Variables
Thanks
|
|
|
|
|
Yes, each thread has its own stack (local variables), registers, and "thread-local-storage". Static and global variables are common to all threads.
This is what makes multithreaded programming such a joy...
If you have an important point to make, don't try to be subtle or clever. Use a pile driver. Hit the point once. Then come back and hit it again. Then hit it a third time - a tremendous whack.
--Winston Churchill
|
|
|
|
|
This is, despite the title, not really a question.
Clearly there will be multiple threads yes, that's the point.
What do you want to know?
|
|
|
|
|
Yes, just the same as MVS and VM programs.
|
|
|
|
|
The problem is the breaking the debugger doesn't stop the system clocks on the PC which means you get a backlog and out of sequence queue of things to happen when you release the debug. So often your debugging does not look like the system when running which can be more than a little frustrating
There is an extension that helps
GitHub - mayerwin/vs-debug-single-thread: Debug Single Thread - Visual Studio Extension[^]
But at times it still gets frustrating.
In vino veritas
|
|
|
|
|
If you're familiar with Visual Studio debugging options they include a Task window, Thread window, and a window to view Parallel stacks. All these windows support various flags and the Parallel stacks shows a nice visual diagram of the execution environment. There's also the Tracepoint option if you want a breakpoint that outputs state information but doesn't halt execution.
I don't really see the issue with out of order execution. That should be something addressed in your code with barriers/fences, locks, semaphores, mutexes, or whatever else you use.
|
|
|
|
|
Thanks
The visual studio thread window I know has the ability to freeze a thread
Regardless I'll down load the
Extension
Let me explain the nature of the problem
I'm writting a debugger for another platform
The way I Interrupt the program and show the user the code is by overlaying the instruction which causes a interrupt and allows me to get control
I quickly put back the instruction that was overlayed
However the interrupt gives me control
This all fine when the "Debugged" program is single thread
However in a multi thread program in which other programs use he same code
I get a operation exception
The way I coded this was the as soon as I overlay the instruction I do a Restevent which cause an event to be non- signaled this will cause the other programs to Wait or WaitForSingleEvent until I have chance to put the instruction back and then I do a SetEvent to let execution of the program to the other threads trying to execute it
Something is obviously not working out right in this timing
In Visual Sudio I can observe how QUICKLY the windows dispatcher switches from thread to thread
Thanks
|
|
|
|
|
Lets see if I have got this right
The other threads won't stop until they hit a lock point. So let me imagine they are in the section of code you overlayed. They will see your overlay (which is an interrupt opcode I guess .. you transposed the real opcode out to a hold memory somewhere). However interrupts will be disabled because you are in the IRQ routine already so it then continues thru to next opcode.
I can imagine if that is the scheme you end up with two equally bad situations
1.) the other threads pull an illegal opcode if your transpose isn't the same length as the replaced opcode
2.) they pass thru the overlay missing the held opcode (they saw the interrupt request which was ignored). So anything could happen the thread missed an entire opcode.
If that is what you are doing there is no fix, you either can't have the threads going thru the same code or you need to stop the threads immediately the other threads even advancing one opcode can be fatal much less allowing them to run to next lock point.
This goes back to what I was getting at originally you need to stop the system totally in some schemes. Some processors like Arm and many microcontrollers can do that under system control for hardware debugging. The Raspberry PI which uses an ARM6/7/8 could do that for example. I fear your current schema needs a full hardware debugging setup if I understand it correctly.
Edit: Assuming above is correct I gave this a bit of thought and there is possibly a way to do this on a normal non stepable processor. You have the stacks of the threads and that contains the Program Counter for each thread. So overlay the other threads as well this time with a relative branch instruction to there current position ... get it ... will deadloop them to exactly where they are ... meeting the requirement they don't move even one opcode forward You don't need the event stuff at all it's just a repeat of what you do to the active thread in the interrupt overlaying a different instruction into non active threads. Just make sure you put back the opcodes in reverse order (incase two threads are in the exact same place) from within an interrupt when you want to release it back.
In vino veritas
modified 10-Jan-17 0:55am.
|
|
|
|
|
I am a MainFrame Assembler programmer by trade
this is the emulator
The Hercules System/370, ESA/390, and z/Architecture Emulator[^]
I overlay two bytes of code (causing it to pause) right before I overlay the code I do a ResetEvent which will cause a manual Event to be NON-signaled the threads right behind this will stop on the WaitForSingleObject
I have code to determine the Work unit executing code in CSA (common storage) it is only for that code that I do a ResetEvent and then memcpy
Once the emulated code that I overlayed (cuasing it to interrupt and pause)
I put back the legal opcode via memcpy right after I do a SetEvent for the other workunits executing the common storage to proceed (as it is now okay) and bypass the overlaying logic
I will paste the relevant code shortly as it is late (have to get to sleep)
I wanted to give you a feel (of what I doing) as you have been so verrrrrry helpful
|
|
|
|
|