PATCH cairo-www: Simpler explanation for how to get sharp, single-pixel-wide lines

Submitted by Lawrence D'Oliveiro on May 17, 2017, 5:02 a.m.

Details

Message ID 20170517170232.1571bf0d@theon.geek-central.gen.nz
State New
Series "PATCH cairo-www: Simpler explanation for how to get sharp, single-pixel-wide lines"
Headers show

Commit Message

Lawrence D'Oliveiro May 17, 2017, 5:02 a.m.

Patch hide | download patch | download mbox

From d6023c23bfffa990d0a7c05fdeef4bac60ad7606 Mon Sep 17 00:00:00 2001
From: Lawrence D'Oliveiro <ldo@geek-central.gen.nz>
Date: Sun, 24 Apr 2016 22:08:39 +0000
Subject: [PATCH 2/2] Simpler explanation for how to get sharp,
 single-pixel-wide lines.

---
 src/FAQ.mdwn | 73 +++++++++++++-----------------------------------------------
 1 file changed, 15 insertions(+), 58 deletions(-)

diff --git a/src/FAQ.mdwn b/src/FAQ.mdwn
index 0d86520..7673ece 100644
--- a/src/FAQ.mdwn
+++ b/src/FAQ.mdwn
@@ -183,65 +183,22 @@  Answer: This problem usually shows up with code like the following,
 The user expects 10 pixels in one row to be affected, but instead the
 line is "smeared" over 20 pixels in two rows.
 
-The reason this happens is easy to explain to someone who believes
-pixels are little squares. By default, integer coordinates map to the
-intersections of the pixel squares. So a width-1 horizontal/vertical
-line is centered on the boundary between pixel rows and extends half
-way into the pixels on either side.
-
-When some people hear pixels described as little squares it sets their
-teeth on edge. For them we have this alternate explanation. By
-default, integer coordinates map to points half way between sample
-point locations. So a width-1 horizontal/vertical will be centered
-between two rows of pixel sample points and will contribute equally to
-the pixels on either side, (assuming a symmetric filter which is
-always the case when synthesizing images in cairo).
-
-Either way, you can avoid the issue by using an even-integer line
-width, (note that the default line width in cairo is 2.0). A line
-drawn this way will still affect just as many pixels, but they will be
-affected at full intensity.
-
-Otherwise, if you really want to light up a single row of pixels at
-full intensity, you can do that by adjusting the endpoints by 0.5 in
-the appropriate direction. For example, by changing the above code to:
-
-	cairo_move_to (cr, 10, 10.5);
-	cairo_line_to (cr, 20, 10.5);
-	cairo_set_line_width (cr, 1);
-	cairo_stroke (cr);
+The answer is simple: turn off antialiasing, by preceding the above
+sequence with a call like this:
+
+    cairo_set_antialias(cr, CAIRO_ANTIALIAS_NONE);
+
+Now you will get nice, sharp lines for both stroking and filling,
+with all drawing automatically being snapped to exact device pixels,
+instead of being smeared across adjacent pixels to emulate in-between
+positions.
+
+The drawback is that, if your lines are not exactly vertical or horizontal,
+you will get horrible “jaggies”. This is why antialiasing is on
+by default, and should be left that way for most text and shape drawing.
+To restore the default, end your aliased drawing sequence with
 
-The reason that cairo does it this way is so that fills align nicely,
-at the cost that some strokes do not. It is not possible to set up
-sample locations in a way so that both fills and strokes with integer
-coordinates work nicely, so one had to be preferred over the
-other. One argument in favor of preferring fills is that all fills
-with integer coordinates align nicely this way. The best that can be
-done with strokes is to make all even-integer-width strokes align
-nicely (as they do in cairo) or to make odd-integer-width strokes
-align (which would then break the fill alignment).
-
-It is important to note that all of this discussion assumes the
-default transformation matrix. Under other transformations, the
-relationship between user-space coordinates and device-space pixels
-may be quite different. Guaranteeing alignment with the device-pixel
-grid, "snapping", in such cases is still possible and is often worth
-doing (except in situations such as animated zooms where the snapping
-would lead to undesired jitter in the result). The trick to snapping
-is simply to perform rounding in device-space so that rectilinear
-geometry lands at integer position in the device-space grid. So, the
-process might look something like:
-
-	cairo_user_to_device (cr, &x, &y);
-	do_rounding (&x, &y);
-	cairo_device_to_user (cr, &x, &y);
-
-and then using the resulting x and y values to construct a path. Note
-that the `do_rounding` function will likely need to be different
-depending on how the coordinates are being used. For example, for a
-fill or a stroke with an even-integer line width, this function might
-round to the nearest integer. For a stroke with an odd-integer line
-width, it might round to the nearest half integer.
+    cairo_set_antialias(cr, CAIRO_ANTIALIAS_DEFAULT);
 
 <h2 id="using_pango">How do I use pango instead of cairo's "toy" text
 API?</h2>
-- 
2.8.0.rc3


Comments

Guillermo Rodriguez May 17, 2017, 8:47 a.m.
This simpler explanation fails to explain why this "problem" occurs,
and what is the rationale behind the current design.

It also fails to discuss alternatives such as adjusting endpoints by
0.5, which allows you to get sharp, single-pixel-wide lines without
turning off antialiasing, which in many cases is undesirable.

Guillermo

2017-05-17 7:02 GMT+02:00 Lawrence D'Oliveiro <ldo@geek-central.gen.nz>:
>
> --
> cairo mailing list
> cairo@cairographics.org
> https://lists.cairographics.org/mailman/listinfo/cairo
Lawrence D'Oliveiro May 17, 2017, 9:24 a.m.
On Wed, 17 May 2017 10:47:46 +0200, Guillermo Rodriguez wrote:

> This simpler explanation fails to explain why this "problem"
> occurs ...

It occurs because of anti-aliasing.

> ... and what is the rationale behind the current design.

You want me to include a rationale for anti-aliasing?

> It also fails to discuss alternatives such as adjusting endpoints by
> 0.5, which allows you to get sharp, single-pixel-wide lines without
> turning off antialiasing, which in many cases is undesirable.

Let me refresh your memory about the question in the FAQ:

    Question: Whenever I try drawing with a line-width of 1.0, my
    horizontal/vertical lines come out fat and blurry (eg. 2 pixels
    wide and half-intensity). What's wrong?

Note that it only discusses “horizontal/vertical” lines. This is the
specific situation where turning off antialiasing is the simplest
solution.
Stefan Salewski May 17, 2017, 9:49 a.m.
On Wed, 2017-05-17 at 21:24 +1200, Lawrence D'Oliveiro wrote:
> Note that it only discusses “horizontal/vertical” lines. This is the
> specific situation where turning off antialiasing is the simplest
> solution.

Maybe the simplest, but not a good one.

I had that problem in my application

http://ssalewski.de/PetEd.html.en

I needed/wanted sharp lines. Turning off antialiasing gave not the
desired results, so I had to follow indeed the tutorial. I was not too
happy about that, because the app was coded in Ruby, and that rounding
to exact positions costs some CPU cycles. I can not remember details, I
think I asked at cairo mailing list that time. At least that proposed
solution worked fine. But I would like to see some direct cairo support
for that, maybe a drawing mode which does that rounding internally. I
think I was thinking about to make a C routine for Ruby for that, but
never did it. Well, now we have faster languages than Ruby or Python
available, like Nim, Rust and many more, so it is not a big problem any
more. And with current HiDPI monitors we may not need antialiasing at
all any more. I have recently turned of antialiasing for font rendering
 on my Gnome desctop -- was not bad, I liked the sharper fonts.
Unfortunately it worked not that well for some font sizes and some web
pages, so I turned on aliasing again for now.
Guillermo Rodriguez May 17, 2017, 10:29 a.m.
2017-05-17 11:24 GMT+02:00 Lawrence D'Oliveiro <ldo@geek-central.gen.nz>:
> On Wed, 17 May 2017 10:47:46 +0200, Guillermo Rodriguez wrote:
>
>> This simpler explanation fails to explain why this "problem"
>> occurs ...
>
> It occurs because of anti-aliasing.

No. It occurs because integer coordinates map to points half way
between sample point locations, as the original text adequately
explains.

>
>> ... and what is the rationale behind the current design.
>
> You want me to include a rationale for anti-aliasing?

I don't want you to do anything. The original text explains perfectly
why the design is like it is ("[...] so that fills align nicely, at
the cost that some strokes do not").

>
>> It also fails to discuss alternatives such as adjusting endpoints by
>> 0.5, which allows you to get sharp, single-pixel-wide lines without
>> turning off antialiasing, which in many cases is undesirable.
>
> Let me refresh your memory about the question in the FAQ:

Not needed.

>
>     Question: Whenever I try drawing with a line-width of 1.0, my
>     horizontal/vertical lines come out fat and blurry (eg. 2 pixels
>     wide and half-intensity). What's wrong?
>
> Note that it only discusses “horizontal/vertical” lines. This is the
> specific situation where turning off antialiasing is the simplest
> solution.

It may be the simplest, but it is not the only one, and in many cases
not the best one either. The solution proposed in the original text
also solves the problem without the need to turn off antialiasing.

Guillermo
Lawrence D'Oliveiro May 17, 2017, 10:50 a.m.
On Wed, 17 May 2017 12:29:15 +0200, Guillermo Rodriguez wrote:

> It occurs because integer coordinates map to points half way
> between sample point locations ...

That’s a common misconception. Sampling doesn’t work that way. Whether
you label the sample points as integer “n” or “n + ½”, the problem still
happens.

Cairo’s stroked and filled shapes have infinitely sharp edges. That
means they have an infinite spatial frequency spectrum, well beyond any
finite Nyquist limit. Such shapes are impossible to represent, in
general, on a finite sampled grid. Anti-aliasing removes the
frequencies beyond this limit; this avoids the sampling artifacts at the
cost of introducing blurriness into the edges of the shape.

It just so happens the blurriness becomes less noticeable for exactly
horizontal or vertical edges if you place these edges between rows or
columns of pixels. But these are also the situations where the aliasing
artifacts are minimized.

And if you turn off anti-aliasing, the precise placement of the edge no
longer becomes critical--anywhere between pixels will do. In
particular, the whole n-versus-n-plus-½ nonsense becomes irrelevant.

Anti-aliasing is not magic, it’s just a tool, to be used when
appropriate and set aside when not. Don’t be superstitious about it.
Lawrence D'Oliveiro May 17, 2017, 10:52 a.m.
On Wed, 17 May 2017 11:49:11 +0200, Stefan Salewski wrote:

> I needed/wanted sharp lines. Turning off antialiasing gave not the
> desired results, so I had to follow indeed the tutorial.

I’d be curious to know exactly what you were trying to do.
Stefan Salewski May 17, 2017, 11:06 a.m.
On Wed, 2017-05-17 at 22:52 +1200, Lawrence D'Oliveiro wrote:
> On Wed, 17 May 2017 11:49:11 +0200, Stefan Salewski wrote:
> 
> > I needed/wanted sharp lines. Turning off antialiasing gave not the
> > desired results, so I had to follow indeed the tutorial.
> 
> I’d be curious to know exactly what you were trying to do.

Unfortunately I can not remember details...

Whenever I should work again on that tool I will tell you.

One topic may be fading out very thin lines...
Guillermo Rodriguez May 17, 2017, 11:27 a.m.
2017-05-17 12:50 GMT+02:00 Lawrence D'Oliveiro <ldo@geek-central.gen.nz>:
> On Wed, 17 May 2017 12:29:15 +0200, Guillermo Rodriguez wrote:
>
>> It occurs because integer coordinates map to points half way
>> between sample point locations ...
>
> That’s a common misconception.

It's taken straight from the current Cairo FAQ.

Again: A common use case is that you want to have antialiasing in
general BUT at the same time be able to draw 1 pixel wide vertical or
horizontal lines that don't look "blurry". The current text describes
an approach which achieves exactly that by adjusting endpoints of
horizontal / vertical lines by 0.5 in the appropriate direction. That
gets you perfect sharp, single-pixel-wide vertical and horizontal
lines without the need to turn off antialiasing. Your "simpler
explanation" proposal misses that completely.

Guillermo
Olaf Schmidt May 17, 2017, 7:28 p.m.
Am 17.05.2017 um 13:27 schrieb Guillermo Rodriguez:

>>> It occurs because integer coordinates map to points half way
>>> between sample point locations ...
>>
>> That’s a common misconception.
> 
> It's taken straight from the current Cairo FAQ.
> 
> Again: A common use case is that you want to have antialiasing in
> general BUT at the same time be able to draw 1 pixel wide vertical or
> horizontal lines that don't look "blurry". The current text describes
> an approach which achieves exactly that by adjusting endpoints of
> horizontal / vertical lines by 0.5 in the appropriate direction. That
> gets you perfect sharp, single-pixel-wide vertical and horizontal
> lines without the need to turn off antialiasing. Your "simpler
> explanation" proposal misses that completely.

To "underline" the above (which is the suggestion I've followed in
a WidgetEngine) - here's a ScreenShot which shows both cases:

http://vbRichClient.com/Downloads/WidgetRenderQuality.png

- btnHello1 following the more "general purpose" suggestion above

- btnHello2 following the suggestion of Lawrence (which has its
   place, but I'd think it should only be mentioned "in addition":
  (in case one wants to render straight horizontal or vertical lines only)


For those who want to run the little Mini-App which produced the
ScreenShot, below is the *.vbs-Code (sorry for the "Win-only" example).

The AntiAliasing-switchery is done in the Paint-Event of the little
cwSimpleButton-Class at the bottom...

Set New_c = CreateObject("vbRichClient5.cConstructor") 'Main-Constructor

Set Cairo = New_c.Cairo 'ensure the global Cairo-Namespace-Entrypoint
	Set Form=Cairo.WidgetForms.Create(2, "Widget-Renderquality", , 320, 240)

	WScript.ConnectObject Form, "Form_" '<- EventSink-Prefix and -Binding 
the VBScript-way
	Form.Show
Cairo.WidgetForms.EnterMessageLoop 'here we enter the message-pump of 
our little Application

Sub Form_Load()
     Form.Widgets.Add New cwSimpleButton,"btnHello1", 10, 10, 100, 25 
'normal AntiAliasing
     Form.Widgets.Add(New cwSimpleButton,"btnHello2", 10, 40, 100, 
25).AntiAliasOff=True
End Sub

'this Event travels through all the Parent-Widgets of a nested 
Widget-Hierarchy up to the Form
Sub Form_BubblingEvent(Sender, EventName, P1, P2, P3, P4, P5, P6, P7)
   Select Case EventName
     Case "W_Paint": Sender.Paint P1, P4, P5 're-route to the Class
     Case "W_Click": If TypeName(Sender) = "cwSimpleButton" Then MsgBox 
Sender.Widget.Key
     Case "W_MouseEnter", "W_MouseLeave", "W_MouseDown", "W_MouseUp": 
Sender.Widget.Refresh
   End Select
End Sub

'just to ensure the missing IIf()-Function in the VBScript-Context
Function IIf(Cond, ResultIfTrue, ResultIfFalse)
	If Cond Then IIf = ResultIfTrue Else IIf = ResultIfFalse
End Function

'a cairo-Widget-Class (for a simple ownerdrawn Command-Button)
Class cwSimpleButton
     Private W  'define and instantiate the internal W-WidgetBase
     Private Sub Class_Initialize(): Set W = Cairo.WidgetBase: End Sub

     'below the two Properties, any cwClass needs to implement
     Property Get Widget():  Set Widget  = W:         End Property
     Property Get Widgets(): Set Widgets = W.Widgets: End Property

     Public AntiAliasOff  'define a Property to allow DrawMode-switching 
from outside

     Sub Paint(ByVal CC, ByVal dx, ByVal dy)
        Dim State
            State = IIf(W.Root.MouseKeyDown And W.MouseOver, 1, 0) Or 
IIf(W.MouseOver, 2, 0)

        If AntiAliasOff Then CC.AntiAlias = 1 'CAIRO_ANTIALIAS_NONE

        Cairo.Theme.DrawTo (CC), (W), 0, State, 0, 0, dx, dy, 2 'draw a 
themed Button-Face first

        CC.SetSourceColor W.BorderColor 'and now the surrounding Border
           CC.SetLineWidth 2
           CC.RoundedRect 0, 0, dx, dy, 4, True '<- True to take care of 
"sharp coord-placement"
        CC.Stroke

        W.SelectFontSettingsInto (CC) 'select all current 
W.Font*-Properties into the CairoContext
        CC.DrawText 1, 1, dx, dy, W.Key, , 2, 2, 1 'a Caption (using the 
W.Key to simplify things)
     End Sub
End Class


HTH

Olaf
Lawrence D'Oliveiro May 18, 2017, 12:45 a.m.
On Wed, 17 May 2017 21:28:22 +0200, Olaf Schmidt wrote:

> - btnHello2 following the suggestion of Lawrence (which has its
>    place, but I'd think it should only be mentioned "in addition":
>   (in case one wants to render straight horizontal or vertical lines
> only)

Which is what the question in the FAQ was asking.

I hope you are not trying to fault my answer for not being a good
answer to a different question from the one being asked...
Lawrence D'Oliveiro May 18, 2017, 4:46 a.m.
On Wed, 17 May 2017 13:27:10 +0200, Guillermo Rodriguez wrote:

> Again: A common use case is that you want to have antialiasing in
> general BUT at the same time be able to draw 1 pixel wide vertical or
> horizontal lines that don't look "blurry".

That’s not clear to me at all, and it’s certainly not what the question
is asking.

To me, a more common use case would be wanting to draw a whole wide
range of filled/stroked shapes that don’t look “blurry”.

Perhaps the question needs to be replaced with one that you think it is
asking, rather than what it actually says.
Guillermo Rodriguez May 18, 2017, 7:09 a.m.
2017-05-18 6:46 GMT+02:00 Lawrence D'Oliveiro <ldo@geek-central.gen.nz>:
> On Wed, 17 May 2017 13:27:10 +0200, Guillermo Rodriguez wrote:
>
>> Again: A common use case is that you want to have antialiasing in
>> general BUT at the same time be able to draw 1 pixel wide vertical or
>> horizontal lines that don't look "blurry".
>
> That’s not clear to me at all, and it’s certainly not what the question
> is asking.

That's your interpretation. Anyway I don't want to convince you. I
only wanted to add my two cents to the list: In my opinion the current
answer is very useful, and the alternative you propose is not useful
except for very limited use cases.

Guillermo
Lawrence D'Oliveiro May 18, 2017, 7:24 a.m.
On Thu, 18 May 2017 09:08:16 +0200, Guillermo Rodriguez Garcia wrote:

> ... but
> unless you are writing an application that ONLY draws vertical and
> horizontal straight lines (which doesn't seem to be very common) it is
> pretty obvious that whoever has this problem would like to have a
> solution that does not affect everything else.

Which I addressed in my answer--please read it again.
Guillermo Rodriguez May 18, 2017, 9:24 a.m.
2017-05-18 9:08 GMT+02:00 Guillermo Rodriguez Garcia
<guille.rodriguez@gmail.com>:
> 2017-05-18 2:45 GMT+02:00 Lawrence D'Oliveiro <ldo@geek-central.gen.nz>:
>> On Wed, 17 May 2017 21:28:22 +0200, Olaf Schmidt wrote:
>>
>>> - btnHello2 following the suggestion of Lawrence (which has its
>>>    place, but I'd think it should only be mentioned "in addition":
>>>   (in case one wants to render straight horizontal or vertical lines
>>> only)
>>
>> Which is what the question in the FAQ was asking.
>
> Except for the "only" bit.
>
> The question in the FAQ talks about horizontal and vertical lines, but
> unless you are writing an application that ONLY draws vertical and
> horizontal straight lines (which doesn't seem to be very common) it is
> pretty obvious that whoever has this problem would like to have a
> solution that does not affect everything else.

BTW here's an excerpt from a post by Carl Worth from this same mailing list [1]:

===
The answer here is not to "turn off antialiasing", but instead to adjust
your geometry as needed to align with the device pixels.
===

 [1]: https://lists.cairographics.org/archives/cairo/2004-October/002039.html

Guillermo
Lawrence D'Oliveiro May 18, 2017, 10:15 a.m.
On Thu, 18 May 2017 11:24:05 +0200, Guillermo Rodriguez wrote:

> BTW here's an excerpt from a post by Carl Worth from this same
> mailing list [1]:
> 
> ===
> The answer here is not to "turn off antialiasing", but instead to
> adjust your geometry as needed to align with the device pixels.
> ===
> 
>  [1]:
> https://lists.cairographics.org/archives/cairo/2004-October/002039.html

He seems to be under the impression that the OP was going to turn off
antialiasing for the entire graphic, whereas it is only the horizontal
and vertical lines that need this.
Lawrence D'Oliveiro May 18, 2017, 10:17 a.m.
On Thu, 18 May 2017 11:03:28 +0200, Guillermo Rodriguez Garcia wrote:

> 2017-05-18 9:24 GMT+02:00 Lawrence D'Oliveiro:
>
>> On Thu, 18 May 2017 09:08:16 +0200, Guillermo Rodriguez Garcia
>> wrote: 
>
>>> ... but unless you are writing an application that ONLY draws
>>> vertical and horizontal straight lines (which doesn't seem to be
>>> very common) it is pretty obvious that whoever has this problem
>>> would like to have a solution that does not affect everything
>>> else.  
>>
>> Which I addressed in my answer--please read it again.  
> 
> Nothing to add on my side.

In which case, let me quote myself:

    The drawback is that, if your lines are not exactly vertical or
    horizontal, you will get horrible “jaggies”. This is why
    antialiasing is on by default, and should be left that way for most
    text and shape drawing. To restore the default, end your aliased
    drawing sequence with

        cairo_set_antialias(cr, CAIRO_ANTIALIAS_DEFAULT);

So the question becomes: do you actually have a point that I haven’t
already addressed in my answer?
Guillermo Rodriguez May 18, 2017, 10:25 a.m.
2017-05-18 12:17 GMT+02:00 Lawrence D'Oliveiro <ldo@geek-central.gen.nz>:
> On Thu, 18 May 2017 11:03:28 +0200, Guillermo Rodriguez Garcia wrote:
>
>> 2017-05-18 9:24 GMT+02:00 Lawrence D'Oliveiro:
>>
>>> On Thu, 18 May 2017 09:08:16 +0200, Guillermo Rodriguez Garcia
>>> wrote:
>>
>>>> ... but unless you are writing an application that ONLY draws
>>>> vertical and horizontal straight lines (which doesn't seem to be
>>>> very common) it is pretty obvious that whoever has this problem
>>>> would like to have a solution that does not affect everything
>>>> else.
>>>
>>> Which I addressed in my answer--please read it again.
>>
>> Nothing to add on my side.
>
> In which case, let me quote myself:
>
>     The drawback is that, if your lines are not exactly vertical or
>     horizontal, you will get horrible “jaggies”. This is why
>     antialiasing is on by default, and should be left that way for most
>     text and shape drawing. To restore the default, end your aliased
>     drawing sequence with
>
>         cairo_set_antialias(cr, CAIRO_ANTIALIAS_DEFAULT);
>
> So the question becomes: do you actually have a point that I haven’t
> already addressed in my answer?

Sure. It's just that I am tired of repeating it over and over. Here is
a summary:

"In my opinion, the current answer is much more useful than your
proposed alternative"

As I said you don't need to convince me. I just wanted to state my
opinion on the list.

Guillermo
Lawrence D'Oliveiro May 18, 2017, 12:04 p.m.
On Thu, 18 May 2017 11:24:05 +0200, Guillermo Rodriguez wrote:

> https://lists.cairographics.org/archives/cairo/2004-October/002039.html

Worth (so to speak) also pointing out this bit:

    As I talk about in the comment in the sample code, it may still be
    beneficial to add some automatic snapping to cairo. It would simply
    make it easier to achieve effects such as this---and in particular,
    to achieve these effects regardless of what scaling the current
    transformation might be performing.

Was such an “automatic snapping” API ever added to Cairo? One that is
independent of the current transformation?

Trick question: in fact, it already existed even as he spoke.

It’s precisely the effect that *aliasing* achieves.
Bill Spitzak May 18, 2017, 5:47 p.m.
On Thu, May 18, 2017 at 5:04 AM, Lawrence D'Oliveiro
<ldo@geek-central.gen.nz> wrote:
> On Thu, 18 May 2017 11:24:05 +0200, Guillermo Rodriguez wrote:
>
>> https://lists.cairographics.org/archives/cairo/2004-October/002039.html
>
> Worth (so to speak) also pointing out this bit:
>
>     As I talk about in the comment in the sample code, it may still be
>     beneficial to add some automatic snapping to cairo. It would simply
>     make it easier to achieve effects such as this---and in particular,
>     to achieve these effects regardless of what scaling the current
>     transformation might be performing.
>
> Was such an “automatic snapping” API ever added to Cairo? One that is
> independent of the current transformation?

No.

> Trick question: in fact, it already existed even as he spoke.

No it does not.

> It’s precisely the effect that *aliasing* achieves.

No it is not. A diagonal line draws with aliasing artifacts when
antialiasing is off. A hinting scheme would not do this. Therefore
they are not the same, no matter how many times you claim they are.

You seem to be under the impression that it is ok to destroy all lines
that are not horizontal or vertical. I think most people here believe
that to be a very bad solution.

I fully agree that a hinting (or "automatic snapping" as you call it)
addition to Cairo would be a VERY VERY good idea as it would stop
people like you from blindly turning antialiasing off and making the
display look like crap. Cairo should be doing this itself, in the
transformed coordinates. Although there are kludges to get around it,
I suspect most software using Cairo trying to avoid these artifacts
just assume the ctm is 1:1 with pixels, and it just seems weird to
transform to display coordinates, fiddle with them, then transform
back, just so cairo can transform them all over again.
Lawrence D'Oliveiro May 18, 2017, 9:47 p.m.
On Thu, 18 May 2017 10:47:16 -0700, Bill Spitzak wrote:

> A diagonal line draws with aliasing artifacts when
> antialiasing is off.

The question was not about diagonal lines.
Bill Spitzak May 18, 2017, 11:25 p.m.
On Thu, May 18, 2017 at 2:47 PM, Lawrence D'Oliveiro
<ldo@geek-central.gen.nz> wrote:
> On Thu, 18 May 2017 10:47:16 -0700, Bill Spitzak wrote:
>
>> A diagonal line draws with aliasing artifacts when
>> antialiasing is off.
>
> The question was not about diagonal lines.

You said "turning off antialiasing is the same as hinting".

Which implies it is the same for ALL drawing, since you gave no
restrictions on what could be drawn.

All drawing includes diagonal lines. Sorry.

> --
> cairo mailing list
> cairo@cairographics.org
> https://lists.cairographics.org/mailman/listinfo/cairo
Ori Bernstein May 19, 2017, 2:53 a.m.
On Fri, 19 May 2017 09:47:02 +1200, Lawrence D'Oliveiro <ldo@geek-central.gen.nz> wrote:

> On Thu, 18 May 2017 10:47:16 -0700, Bill Spitzak wrote:
> 
> > A diagonal line draws with aliasing artifacts when
> > antialiasing is off.
> 
> The question was not about diagonal lines.

Perhaps another question should be added, if you want to go down this route.

	"I turned off antialiasing, but now the sloped lines, the curves on my
	rectangles, and anything else that doesn't have vertical or horizontal edges
	are jagged. What do I do?"

Of course, the original answer removes the need for this question, since it
handles that case as well.
Lawrence D'Oliveiro May 19, 2017, 5:40 a.m.
On Thu, 18 May 2017 19:53:34 -0700, Ori Bernstein wrote:

> Of course, the original answer removes the need for this question,
> since it handles that case as well.

My answer is indeed careful to address that point.
me@beroal.in.ua May 19, 2017, 9:25 a.m.
Hi. Your patch deletes the existing answer that contains an explanation 
and alternative (IMHO, better) solutions. I am against this.

Automatic hinting is not the same as antialiasing. Automatic hinting 
adds .5 pixels if the line width is odd, 0 pixels if the line width is 
even. The effect of antialiasing is not defined in case when the line 
width is odd. The actual line width may be 1 pixel more or 1 pixel less. 
Therefore, automatic hinting should be a separate option with defined 
behavior.
Lawrence D'Oliveiro May 19, 2017, 10:08 a.m.
On Fri, 19 May 2017 12:25:08 +0300, me@beroal.in.ua wrote:

> Automatic hinting is not the same as antialiasing.

Why exactly is this relevant?
Bill Spitzak May 19, 2017, 5:40 p.m.
On Fri, May 19, 2017 at 3:08 AM, Lawrence D'Oliveiro
<ldo@geek-central.gen.nz> wrote:
> On Fri, 19 May 2017 12:25:08 +0300, me@beroal.in.ua wrote:
>
>> Automatic hinting is not the same as antialiasing.

Obviously not. Not sure what the argument is.

Though I agree with some of the patch shown above (in particular
remove all the stuff about "some people don't like pixels described as
squares" which is rather opinionated, and has NOTHING to do with
whether the integers are at the pixel centers or 1/2 way between them.
The integers are 1/2 way between the pixel centers in Cairo in the
default ctm, and imagining different shapes for pixels does not and
cannot change this).

The problem with "turn off antialiasing" is that it will fail for any
lines that are not horizontal or vertical. And just saying "turn it
on/off depending on whether you are drawing horizontal/vertical lines"
is not a solution though it is implied. That will not allow the
diagonal lines to cleanly join onto the horizontal and vertical lines,
as they are in effect shifted by .5 pixel.

I do agree that Cairo really needs some kind of hinting as this is a
huge impediment for novice programmers to get any kind of nice
graphics out of it, and pretty much makes Cairo's support of
transformation unusable if you do want to fix this. It also needs to
gamma correct the antialiasing as proper antialiasing can look far
better than what Cairo is producing now.