I saw some issues from 2016 talking about 125% desktop scaling on Windows 10 (which is very common) for trying to draw a single pixel line. I have been dealing with this issue with several UIs which are not very line dependent, but sometimes you really need a one pixel line for example for drawing a grid. What is the suggested way to draw a single pixel line using JUCE in 2019? Is there a way to draw a single line snapped to the hardware grid?
I donât know if that helps with the scaling issues, but have you tried Graphics::drawHorizontalLine() and Graphics::drawVerticalLine()?
See: https://docs.juce.com/master/classGraphics.html#a6625d72cb899b3d213c3bb7a91409ff2
This one just fills a float rectangle internally, I have tried this, I have even tried to put all lines into paths and tried to paint them like that (this resulted in different unexpected behaviour but still wrong). Antialiasing is not what im looking for basically I want to paint straight to the physical pixel.
I might be wrong, but I think the only way to achieve that is to write the graphics driver yourself.
It is 2019, there are so many different resolutions and pixel sizes, devices from 10cm to 10m. There will always be an abstraction layer from logical to physical pixels, unless it is a bespoke system.
I second that request. Not being able to draw a 1px line if the Windows user is using 125% is really weird. It always looks blurry and ugly and as plugin developer you donât care about 10m or 10cm screens.
Unfortunately, as an Operating System vendor, Microsoft doesnât care about (some) plugin developers not caring about 10m or 10cm screens.
So how come that VisualStudio doesnât look blurry in 125%?
No idea, I avoid it as much as possible, and use Azure to build my Windows versions
You should try it, itâs awesomely unblurry
Jokeâs aside, would it be possible to add a API call Graphics::draw1PxLine (along with his friend Graphics::draw1PxRect) that magically takes all scale factors into account and creates a float rectangle that is guaranteed to resolve to exactly one pixel on the screen?)
I sthis 1px logical or physical youâre after?
Well a âlogicalâ pixel brought us this topic, so I guess a physical one
Just a quick comparison between 100% and 125% (this example uses a AffineTransform within JUCE, but I can imagine, itâs the same for the global scale factor in Windows).
100% with a direct pixel to pixel correlation looks like this:
as opposed to 125%:
I hope the browser doesnât rescale the images or this post will look like a crazy-person rant. If it doesnât, you can clearly see the 100% view looks crisp and sharp and the 125% view looks like the familiy photos my father converted using a shareware image converter from 1995
Now I can live with the fact that the fonts are a bit more blurry (not sure why this is the case though, the vertical text was imported as .SVG so it should be 100% sharp). But the lines and especially the note rectangles look pretty cheap.
EDIT: Oh it does in fact rescale the images. You have to drag them to another browser tab to view them in their original resolution.
I can see the annoyance (I share it) but with display pixel densities going the way they are (and complexities such as sub-pixel rendering) a 1px physical line may not really be what you want (as it will be very thin on a 400ppi+ display).
It seems to me what this thread is asking is a way to draw a non-antialised line with a given minimum thickness which Iâm not even sure is possible these daysâŠ
Its more about having all the lines look the same independent of where they are positioned.
And this is precisely the thing that goes away on HiDPI displays as no matter where you draw the lines, thereâs enough pixels that the edge aliasing is small in comparison (unless you really do draw a 1px physical line and youâre back to square one).
And this is precisely the thing that goes away on HiDPI displays.
Yes, but it doesnât go away for the majority of your user base which has to cope with blurry user interfaces - or use a ridiculous small 100% version, which makes the whole âmodern UIs can be scaled to match the screen size perfectlyâ-paradigm kind of pointless.
It seems to me what this thread is asking is a way to draw a non-antialised line with a given minimum thickness which Iâm not even sure is possible these daysâŠ
Exactly. But since we can query which which CPU instructions are available on the current system (along with pretty much every other system property), I am pretty sure some smart person has thought about a way to get the actual logical-pixel to phyical pixel ratio for the current display. From then on, converting the Rectangle<float>
that draws the blurred line into a version that doesnât blur shouldnât require a degree in rocket science.
I think weâre talking at cross purposes a bit. What Iâm trying to get at is that sure, for the most common systems right now this is possible but itâs a constantly shifting ecosystem and I can imagine a time when all this physical hardware stuff is completely abstracted away from software APIs.
The other thing Iâve tried to clarify is what is actually being requested here as itâs certainly not as simple as âa 1px lineâ.
Iâm also advocating that itâs really a free function helper method that should live outside of the standard JUCE drawing classes as it will likely need to know more than just the Graphics
context such as the Display
itâs currently on.
Does Displays::logicalToPhysical
do what you need if you simply pass it a 1px rect?
Displays::logicalToPhysical
. Nice one, exactly what I am looking for. Now I just need to traverse the component hierarchy and add all scale factors that are applied.
I still think that it should be part of the Graphics object, passing the current component you draw on as reference:
Graphics::draw1pxHorizontalLine(int y, int startX, int endX, Component* componentToDrawOn);
If you bury it in a helper tool class, people will not stumble upon it when browsing the Graphics API and keep on drawing blurry lines without knowing better.
Correct me if Iâm wrong, but web-browsers donât provide any mechanism for drawing physical-pixel-aligned graphics, right? How come the entire internet seems to be completely fine with the idea of providing carefully-designed graphics that run on every imaginable size and shape of screen⊠but plugin GUI people are constantly banging on about this as if itâs some kind of essential feature?
If you really, really want this, you can use LowLevelGraphicsContext::getPhysicalPixelScaleFactor()
but be ready to deal with all kinds of stupid edge-cases as devices continue to move in the direction of simply not wanting people to get access to the pixels.
Another âplugin GUI peopleâ here: Weâre perfectly happy with the scaling and what it entails. Itâs unavoidable. The user decides what resolution he wants his screen/apps to be in, not the developer. A 1px line is almost invisible on a 400 DPI screen.
If you really enforce all drawing primitives start and end on physical pixel edges, then your scaling will be all screwed up. Some events will be one pixel smaller than others, lines will be too thin etc.
Instead of fighting logical pixels, you should embrace them and design your artwork/layout to accommodate ANY resolution.
@jules is 100% right. The browsers scale it all and it looks really good.