Uh, in many cases this will be worse than a failed draw.
Vincent Povirk madewokherd@gmail.com wrote:
Uh, in many cases this will be worse than a failed draw.
wineps and most (if not all) printer drivers do not support blending or any transparency, if you know another way to print images with gdiplus I'm all ears.
You can't rely on the area we're drawing to be rectangular. We use AlphaBlend to draw rotated images, any text that isn't a solid color, and any brushes other than solid or hatch brushes. Anything we can't do accurately with gdi32 will use AlphaBlend, and the number of cases will only increase.
Can't we fix wineps?
Can we read the bits back from wineps and write new bits with the image applied?
If neither of those things are possible, the best we can do is to do ALL of our drawing through alpha_blend_pixels (by using a GpGraphics without an hdc), compose the result internally, and blit the result with a mask based on the resulting alpha values when GdipFlush or GdipDeleteGraphics is called. But until we have a line/curve drawing implementation using alpha_blend_pixels, that would cause those operations to fail.
Vincent Povirk madewokherd@gmail.com wrote:
You can't rely on the area we're drawing to be rectangular. We use AlphaBlend to draw rotated images, any text that isn't a solid color, and any brushes other than solid or hatch brushes. Anything we can't do accurately with gdi32 will use AlphaBlend, and the number of cases will only increase.
I tested printing quite a bit of different documents with an application I have here and all of them get printed correctly with the patch. Before the printed pages were just blank. What do you think is better for a user?
Can't we fix wineps?
Can we read the bits back from wineps and write new bits with the image applied?
Of course we can't. Printer drivers just convert input commands into direct output to a printing device on the fly.
If neither of those things are possible, the best we can do is to do ALL of our drawing through alpha_blend_pixels (by using a GpGraphics without an hdc), compose the result internally, and blit the result with a mask based on the resulting alpha values when GdipFlush or GdipDeleteGraphics is called.
Did you test it under Windows? Does it really do it that way?
But until we have a line/curve drawing implementation using alpha_blend_pixels, that would cause those operations to fail.
PNG (with transparency) and JPEG/BMP images do print with my patch same way as they look like under Windows. May be I'm missing something, but IMO it's better to print something (and fix any probable problems later) instead of printing empty pages.
I tested printing quite a bit of different documents with an application I have here and all of them get printed correctly with the patch. Before the printed pages were just blank. What do you think is better for a user?
It's not good if things work by coincidence in one case that's important to you, and then we can't fix other cases later (or we can't fix other cases without breaking yours).
If neither of those things are possible, the best we can do is to do ALL of our drawing through alpha_blend_pixels (by using a GpGraphics without an hdc), compose the result internally, and blit the result with a mask based on the resulting alpha values when GdipFlush or GdipDeleteGraphics is called.
Did you test it under Windows? Does it really do it that way?
I heard a rumor that native draws by reading screen bits and writing back modified screen bits. This is consistent with what I know about the GDI+ API (in particular, it seems to be the only way to fully control gamma correction, which the API allows). I have not made any attempt to verify this.
Based on the things the GDI+ API allows and the things it doesn't, I believe it does everything based on its own implementation of AlphaBlend (except when drawing to a metafile Graphics created using the GDI+ metafile API's; in those cases I believe it tries harder to express things in terms of gdi32 operations, even to the point where it loses things in the translation). In particular, it respects alpha everywhere, and it doesn't allow things like SRCAND that cannot be expressed in terms of AlphaBlend. So I believe the best implementation would be based on AlphaBlend, with "optimizations" for the simple cases that gdi32 can handle. That prevents us from controlling gamma correction but otherwise allows us to do everything correctly.
I can't and won't test how native does anything. I will always look for the most efficient way to do things as well as native can do them. I'm willing to compromise on gamma correction because doing it correctly would be a heavy performance hit for something people aren't likely to notice much.
Until proven otherwise, I have to assume that native can handle the full range of drawing operations that are possible when drawing to a screen DC or image, such as filling paths with a partially transparent color. If you test on Windows (not just with native gdiplus) and find there are limitations to what GDI+ can print, then I can accept a method of drawing that has the same limitations.
I would be interested in how rotated images, translucent images stacked on top of each other, and translucent shapes print on Windows with GDI+. If you can find some limitations there, then maybe I can accept a broken alpha_blend_pixels, or some alternate paths for printer DC's specifically.
I have a program that I use to test GDI+ drawing operations. Maybe it can help with this.
PNG (with transparency) and JPEG/BMP images do print with my patch same way as they look like under Windows. May be I'm missing something, but IMO it's better to print something (and fix any probable problems later) instead of printing empty pages.
Have you tried composing transparent PNG images on top of each other? I don't think that will work with your patch.
Given that alpha_blend_pixels is designed to be the default way to draw anything, it's not acceptable for it to be so severely broken.
Vincent Povirk madewokherd@gmail.com wrote:
I tested printing quite a bit of different documents with an application I have here and all of them get printed correctly with the patch. Before the printed pages were just blank. What do you think is better for a user?
It's not good if things work by coincidence in one case that's important to you, and then we can't fix other cases later (or we can't fix other cases without breaking yours).
I don't understand your objection, nothing prevents you from improving my patch. Printing something is still better than printing nothing, consdier this as adding a partial implemenation in the place of a stub. GdiAlphaBlend is not supported by printers, that's a matter of the fact, using StretchBlt for now is better than doing nothing and even not printing a FIXME or returning an error to an application. Feel free to implement it differently, until that my implementation is suffice for many applications.
If neither of those things are possible, the best we can do is to do ALL of our drawing through alpha_blend_pixels (by using a GpGraphics without an hdc), compose the result internally, and blit the result with a mask based on the resulting alpha values when GdipFlush or GdipDeleteGraphics is called.
Did you test it under Windows? Does it really do it that way?
I heard a rumor that native draws by reading screen bits and writing back modified screen bits. This is consistent with what I know about the GDI+ API (in particular, it seems to be the only way to fully control gamma correction, which the API allows). I have not made any attempt to verify this.
Obviously this can't work for a printer.
I tested printing quite a bit of different documents with an application I have here and all of them get printed correctly with the patch. Before the printed pages were just blank. What do you think is better for a user?
It's not good if things work by coincidence in one case that's important to you, and then we can't fix other cases later (or we can't fix other cases without breaking yours).
I don't understand your objection, nothing prevents you from improving my patch. Printing something is still better than printing nothing, consdier this as adding a partial implemenation in the place of a stub. GdiAlphaBlend is not supported by printers, that's a matter of the fact, using StretchBlt for now is better than doing nothing and even not printing a FIXME or returning an error to an application. Feel free to implement it differently, until that my implementation is suffice for many applications.
Printing something is worse than printing nothing when it's a giant black box that happens to contain the thing that was supposed to draw, and that will start happening if you make this change. And then I won't know how to fix it.
Vincent Povirk madewokherd@gmail.com wrote:
I don't understand your objection, nothing prevents you from improving my patch. Printing something is still better than printing nothing, consdier this as adding a partial implemenation in the place of a stub. GdiAlphaBlend is not supported by printers, that's a matter of the fact, using StretchBlt for now is better than doing nothing and even not printing a FIXME or returning an error to an application. Feel free to implement it differently, until that my implementation is suffice for many applications.
Printing something is worse than printing nothing when it's a giant black box that happens to contain the thing that was supposed to draw, and that will start happening if you make this change. And then I won't know how to fix it.
Where do you see a black box? Isn't that just a speculation? I'll repeat: I tested this patch, and it makes wide range of images print instead of doing nothing. Having partial implementation is always better than having nothing. Try for instance object to adding a stub or partial fix to some other area of Wine code. You can't object to something if you really didn't event test it, but just briefly looked at it and just think it's wrong.