How to draw an "X" in cairo

78 views
Skip to first unread message

Greg Ercolano

unread,
Dec 31, 2021, 2:54:35 PM12/31/21
to fltkg...@googlegroups.com
Trying to just draw a simple "X" to all four corners of the Fl_Cairo_Window.
Having trouble getting this working.

My understanding is the default coordinate space of cairo is:

    (0.0, 0.0) = top/left
    (1.0, 1.0) = bottom/right

..and to use FLTK's coordinate space, you'd use cairo_scale(cr, w(), h())
to convert to the window's integer coordinate space.

Here's what I have (it doesn't work - weird behavior).
Am I missing something?


#include <FL/Fl.H>
#include <FL/Fl_Cairo_Window.H>

static void my_cairo_draw_cb(Fl_Cairo_Window *window, cairo_t *cr) {
    const double xmax = (window->w() - 1);
    const double ymax = (window->h() - 1);

    // Draw green "X"
    //     Draw an X to four corners of resizable window.
    //
    cairo_scale(cr, window->w(), window->h());                    // use FLTK's coordinate space 0,0,w(),h()
    cairo_set_line_width(cr, 0.01);                               // line width for drawing
    cairo_set_source_rgb(cr, 0.0, 1.0, 0.0);                      // green
    cairo_move_to(cr, 0.0, 0.0);  cairo_line_to(cr, xmax, ymax);  // draw diagonal "\" in fltk coord space
    cairo_move_to(cr, 0.0, ymax); cairo_line_to(cr, xmax, 0.0);   // draw diagonal "/" in fltk coord space
    cairo_stroke(cr);                                             // stroke the lines
}

int main(int argc, char **argv) {
  Fl_Cairo_Window window(300, 300, "Cairo Draw 'X'");
  window.color(FL_BLACK);
  window.resizable(&window);
  window.set_draw_cb(my_cairo_draw_cb);
  window.show(argc, argv);
  return Fl::run();
}


    

Albrecht Schlosser

unread,
Dec 31, 2021, 5:21:11 PM12/31/21
to fltkg...@googlegroups.com
On 12/31/21 8:54 PM Greg Ercolano wrote:
Trying to just draw a simple "X" to all four corners of the Fl_Cairo_Window.
Having trouble getting this working.

My understanding is the default coordinate space of cairo is:

    (0.0, 0.0) = top/left
    (1.0, 1.0) = bottom/right

..and to use FLTK's coordinate space, you'd use cairo_scale(cr, w(), h())
to convert to the window's integer coordinate space.

Here's what I have (it doesn't work - weird behavior).
Am I missing something?


I don't know how the coordinate systems are (or should be) translated, but if I change only your two drawing code lines to

cairo_move_to(cr, 0.0, 0.0); cairo_line_to(cr, 1.0, 1.0); // draw diagonal "\"
cairo_move_to(cr, 0.0, 1.0); cairo_line_to(cr, 1.0, 0.0); // draw diagonal "/"

the "green X" works for me.

If you look at test/cairo_test.cxx you can see that all the "buttons" are drawn inside the (0.0 ... 1.0) coordinate space, using the same cairo_scale instruction as you do.


Greg Ercolano

unread,
Dec 31, 2021, 5:59:18 PM12/31/21
to fltkg...@googlegroups.com
   Thanks, I get that too.

   Though still not sure how to achieve FLTK drawing coordinates.

   One would think if setting the scale to (w,h) gets you a (0,0,1,1) coord system,
   then a scale of (1.0/w, 1.0/h) would achieve a (0,0,w,h) coord system,
   but that doesn't seem to work. Or at least I'm not seeing anything.

   Maybe the scale is affecting the line width coordinate space, but doing
   the above and setting the line width to 1.0 doesn't work.. hmm.

   Anyway, that's what I'm struggling with.

Greg Ercolano

unread,
Dec 31, 2021, 6:20:05 PM12/31/21
to fltkg...@googlegroups.com


On 12/31/21 2:59 PM, Greg Ercolano wrote:

On 12/31/21 2:21 PM, Albrecht Schlosser wrote:


I don't know how the coordinate systems are (or should be) translated, but if I change only your two drawing code lines to

cairo_move_to(cr, 0.0, 0.0); cairo_line_to(cr, 1.0, 1.0); // draw diagonal "\"
cairo_move_to(cr, 0.0, 1.0); cairo_line_to(cr, 1.0, 0.0); // draw diagonal "/"

the "green X" works for me.
   Thanks, I get that too.


   Though still not sure how to achieve FLTK drawing coordinates.

    So the solution is just leave the scale alone and use 1.0 for line width.
    The default *is* FLTK space, not normalized cairo space, lol.
    Guess I was thinking too hard about it.

    Apparently scale affects the line width too, so the tiny line widths
    in the cairo examples I was working with were for normalized space
    and weren't showing up because it was too thin, making me think I was
    in the wrong coordinate space.

    So anyway, this works:



// Cairo rendering cb called during Fl_Cairo_Window::draw()
static void my_cairo_draw_cb(Fl_Cairo_Window *window, cairo_t *cr) {
    const double xmax = (window->w() - 1);
    const double ymax = (window->h() - 1);

    // Draw green "X"
    //     Draws an X to four corners of resizable window.
    //
    cairo_set_antialias(cr, CAIRO_ANTIALIAS_BEST);
    cairo_set_line_width(cr, 1.00);                               // line width for drawing XXX what coord space is this?!
    cairo_set_source_rgb(cr, 0.0, 1.0, 0.0);                      // green
    cairo_move_to(cr, 0.0, 0.0);  cairo_line_to(cr, xmax, ymax);  // draw diagonal "\"
    cairo_move_to(cr, 0.0, ymax); cairo_line_to(cr, xmax, 0.0);   // draw diagonal "/"
    cairo_stroke(cr);                                             // stroke the lines
}

int main(int argc, char **argv) {
  Fl_Cairo_Window window(300, 300, "Cairo Draw 'X'");
  window.color(FL_BLACK);
  window.resizable(&window);
  window.set_draw_cb(my_cairo_draw_cb);
  window.show(argc, argv);
  return Fl::run();
}

Albrecht Schlosser

unread,
Dec 31, 2021, 6:26:52 PM12/31/21
to fltkg...@googlegroups.com
On 1/1/22 12:20 AM Greg Ercolano wrote:
On 12/31/21 2:59 PM, Greg Ercolano wrote:

On 12/31/21 2:21 PM, Albrecht Schlosser wrote:


I don't know how the coordinate systems are (or should be) translated, but if I change only your two drawing code lines to

cairo_move_to(cr, 0.0, 0.0); cairo_line_to(cr, 1.0, 1.0); // draw diagonal "\"
cairo_move_to(cr, 0.0, 1.0); cairo_line_to(cr, 1.0, 0.0); // draw diagonal "/"

the "green X" works for me.
   Thanks, I get that too.

   Though still not sure how to achieve FLTK drawing coordinates.

    So the solution is just leave the scale alone and use 1.0 for line width.
    The default *is* FLTK space, not normalized cairo space, lol.

Yep, found that too.

Greetings from 2022 (Jan 1, 0:25 am) back to 2021 ;-)

Happy new year to all !

Greg Ercolano

unread,
Dec 31, 2021, 7:16:11 PM12/31/21
to fltkg...@googlegroups.com

On 12/31/21 3:26 PM, Albrecht Schlosser wrote:

Yep, found that too.

    I'll suggest an examples/cairo-draw-x.cxx on fltk.coredev.

    To do so would mean some kind of conditional in the examples/Makefile* and examples/CMakeLists.txt
    to only build the example if cairo is enabled.

    I have something that works, but I'll probably open a separate thread on fltk.coredev
    about that.


Greetings from 2022 (Jan 1, 0:25 am) back to 2021 ;-)
Happy new year to all !

    Oh wow, so is 2022 is any better, or should I stick with 2021 and hold off on "upgrading"? :D

Albrecht Schlosser

unread,
Dec 31, 2021, 7:41:35 PM12/31/21
to fltkg...@googlegroups.com
On 1/1/22 1:16 AM Greg Ercolano wrote:
>
> On 12/31/21 3:26 PM, Albrecht Schlosser wrote:
>
>> Yep, found that too.
>
>     I'll suggest an examples/cairo-draw-x.cxx on fltk.coredev.

OK, +1

>     To do so would mean some kind of conditional in the
> examples/Makefile* and examples/CMakeLists.txt
>     to only build the example if cairo is enabled.

In the latest 1.4 commits we have <FL/fl_config.h> which is
automatically included and defines FLTK_HAVE_CAIRO if cairo is
available. test/cairo_test.cxx shows how to use it and how to display an
alternate message if cairo is not available. I suggest to do it like this.

I'm going to remove libfltk_cairo soon, so linking with that should not
be a problem (fltk-config could help anyway).

Linking with libcairo (or not) would be another issue I'll attack at
least with CMake. Makefiles could either use ../makeinclude or a
combination of fltk-config options. But that's only thoughts so far...

>     I have something that works, but I'll probably open a separate
> thread on fltk.coredev
>     about that.

OK.

>> Greetings from 2022 (Jan 1, 0:25 am) back to 2021 ;-)
>> Happy new year to all !
>
>     Oh wow, so is 2022 is any better, or should I stick with 2021 and
> hold off on "upgrading"? :D

I hope it'll be better (less COVID issues, hopefully), but I can't
downgrade anyway. Looking forward to its new features... ;-)

Albrecht Schlosser

unread,
Dec 31, 2021, 7:54:03 PM12/31/21
to fltkg...@googlegroups.com
On 1/1/22 1:41 AM Albrecht Schlosser wrote:
> In the latest 1.4 commits we have <FL/fl_config.h> which is
> automatically included and defines FLTK_HAVE_CAIRO if cairo is available.

To be precise, this should read: ... defines FLTK_HAVE_CAIRO if the FLTK
library has been configured and built with one of the Cairo options.

Greg Ercolano

unread,
Dec 31, 2021, 8:04:39 PM12/31/21
to fltkg...@googlegroups.com
    To do so would mean some kind of conditional in the examples/Makefile* and examples/CMakeLists.txt
    to only build the example if cairo is enabled.

In the latest 1.4 commits we have <FL/fl_config.h> which is automatically included and defines FLTK_HAVE_CAIRO [..]

    OK, so I'll investigate having it operate like test/cairo_test, so that that it builds unconditionally,
    but pops a dialog if cairo isn't enabled.

    Was hoping to avoid that in user example code (as a regular user wouldn't likely do that).

    Perhaps we should have some way to leverage fltk-config to interrogate config.h options
    so that even user's projects can check this stuff from their own Makefiles, e.g. to warn if
    FLTK was built without cairo when this was expected.


    Oh wow, so is 2022 is any better, or should I stick with 2021 and hold off on "upgrading"? :D 
I hope it'll be better (less COVID issues, hopefully), but I can't downgrade anyway. Looking forward to its new features...

    To paraphrase a comic someone posted on facebook, traditionally each New Year
    is like turning to a new page on life, full of optimisim and choices.
    But lately it's been like turning a page in a Stephen King horror novel, lol.
 

janezz55

unread,
Jan 11, 2022, 6:53:34 AM1/11/22
to fltk.general
Try to draw using the CairoWidget, in case you don't have cairo support compiled into FLTK:

Reply all
Reply to author
Forward
0 new messages