# Graphics drawing artifacts

**URL:** <https://forum.juce.com/t/graphics-drawing-artifacts/51845>\
**Category:** General JUCE discussion\
**Created:** [June 17, 2022, 10:05am UTC](https://forum.juce.com/t/graphics-drawing-artifacts/51845 "2022-06-17T10:05:15Z")\
**Posts on this page:** 20\
**Page:** 1

<div class="post-metadata">

**Author:** ![Blueteal](https://sea2.discourse-cdn.com/flex026/user_avatar/forum.juce.com/blueteal/32/5324_2.png) [@Blueteal](https://forum.juce.com/u/Blueteal)\
**Post date:** [June 17, 2022, 10:05am UTC](https://forum.juce.com/t/graphics-drawing-artifacts/51845/1 "2022-06-17T10:05:15Z")

</div>

Hello, I have a weird behaviour using the `Graphics` class that I had not before.

When I use this code :

```auto
class BoxComponent : public Component {
public:
	void paint(Graphics& g) override {
		g.setColour(Colours::red);
		g.fillRect(getLocalBounds());
		g.setColour(Colours::green);
		g.drawRect(getLocalBounds());
	}
};
//Parent resize
void MainComponent::resized() {
	const int boxW = 100;
	const int boxH = 30;
	const auto centre = getLocalBounds().getCentre();
	Rectangle<int> bounds(boxW * _boxs.size(), boxH);
	bounds.setCentre(centre);

	for (const auto& box : _boxs) {
		const auto bBox = bounds.removeFromLeft(boxW);
		box->setBounds(bBox);
	}
}

```

I expect to have this result (well aligned rectangles):

 ![image](https://us1.discourse-cdn.com/flex026/uploads/juce/original/2X/e/ed96cf60bb71d51fb30a11c95ae100714684ee4f.png)

But I actually get this :

 ![image](https://us1.discourse-cdn.com/flex026/uploads/juce/original/2X/2/25b5b1fb4492391c0871f19f4ff63fb2aebf9f38.png)  
The green isn’t the same, but it’s not the point. The point is the drawRect seems to draw with `float` coordinates when I give it `int` ones

---

<div class="post-metadata">

**Author:** ![kamedin](https://sea2.discourse-cdn.com/flex026/user_avatar/forum.juce.com/kamedin/32/11711_2.png) [@kamedin](https://forum.juce.com/u/kamedin)\
**Post date:** [June 17, 2022, 1:12pm UTC](https://forum.juce.com/t/graphics-drawing-artifacts/51845/2 "2022-06-17T13:12:36Z")

</div>

Sorry, I just discovered (because I never use it) that `drawRect` behaves differently from the rest of the stroke functions… I’m not sure what’s happening there, but my guess is that there’s some scaling being applied, so the 1 px stroke ends up not being 1 px in the end. This is still equivalent and faster:

```auto
g.setColour (Colours::green);
g.fillRect (getLocalBounds());
g.setColour (Colours::red);
g.fillRect (getLocalBounds().reduced (1));

```

---

<div class="post-metadata">

**Author:** ![lalala](https://sea2.discourse-cdn.com/flex026/user_avatar/forum.juce.com/lalala/32/8577_2.png) [@lalala](https://forum.juce.com/u/lalala)\
**Post date:** [June 17, 2022, 1:59pm UTC](https://forum.juce.com/t/graphics-drawing-artifacts/51845/3 "2022-06-17T13:59:52Z")

</div>

a post about it:

> [@Rectangles and lineThickness](https://forum.juce.com/t/rectangles-and-linethickness/18517/2):
>
> Hi lalala, Let me summarise your findings in a screenshot (including retina and non-retina displays): Let me first try to explain the difference between roundedRect and drawRect. roundedRect uses a path internally to draw the rounded rect. You can get the same result with the following code: Path p; p.addRectangle (area.getX(), area.getY(), area.getWidth(), area.getHeight()); g.strokePath (p, PathStrokeType(1.f)); If you think about it, the expected result of drawing a path with li…

---

<div class="post-metadata">

**Author:** ![Blueteal](https://sea2.discourse-cdn.com/flex026/user_avatar/forum.juce.com/blueteal/32/5324_2.png) [@Blueteal](https://forum.juce.com/u/Blueteal)\
**Post date:** [June 17, 2022, 2:59pm UTC](https://forum.juce.com/t/graphics-drawing-artifacts/51845/4 "2022-06-17T14:59:06Z")

</div>

Thank you for your answers !

@Kamedin : The use case I show here is a simplification of what I actually need to draw. In my original code I don’t use `drawRect`, I use `drawVerticalLine` at the end of my object, and I have the same issue of incorrect positions. And my line color use transparancy so, it stacks up constraints. So I would like to understand what’s going on here. Especially since that’s a new behaviour. I remember doing similar things with no problems before.

@lalala  
Based on your link, a work around could have been :

```auto
Path p;
p.addRectangle(getLocalBounds());
g.setColour(Colours::red);
g.fillPath(p);
g.setColour(Colours::green);
g.strokePath(p, PathStrokeType(1.0));

```

But I get this :

 ![image](https://us1.discourse-cdn.com/flex026/uploads/juce/original/2X/6/6582183e39ec49924db34910a3f20bede229f173.png)  
It’s a bit better, but there is still some artifacts

---

<div class="post-metadata">

**Author:** ![kamedin](https://sea2.discourse-cdn.com/flex026/user_avatar/forum.juce.com/kamedin/32/11711_2.png) [@kamedin](https://forum.juce.com/u/kamedin)\
**Post date:** [June 17, 2022, 3:07pm UTC](https://forum.juce.com/t/graphics-drawing-artifacts/51845/5 "2022-06-17T15:07:38Z")

</div>

Actually, for `strokePath` what I had written before revising applies: you need to use

```auto
p.addRectangle (getLocalBounds().toFloat().reduced (0.5f));

```

because the coordinates correspond to the middle of the stroke. That’s not the case for `drawRect`: “The lines are drawn inside the given rectangle, and greater line thicknesses extend inwards”. It’s not the case for `drawVerticalLine` either: “The x position is an integer, but the top and bottom of the line can be sub-pixel positions, and these will be anti-aliased if necessary”. So with integer positions and sizes, there shouldn’t be antialiasing. That’s why I suspect there’s scaling involved.

---

<div class="post-metadata">

**Author:** ![Blueteal](https://sea2.discourse-cdn.com/flex026/user_avatar/forum.juce.com/blueteal/32/5324_2.png) [@Blueteal](https://forum.juce.com/u/Blueteal)\
**Post date:** [June 17, 2022, 3:27pm UTC](https://forum.juce.com/t/graphics-drawing-artifacts/51845/6 "2022-06-17T15:27:23Z")

</div>

I tried it but it’s worst 😅

```auto
Path p;
p.addRectangle(getLocalBounds().toFloat().reduced(0.5f));
g.setColour(Colours::red);
g.fillPath(p);
g.setColour(Colours::green);
g.strokePath(p, PathStrokeType(1.0));

```

 ![image](https://us1.discourse-cdn.com/flex026/uploads/juce/original/2X/4/461512b923573ffa170d00eea2a16c4540a6c90f.png)

---

<div class="post-metadata">

**Author:** ![sudara](https://sea2.discourse-cdn.com/flex026/user_avatar/forum.juce.com/sudara/32/8071_2.png) [@sudara](https://forum.juce.com/u/sudara)\
**Post date:** [June 17, 2022, 3:41pm UTC](https://forum.juce.com/t/graphics-drawing-artifacts/51845/7 "2022-06-17T15:41:45Z")

</div>

is getCentre of the main component returning a float point? You might want to have a wrapper container that is an integer mutiple of your boxes.

---

<div class="post-metadata">

**Author:** ![Blueteal](https://sea2.discourse-cdn.com/flex026/user_avatar/forum.juce.com/blueteal/32/5324_2.png) [@Blueteal](https://forum.juce.com/u/Blueteal)\
**Post date:** [June 17, 2022, 3:52pm UTC](https://forum.juce.com/t/graphics-drawing-artifacts/51845/8 "2022-06-17T15:52:20Z")

</div>

Yes `getLocalBounds()` return a `Rectangle<int>`, `getCentre()` returns a `Point<int>` and in the end, `setBounds()` only have one version taking a `Rectangle<int>` so no way to offset a component by a `float` amount

---

<div class="post-metadata">

**Author:** ![kamedin](https://sea2.discourse-cdn.com/flex026/user_avatar/forum.juce.com/kamedin/32/11711_2.png) [@kamedin](https://forum.juce.com/u/kamedin)\
**Post date:** [June 17, 2022, 4:04pm UTC](https://forum.juce.com/t/graphics-drawing-artifacts/51845/9 "2022-06-17T16:04:01Z")

</div>

That’s expected: the reduced path _should_ behave like drawRect. Again, this must be scaling. If it’s Windows, there’s a system-wide scaling which is often active by default in laptops. The interface from JUCE is different for plugins and applications. I don’t know the details for MacOS. One of the links before showed the results for retina and non-retina displays.

---

<div class="post-metadata">

**Author:** ![Blueteal](https://sea2.discourse-cdn.com/flex026/user_avatar/forum.juce.com/blueteal/32/5324_2.png) [@Blueteal](https://forum.juce.com/u/Blueteal)\
**Post date:** [June 17, 2022, 5:09pm UTC](https://forum.juce.com/t/graphics-drawing-artifacts/51845/10 "2022-06-17T17:09:33Z")

</div>

Some tests :

==============================  
Test 1

```auto
g.fillAll(Colours::red);

```

![image](https://us1.discourse-cdn.com/flex026/uploads/juce/original/2X/b/b3c1202f38212d54a5efaa8277f10cd7d46b9538.png)  
Seems normal

==============================  
Test2

```auto
g.setColour(Colours::red);
g.fillRect(getLocalBounds());

```

![image](https://us1.discourse-cdn.com/flex026/uploads/juce/original/2X/9/9b928123078212c6515054417e40954f240b2b86.png)  
Seems normal

==============================  
Test3

```auto
Path p;
p.addRectangle(getLocalBounds().toFloat());
g.setColour(Colours::red);
g.fillPath(p);

```

![image](https://us1.discourse-cdn.com/flex026/uploads/juce/original/2X/5/51d4caf317b78ff0b8e0a8939f62cf3bc9923229.png)  
Not what I expect

==============================  
Test4

```auto
Path p;
p.addRectangle(getLocalBounds().toFloat().reduced(0.5f));
g.setColour(Colours::red);
g.fillPath(p);

```

![image](https://us1.discourse-cdn.com/flex026/uploads/juce/original/2X/c/cec9d3b43364d0e12aec2f3a2d2f5bea4e327247.png)  
From this it seems that a rectangle in a path is already reduced, so it stacks to 1 pixel difference.

==============================  
Test5

```auto
Path p;
p.addRectangle(getLocalBounds().toFloat().expanded(0.5f)); 
g.setColour(Colours::red);
g.fillPath(p);

```

![image](https://us1.discourse-cdn.com/flex026/uploads/juce/original/2X/f/f549fffac2e7b48be39778502e6bf55c53efd9f8.png)  
So if we add 0.5 it display wath I want. At least for the fillPath

==============================  
Test6

```auto
Path p;
p.addRectangle(getLocalBounds().toFloat().expanded(0.5f));
g.setColour(Colours::red);
g.fillPath(p);

Path p2;
p2.addRectangle(getLocalBounds().toFloat());
g.setColour(Colours::green);
g.strokePath(p2, PathStrokeType(1.0));

```

![image](https://us1.discourse-cdn.com/flex026/uploads/juce/original/2X/c/cd37eb735fed08da44f94d462e88293fd8c98230.png)  
This one seems pretty good, but actually if you look at pixel levels there is a dark rectangle. Something I would expect with this formula :

```auto
auto bounds = getLocalBounds();
bounds = bounds.removeFromLeft(1);
bounds = bounds.removeFromRight(1);
g.setColour(Colours::black.withAlpha(0.1f));
g.drawRect(bounds);

```

==============================  
Test7  
I tried

```auto
Path p;
p.addRectangle(getLocalBounds().toFloat().expanded(0.5f)); 
g.setColour(Colours::red);
g.fillPath(p);

Path p2;
p2.addRectangle(getLocalBounds().toFloat().reduced(0.5f));
g.setColour(Colours::green);
g.strokePath(p2, PathStrokeType(1.0));

```

![image](https://us1.discourse-cdn.com/flex026/uploads/juce/original/2X/7/756ebb8d0b73944441321d6feebdc2f945ef309f.png)  
This one has the blurred lines for the outline that teach us that for drawing rect it should have the 0.5 offset, wich is seems normal to me.

==============================  
Conclusion, it seems that `g.drawRect` behaviour is the same as the one using `g.strokePath`. It’s consistant, so it’s fine.  
Filling a rect from a path should expand it from 0.5f to actually fill the full component which seems strange to me.  
But stroking a path does not need the bounds to be expanded wich seems normal, but unfortunately there is artifacts (the dark rectangle that exclude the side of the component)…

---

<div class="post-metadata">

**Author:** ![kamedin](https://sea2.discourse-cdn.com/flex026/user_avatar/forum.juce.com/kamedin/32/11711_2.png) [@kamedin](https://forum.juce.com/u/kamedin)\
**Post date:** [June 17, 2022, 5:59pm UTC](https://forum.juce.com/t/graphics-drawing-artifacts/51845/11 "2022-06-17T17:59:28Z")

</div>

Ok, I tried.

---

<div class="post-metadata">

**Author:** ![Rachmaninov](https://sea2.discourse-cdn.com/flex026/user_avatar/forum.juce.com/rachmaninov/32/5074_2.png) [@Rachmaninov](https://forum.juce.com/u/Rachmaninov)\
**Post date:** [June 18, 2022, 10:42am UTC](https://forum.juce.com/t/graphics-drawing-artifacts/51845/12 "2022-06-18T10:42:49Z")

</div>

Maybe @t0m can explain or give a workaround 😉

---

<div class="post-metadata">

**Author:** ![chkn](https://sea2.discourse-cdn.com/flex026/user_avatar/forum.juce.com/chkn/32/3862_2.png) [@chkn](https://forum.juce.com/u/chkn)\
**Post date:** [June 18, 2022, 12:37pm UTC](https://forum.juce.com/t/graphics-drawing-artifacts/51845/13 "2022-06-18T12:37:43Z")

</div>

The integer-version of fillrect on windows behaves inconsistent to all other functions/platforms.  
I discovered this a long time ago.  
Maybe all integer drawing functions should be simply marked as deprecated.

> [@Subtle drawing bug(?) -\> fillRect (integer version) scaled](https://forum.juce.com/t/subtle-drawing-bug-fillrect-integer-version-scaled/23665):
>
> the integer version of fillRect -\> Graphics::fillRect (int x, int y, int width, int height) aligns the coordinates to pixels, even when its in a context which is scaled. The is inconsistent with other integer drawing functions like drawRect, so im pretty sure this is a bug. (checked on windows) You can see this very easily when a TreeView is scaled, which uses the integer version of fillRect and drawRect to draw the + - box (the right version uses the float version of fillRect) [rightWrong…

---

<div class="post-metadata">

**Author:** ![sudara](https://sea2.discourse-cdn.com/flex026/user_avatar/forum.juce.com/sudara/32/8071_2.png) [@sudara](https://forum.juce.com/u/sudara)\
**Post date:** [June 18, 2022, 12:47pm UTC](https://forum.juce.com/t/graphics-drawing-artifacts/51845/14 "2022-06-18T12:47:42Z")

</div>

Good call, I ran into this on windows and it drove me crazy for a bit until I dove around the forum, found your post and added a `toFloat()` to my drawRect() that I cared about being “logical pixel perfect.”

---

<div class="post-metadata">

**Author:** ![kamedin](https://sea2.discourse-cdn.com/flex026/user_avatar/forum.juce.com/kamedin/32/11711_2.png) [@kamedin](https://forum.juce.com/u/kamedin)\
**Post date:** [June 18, 2022, 1:48pm UTC](https://forum.juce.com/t/graphics-drawing-artifacts/51845/15 "2022-06-18T13:48:34Z")

</div>

Anyway what’s being reported here is different. I don’t know which platform and renderer is the op on, but here on Windows, both on the software and opengl renderers, a 1 px integer drawRect gives the same result as a strokePath with 0.5 px reduction, which is solid, non-antialiased lines, of course _only when there’s no scaling_. What’s being reported here is visible antialiasing in those cases, so unless there’s a bug in another platform’s implementation, this is just scaling doing its normal thing, as would happen on retina displays. From the images I assume a 150% scale or close, as the 2 px logical boundaries appear as 3.

---

<div class="post-metadata">

**Author:** ![Blueteal](https://sea2.discourse-cdn.com/flex026/user_avatar/forum.juce.com/blueteal/32/5324_2.png) [@Blueteal](https://forum.juce.com/u/Blueteal)\
**Post date:** [June 19, 2022, 7:05pm UTC](https://forum.juce.com/t/graphics-drawing-artifacts/51845/16 "2022-06-19T19:05:08Z")

</div>

I’m on Windows, and I used a brand new project to confirm what I noticed on my app. I’m not using OpenGl unless juce is using it by default

---

<div class="post-metadata">

**Author:** ![kamedin](https://sea2.discourse-cdn.com/flex026/user_avatar/forum.juce.com/kamedin/32/11711_2.png) [@kamedin](https://forum.juce.com/u/kamedin)\
**Post date:** [June 19, 2022, 9:38pm UTC](https://forum.juce.com/t/graphics-drawing-artifacts/51845/17 "2022-06-19T21:38:43Z")

</div>

On Windows using the software renderer, I run your code on a 400x400 main component with your `resize` function and these three versions of `BoxComponent::paint`:

```auto
g.setColour (juce::Colours::red);
g.fillRect (getLocalBounds());
g.setColour (juce::Colours::green);
g.drawRect (getLocalBounds());

```

```auto
g.setColour (juce::Colours::red);
g.fillRect (getLocalBounds());
g.setColour (juce::Colours::green);
juce::Path p;
p.addRectangle (getLocalBounds().toFloat().reduced (0.5f));
g.strokePath (p, juce::PathStrokeType (1.0f));

```

```auto
g.setColour (juce::Colours::green);
g.fillRect (getLocalBounds());
g.setColour (juce::Colours::red);
g.fillRect (getLocalBounds().reduced (1));

```

This is what I get in all cases:  
 ![test](https://us1.discourse-cdn.com/flex026/uploads/juce/original/2X/6/6c1c39425e7056f318f163279706f5996bdaf3c7.png)  
You can open that image and see the whole rectangle is 300x30. Your image, otoh, has a 1504x152 rectangle, where each of the apparent pixels is actually 4x4:  
 ![test1](https://us1.discourse-cdn.com/flex026/uploads/juce/original/2X/8/8c1c335176e84802f5706e3fa41b7a06fc2b7508.png)  
Even reducing by 4 leaves us with a 376x38 rectangle, which is (almost) x1.25 with respect to the code. So the image you uploaded has a 125% scale, and then 400% on top of that. I’ve been mentioning scaling since the first answer and you’ve consistently ignored it, so that’s it from me.

---

<div class="post-metadata">

**Author:** ![Blueteal](https://sea2.discourse-cdn.com/flex026/user_avatar/forum.juce.com/blueteal/32/5324_2.png) [@Blueteal](https://forum.juce.com/u/Blueteal)\
**Post date:** [June 20, 2022, 9:09am UTC](https://forum.juce.com/t/graphics-drawing-artifacts/51845/18 "2022-06-20T09:09:35Z")

</div>

I didnt understood what you were talking about mentionning scaling. From the source code I do not apply any scaling (unless there is one from juce I’m not aware of). The only one is when I paste my screenshot in windows paint app to zoom to better see at pixel level.

So with this code :

```auto
g.setColour(Colours::red);
g.fillRect(getLocalBounds());

Path p2;
p2.addRectangle(getLocalBounds().toFloat());
g.setColour(Colours::green);
g.strokePath(p2, PathStrokeType(1.0));

```

A raw screenshot is :

 ![image](https://us1.discourse-cdn.com/flex026/uploads/juce/original/2X/2/210db11cb48bab75b98e5bc9b299b1f39b7f8eec.png)

One on paint, with a pixel level zoom x400 :

 ![image](https://us1.discourse-cdn.com/flex026/uploads/juce/original/2X/f/f8f0772328b48d3d098cf0b547207963bffd8152.png)

And a larger one x800 to make it even more obvious :

 ![image](https://us1.discourse-cdn.com/flex026/uploads/juce/original/2X/4/4bcd1dee07937508cece34e9d4540462e6c2c4f4.png)

The issue is this dark rectangle that should not appear, and the size of the green rectangle seems to overlap the start of the next object since it’s only 1px large instead of 2 when there’s two objects.

I get the same thing using different screenshot applications, or replacing Paint app by Gimp

============================================  
We were talking about drawRect, but there’s artifacts to draw a line too

```auto
g.setColour(Colours::red);
g.fillRect(getLocalBounds());

g.setColour(Colours::green);
g.drawVerticalLine(getWidth()-1, 0, getHeight()); //without -1 the line does not appear at all

```

I get this (I took a screenshot, then paste it onto paint, then zoom x800 to confirm pixel level):

 ![image](https://us1.discourse-cdn.com/flex026/uploads/juce/original/2X/8/8a7f72d713e1c440395445602fa8f8e97b78226d.png)

If I replace the drawVerticalLine by a path :

```auto
Path p2;
p2.addRectangle(getLocalBounds().toFloat().removeFromRight(1));
g.setColour(Colours::green);
g.strokePath(p2, PathStrokeType(1.0));

```

With a 1px large rectangle instead I get a 2 pixel wide drawing + a dark line (??)

 ![image](https://us1.discourse-cdn.com/flex026/uploads/juce/original/2X/4/401fc8c44d60c98a680b55b76bb58b2b32a043c7.png)

I tried the 0.5 pixel fix we discussed previously :

```auto
Path p2;
p2.addRectangle(getLocalBounds().toFloat().removeFromRight(0.5));
g.setColour(Colours::green);
g.strokePath(p2, PathStrokeType(1.0));

```

But I still have a 2 line rectangle. It drives me crazy 😅

 ![image](https://us1.discourse-cdn.com/flex026/uploads/juce/original/2X/b/bbcac6502aeeffa068b073f4ccbdc026ca436e94.png)

---

<div class="post-metadata">

**Author:** ![PeterRoos](https://avatars.discourse-cdn.com/v4/letter/p/7ab992/32.png) [@PeterRoos](https://forum.juce.com/u/PeterRoos)\
**Post date:** [June 20, 2022, 9:27am UTC](https://forum.juce.com/t/graphics-drawing-artifacts/51845/19 "2022-06-20T09:27:10Z")

</div>

Just make it a habit to force your pixels coordinates either on (0.0f) or between (0.5f) pixels, depending on what graphic methods you use, before you call them. Simply make sure your code bypasses these “issues”.

You can safely assume that the mapping by those methods will never be changed, given all the existing Juce-based plugins using them.

Be pragmatic - some things are not worth the effort trying to understand them 🙃

---

<div class="post-metadata">

**Author:** ![Blueteal](https://sea2.discourse-cdn.com/flex026/user_avatar/forum.juce.com/blueteal/32/5324_2.png) [@Blueteal](https://forum.juce.com/u/Blueteal)\
**Post date:** [June 20, 2022, 10:12am UTC](https://forum.juce.com/t/graphics-drawing-artifacts/51845/20 "2022-06-20T10:12:06Z")

</div>

I understand that, so what would you do exactly ? Because none of the try was artifacts free

[Next page](https://forum.juce.com/t/graphics-drawing-artifacts/51845.md?page=2)
