Sven wrote:
> If you had a look at the Ink tool you would have noticed that all
> paint tools are extraordinarily simple. I agree that other tools
> (those that draw to the display) are a lot more complex but all paint
> tools are identical except that they register different GimpPaintCore
> objects. So you don't even need to deal with tools at all (which is
> admittedly one of the most complex and least cleaned up parts of the
> Gimp code).
> All you need to do is to derive a new GimpPaintCore, either directly
> from GimpPaintCore or (in case you want to make use of brushes) from
> GimpBrushCore. This is all nicely abstracted in the app/paint folder
> and you basically don't need to worry about anything outside this
> directory. All you need to do is to implement a couple of methods.
> Just take an existing paint core as an example to copy from. 

Thank you.  This is already very helpful.  So in the spirit of
trying to figure things out for myself, let me try to figure out how
to make a tool register a different GimpPaintCore object.

Let's see -- nothing useful in tools/gimpinktool.c, which as you
say is very simple.  

So let's look at the code for the parent class, tools/gimppainttool.c.
Yes, here it is, line 230:

  paint_tool->core = g_object_new (tool->tool_info->paint_info->paint_type,

A bit daunting, but obviously what I need to do is set the paint_type.
So let's figure out where that is done.  Grepping for paint_type
in the tools directory gives nothing.  Grepping in the entire
code base gives about a dozen hits -- core/gimppaintinfo.c looks
most promising.

Okay, here it is, I think, line 145:

  paint_info->paint_type         = paint_type;

This is in the code for gimp_paint_info_new(), and paint_type
is one of the arguments to the function.  So the next step is to figure 
out where gimp_paint_info_new() is called.

Grepping gives only one hit, fortunately, in paint/gimp-paint.c,
line 109:

  paint_info = gimp_paint_info_new (gimp,

This occurs in the code for the function gimp_paint_register(), which
is declared static void, so it must be used in gimp-paint.c; let's
find it.

Okay, here it is, line 77:

  for (i = 0; i < G_N_ELEMENTS (register_funcs); i++)
      register_funcs[i] (gimp, gimp_paint_register);

This is kind of scary looking, but fortunately the array
register_funcs[] is created directly above, and I see that
one of its entries is gimp_ink_register.  I make a mental
note that I will at some point need to add my new tool to
this array, and then go on to look for gimp_ink_register().

Okay, here it is, in paint/gimpink.c:

gimp_ink_register (Gimp                      *gimp,
                   GimpPaintRegisterCallback  callback)
  (* callback) (gimp,

So finally I see that paint_type is GIMP_TYPE_INK, which is defined 
in paint/gimpink.h as: 

paint/gimpink.h:#define GIMP_TYPE_INK            (gimp_ink_get_type ())

And now I see that to create my new "spew" tool, I need to do the
following things:

1) In app/paint, "cp gimpink.c gimpspew.c" and then edit gimpspew.c
   to s/ink/spew/g  (don't take this literally).

2) Handle gimpink.h similarly.

3) in paint/gimp-paint.c, add an include for "gimpspew.h" and add
   gimp_spew_register to the register_funcs array.

4) in app/tools, copy gimpinktool.c and gimpinktool.h to gimpspewtool.c
   and gimpspewtool.h, then change "ink" to "spew" everywhere in the new

5) in app/tools, handle gimpinkoptions-gui.c and gimpinkoptions-gui.h the
   same way.

6) Add the new files to in the appropriate places.

7) In tools/gimp-tools.c, add "gimpspewtool.h" as an include, and add 
   gimp_spew_tool_register to the register_funcs array.  (I found 
   this by sheer luck.)

8) (The hard part)  Edit paint/gimpspew.[ch] and tools/gimpspewoptions-gui.c
   to give the desired new functionality.  The code from gimpink.c is
   rather complex and will no doubt give rise to more questions.

Does that look right?

No, I see that I haven't created an icon yet.  Fortunately I think I more
or less know how to do this:

9) Create stock-tool-spew-16.png and stock-tool-spew-22.png and place them
   in themes/Default/images/tools.  As I understand it, the appropriate
   line in libgimpwidgets/gimpstock.h will be autogenerated if in the 
   themes directory I then do "make -C clean; make".

How about that?

> That is void as well. A paint core is easy enough to be understood
> quite easily and since the code is in a single file, there is no risk
> at all that such problems could arise.

Well, I think I have demonstrated that I need to create or modify at
least 10 files to produce a new paint tool, and I have probably missed
something along the way.  But I will admit that the danger of code
collision does not seem all that large.

> There are a couple of paint tools in the core. I don't see how we
> could document this any better than by example. I've offered a helping
> hand for anyone who wants to work on new paint tools but I am
> certainly not going to waste the very few free time that I have by
> writing tutorials.

That's fine.  I think I have more or less assembled one in this email,
if it is correct.  Once I understand more clearly what needs to be done
to alter a file such as gimpink.c, I'll be happy to flesh it out.  (And
I hope that the first half of this email makes clear the difficulties
of working from examples in code where there is a lot of indirection.)

I'll respond to the other points separately; this is already very long.

  -- Bill

______________ ______________ ______________ ______________
Sent via the KillerWebMail system at

Gimp-developer mailing list

Reply via email to