RSS/Atom feed Twitter
Site is read-only, email is disabled

Thin lines

This discussion is connected to the gimp-developer-list.gnome.org mailing list which is provided by the GIMP developers and not related to gimpusers.com.

This is a read-only list on gimpusers.com so this discussion thread is read-only, too.

4 of 4 messages available
Toggle history

Please log in to manage your subscriptions.

Thin lines Henning Makholm 07 Jun 03:33
  Thin lines Sven Neumann 07 Jun 14:07
Thin lines Henning Makholm 07 Jun 20:08
  Thin lines Sven Neumann 07 Jun 20:19
Henning Makholm
2002-06-07 03:33:21 UTC (almost 22 years ago)

Thin lines

Whereas,

1. I recently discovered the Gimp and decided that it's the greatest thing since sliced bread and just what I need ...

2. ... except that it cannot draw thin lines and curves that look nice. I'm not the first to discover this, see e.g. bug #69773,

3. Last August there was a thread about ways to fix the problem: http://lists.xcf.berkeley.edu/lists/gimp-developer/2001-August/005549.html,

4. That thread seemed to end up with a rough consensus that a solution that worked for thin lines would be a Good Thing, and that it might be acceptable to change the basic line-drawing engine to be more DDA/bresenham-ish to make that work,

5. However, nothing concrete seems to have come of that. At least the word "bresenham" has not been uttered on the list ever since, and thin lines are still ugly in 1.3.7 (but I may be wrong. If so, please tell me), and

6. I think I have a workable idea of what needs to be done (see below), and after having hunted down a rounding bug related to line drawing, I even feel competent to make some rough guesses about where in the source code it should be done,

I hereby offer my programming skills to the task.

[That being, if you want them. I'm not quite sure where on the cathedral-bazaar scale the Gimp core lies, but the guy I met on comp.graphics.app.gimp (hi, Dave!) seemed rather eager to send me here so I don't expect to have my head bitten off.]

In greater detail: I understand that the Gimp draws lines by stamping the brush image at equidistant places along the line. The problem with thin lines is that those equidistant places are computed in floating point without any particular attention to pixel boundaries. This gives ugly lines when the brush is only one or a few pixels across, no matter (but in different ways) whether the pixel stamps are anti-aliased or not.

As long as we're only drawing straight lines with an 1x1 brush and spacing 1.0, the solution is clear: just adjust the positions of the brush centers along the abstract line such that they all have integral-plus-one-half x coordinates if the slope is horizontalish, and integral-plus-one-half y coordinates if the slope is verticalish.

The challenge is to let this scale to (a) larger spacing, bigger brushes, and (b) stroking of cubic spline paths.

Regarding (b), the "obvious" idea is to divide the spline into segments according to the octant of tangent. However, it becomes difficult to find a simple way to make two segments with different orientations always meet seamlessly in case of a 1x1 brush with antialiasing. Instead I propose another solution: compute all points along the spline where *either* the x coordinate *or* the y coordinate has fractional part equal to 1/2 - then select a suitable subset of these points to draw, according to the brush spacing (see below).

These "extra" brush positions will be invisible if all points are painted with a 1x1 brush - if the paint from neighbouring brush positions is combined by "maximum" rather than "addition", the "extra" brush stamps will always have lower intensity than their "ordinary" neighbours combined. This holds for the pencil as well as for the brush, as long as the spline is locally approximated by a line. But the admission of "extra" positions means that there will be no discontinuity when the spline's tangent passes from one octant to another.

Brush spacing now becomes a matter of choosing among the candidate points (defined as those where one or both coordinates is n+1/2) such that the (euclidean) distance between successive actiual painting operations is at least .

So, do you think this is worth wasting time on? If so, what is the protocol for "outsider"s contributing to the Gimp - does one just post patches to this list, or must I find a sponsor with commit priveleges, or what?

I also have a design for a "stroke selection" operation that creates nice thin AA outlines if the selection was made with AA tools, but that would not be as easy to integrate with the Gimp's user interface paradigm.

Sven Neumann
2002-06-07 14:07:03 UTC (almost 22 years ago)

Thin lines

Hi,

Henning Makholm writes:

I hereby offer my programming skills to the task.

great. You have the job.

In greater detail: I understand that the Gimp draws lines by stamping the brush image at equidistant places along the line. The problem with thin lines is that those equidistant places are computed in floating point without any particular attention to pixel boundaries. This gives ugly lines when the brush is only one or a few pixels across, no matter (but in different ways) whether the pixel stamps are anti-aliased or not.

right.

As long as we're only drawing straight lines with an 1x1 brush and spacing 1.0, the solution is clear: just adjust the positions of the brush centers along the abstract line such that they all have integral-plus-one-half x coordinates if the slope is horizontalish, and integral-plus-one-half y coordinates if the slope is verticalish.

The challenge is to let this scale to (a) larger spacing, bigger brushes, and (b) stroking of cubic spline paths.

Regarding (b), the "obvious" idea is to divide the spline into segments according to the octant of tangent. However, it becomes difficult to find a simple way to make two segments with different orientations always meet seamlessly in case of a 1x1 brush with antialiasing. Instead I propose another solution: compute all points along the spline where *either* the x coordinate *or* the y coordinate has fractional part equal to 1/2 - then select a suitable subset of these points to draw, according to the brush spacing (see below).

These "extra" brush positions will be invisible if all points are painted with a 1x1 brush - if the paint from neighbouring brush positions is combined by "maximum" rather than "addition", the "extra" brush stamps will always have lower intensity than their "ordinary" neighbours combined. This holds for the pencil as well as for the brush, as long as the spline is locally approximated by a line. But the admission of "extra" positions means that there will be no discontinuity when the spline's tangent passes from one octant to another.

Brush spacing now becomes a matter of choosing among the candidate points (defined as those where one or both coordinates is n+1/2) such that the (euclidean) distance between successive actiual painting operations is at least .

So, do you think this is worth wasting time on? If so, what is the protocol for "outsider"s contributing to the Gimp - does one just post patches to this list, or must I find a sponsor with commit priveleges, or what?

line drawing is definitely worth to improve. We would like to see this development take place in the 1.3 tree. The prefered protocol for contributions is to use Bugzilla (http://bugzilla.gnome.org/). You open a bug-report (marked as enhancement probably) and attach your patches to it. This way the patch isn't lost even if none of the core developers finds the time to apply it immidiately. Bugzilla also allows us to comment on the patches and keeps everything together in one place. Patches should preferably be generated against the CVS tree but the latest tarball should also do fine. You can also get CVS write access but we prefer to see a couple of patches first.

Salut, Sven

Henning Makholm
2002-06-07 20:08:18 UTC (almost 22 years ago)

Thin lines

Scripsit Sven Neumann

one place. Patches should preferably be generated against the CVS tree

Hm, seems the bleeding-edge cvs source doesn't compile right now. After lots of trouble because I have automake 1.6 instead of automake 1.4 (separate bug report filed) I ended up at

... -g -O2 -Wall -c gimpunits.c
gimpunits.c: In function `gimp_unitrc_load': gimpunits.c:100: too few arguments to function `gimp_scanner_new' make[3]: *** [gimpunits.o] Error 1
make[3]: Leaving directory `/scratch/foogimp/gimp-1.3.cvs/app/core' ...

but the latest tarball should also do fine.

I'll work from there, and see if the cvs tree happens to be consistent when I'm done.

Sven Neumann
2002-06-07 20:19:10 UTC (almost 22 years ago)

Thin lines

Hi,

Henning Makholm writes:

Hm, seems the bleeding-edge cvs source doesn't compile right now. After lots of trouble because I have automake 1.6 instead of automake 1.4 (separate bug report filed) I ended up at

... -g -O2 -Wall -c gimpunits.c
gimpunits.c: In function `gimp_unitrc_load': gimpunits.c:100: too few arguments to function `gimp_scanner_new' make[3]: *** [gimpunits.o] Error 1
make[3]: Leaving directory `/scratch/foogimp/gimp-1.3.cvs/app/core' ...

that's the anoncvs problem reported here earlier. The tree you got from anoncvs is inconsistent. This sucks :-(

Salut, Sven