Wrong alpha values with Graphics::fillPath()


#1

Hello,

I think there is an error with Graphics::fillPath(.).
When I create a sub path with Path::addRectangle(.) which has the same size as the image I am drawing to, the last pixel in every row has a wrong alpha value.
The following code reproduces the problem:

int w = 96, h = 48;
Image img(Image::ARGB, w, h, true);
{
	Graphics g(img);
	g.setColour(Colour::fromRGBA(255,255,255,255));
	Path path;
	path.addRectangle(juce::Rectangle<int>(0,0,w,h));
	g.fillPath(path);
}

// Debug:
Image::BitmapData data(img, Image::BitmapData::readOnly);
for(int y = 0; y < data.height; ++y) {
	for(int x = 0; x < data.width; ++x) {
		if(data.getPixelColour(x,y).getAlpha() < 255){
			Logger::outputDebugString("Pixel is not opaque.");
		}
	}
}

When I run this example the last pixel in a row has always an alpha value of 253 (instead of 255). Even if I make the rectangle larger than the image the last pixel is wrong.
Can anybody confirm that this is an error in the juce code or am I doing something silly?

Jan


#2

Just curious, are you on a Mac? If you are, open up digital color meter and mouse over that corner of your rectangle being drawn and take a look at the zoomed in pixels shown in digital color meter. It might be the OS applying a shadow to your window


#3

No, I’m developing on windows at the moment. I don’t think that it is an OS issue since the error is already in the Image data buffer without displaying it. The code in my first post draws into the image and immediately checks the buffer. The error is already in there…


#4

Could just be a rounding error in the software renderer’s rasteriser…


#5

Possible, yes. I can only reproduce the error under windows which probably makes the software renderer even more suspicious.
Do you think this issue can be fixed? If the path/rectangle is smaller than the image this error does not show up. The last pixel of the rect is correct. So this might not be “just a rounding error” since the size of the rect definitely plays a role together with the image size. The actual size of the image is not important. I tried several different sizes and the error occurred every time. It is just important that the rect has the same size as the image.


#6

I’d be very reluctant to dig into the very complex edge table rendering code to try to fix this, which will be invisible to the naked eye in pretty much every case it gets used. The renderer was never designed for perfect, mathematically correct output, it was a compromise to get good performance out of making a CPU do a task it’s not very good at!


#7

Is there anything special that we have to do to make our apps draw using the OpenGL Renderer instead of CPU rendering? I don’t know why i’m thinking that I read that there is a projucer flag we can set to use OpenGL for the rendering engine… :thinking:


#8

Hi Jules, you may want to consider pinning something on the OpenGLRenderer topic. I see the questions like that here very often…


#9

Obviously not the answer I was hoping for. But anyway, thank you for the clear statement. I will try to find a work around for my specific needs.


#10

Have you tried just calling g.fillRect instead of constructing a path? Of giving it a slightly bigger rectangle than the size of the image?


#11

Thank you for your suggestions.
Using g.fillRect() is not an option because I want to use more complex shapes too.
Making the path slightly bigger does not help. Even when the path overlaps the image border the last pixel of the image has the reduced alpha value.

Sorry for cross linking to another post in this forum. But this question


has a big impact on finding a solution for my current problem.
Could you be so kind to give me a short answer on this. It would really help me to find a solution.


#12

Yeah, increasing the bit depth would involve re-engineering the whole rendering stack, the Colour class, etc - it’d be a heck of a lot of work for a feature that I’ve only heard requested once or twice, so unlikely to become a priority for us soon!


#13

Ok, no surprise. Tank you!