[cairo] line width questions

Ian Britten britten at caris.com
Mon Aug 18 11:08:12 PDT 2008

Simon Budig wrote:

>>>> First, is there a quick/easy way to draw a line "as thin as possible"?
>>> Well, how would you define "as thin as possible" when lines with a
>>> width smaller than 1 device pixel are allowed and get rendered nicely?
>> Seriously though, as I originally described, most graphics systems
>> have an idiom to draw a line as thin as they possibly can, while still
>> actually drawing the line.  This is often done by setting the the
>> thickness to zero (eg: PS behaves this way, and with X, a thickness
>> of zero draws a 1-pixel wide line).
> I know and it perfectly makes sense if you draw non-antialiased lines
> where a linewidth of zero indicates a straight-bresenham-style line.
> My point is, that in an antialiased rendering context this definition no
> longer makes sense.

At least for now, I'd like to keep this focused on PDF (and maybe the
other vector output formats: PS, SVG, etc), where the output is most
definitely not anti-aliased.
[ Or, I'm assuming they aren't.  If Cairo is doing some sort of AA for
PDF, etc, then that would open up a whole different discussion ]

> It would be desastrous for your API, if you e.g.
> specify a line width of 0.005 px (which might get rendered nicely
> although basically invisible), then you do some transformations on top
> of your code and due to rounding errors you end up with a linewidth of
> zero and suddenly you get a fat 1px line in your output, which is not
> what you expect from scaling down your drawing code with a
> transformation (this argument might be bogus, since the linewidth in
> the drawing context probably does not get affected by transformations
> directly, but you get the idea).

I agree in this case you might get inconsistent results.
For my case at least, this case doesn't normally happen though, since
we'd be re-rendering/regenerating the resulting PDF rather than
just scaling it up/down.

> Also, if you think in the context of a PDF - if a zero linewidth
> specifies the "thinnest possible" linewidth and you cannot possibly know
> what to write to the PDF, since you have no idea about the actual output
> device. A line might show up nicely on the imagesetter in your print
> shop, but a same width line might just be invisible on your offices'
> laser printer.

I think it'd be worthwhile for this discussion to separate
high-quality from low-quality output.
[ Note though that in my rendering 'canvas', I don't know what I might
be rendering, and have to handle both cases ]

For high-quality output, I agree that the lineweight of all the lines
should be (And usually are) specified.  Furthermore, printing any data
that isn't fully-qualified may/will result in indeterminate results.
However, that is a data/application problem.  There's nothing the
rendering engine (me, cairo, etc) can do to correctly account for the
lack of any lineweights.

OTOH, for low-quality output, it's a different matter.  The user may
simply be trying to do a 'preview' type of output, or might not have
prepped their data yet, and are just dumping it to any nearby printer.
In these cases, the data may not be critical (Or even 'pretty'), and
the possibility of different thicknesses from different devices may
not be a concern to the user.

> Just specifying the actual width - which in certain conditions might add
> the "complexity" of doing an additional cairo_device_to_user_distance ()
> to get real 1px lines on your image surface - is way easier than having
> a magical guessing machine in cairo that does the wrong thing in a
> critical situation.

I might be prepared to do this (And I even tried), but it's unclear
how small of a number to use.  As I stated, 1px (point) is an
unacceptably thick equivalent for a "As thin as possible" line,
Thus, I'm trying to find out how small to go: 0.5? 0.01? 0.000001?
At some point (Zero) Cairo simply stops drawing the line (Rather than
letting the device handle it), and I don't know what epsilon or
precision Cairo is working with, to know how close to zero I can

>> Since a thickness of zero seems to draw no line with Cairo, how
>> am I to know what the thinnest possible line can be (Esp. when
>> accounting for different surface types!).
> If you don't know, how should cairo know? As written above, the
> effective resolution of a printer is not known at the time of the PDF
> output.

So you're saying that Cairo is going to prevent me from using this
valid PS/PDF feature? Namely, using a lineweight of zero and
automatically getting a "as thin as possible" line?

[ Ya, sorry - That's a pretty obvious troll...  :(  I just seem to
be spending an awful lot of time getting this one small line
attribute working correctly... ]

>> My main problem is that "1 device unit" is unacceptably thick in PDF
>> (Can anyone tell me what the PDF device units are?  Points maybe?).
>> So how small can I specify the thickness? 0.5? 0.01? 0.000000001?
>> And how am I supposed to know this, short of experimenting?
> AFAIK the device units for postscript/pdf are postscript points, i.e.
> 1/72 inches or 0.353mm.

I just printed some (PS) lines with a lineweight of zero.  Admittedly,
it was only to a 1200dpi laser printer, and my optical measuring tools
aren't super-advanced, but the resulting lines are around 0.03mm
thick - Far smaller than one point.

Suggestions about how to match this result via the Cairo API would
be welcome!

More information about the cairo mailing list