2008-09-25 22:26:33 +04:00
|
|
|
//
|
2022-11-12 22:14:44 +03:00
|
|
|
// Special Cairo support for the Fast Light Tool Kit (FLTK).
|
2008-09-25 22:26:33 +04:00
|
|
|
//
|
2022-03-04 17:40:29 +03:00
|
|
|
// Copyright 1998-2022 by Bill Spitzak and others.
|
2008-09-25 22:26:33 +04:00
|
|
|
//
|
2011-07-19 08:49:30 +04:00
|
|
|
// This library is free software. Distribution and use rights are outlined in
|
|
|
|
// the file "COPYING" which should have been included with this file. If this
|
|
|
|
// file is missing or damaged, see the license at:
|
|
|
|
//
|
2020-07-01 19:03:10 +03:00
|
|
|
// https://www.fltk.org/COPYING.php
|
2008-09-25 22:26:33 +04:00
|
|
|
//
|
2020-07-01 19:03:10 +03:00
|
|
|
// Please see the following page on how to report bugs and issues:
|
2008-09-25 22:26:33 +04:00
|
|
|
//
|
2020-07-01 19:03:10 +03:00
|
|
|
// https://www.fltk.org/bugs.php
|
2008-09-25 22:26:33 +04:00
|
|
|
//
|
|
|
|
|
2022-11-12 22:14:44 +03:00
|
|
|
// This file implements the FLTK Cairo support (since 1.3.x):
|
|
|
|
//
|
|
|
|
// - ./configure --enable-cairo and/or --enable-cairoext
|
|
|
|
// - cmake -DOPTION_CAIRO and/or -DOPTION_CAIROEXT
|
|
|
|
//
|
|
|
|
// Preprocessor macro FLTK_HAVE_CAIRO is defined for both options.
|
|
|
|
// Preprocessor macro FLTK_HAVE_CAIRO_EXT is defined only for "cairoext"
|
|
|
|
|
|
|
|
#include <FL/Fl.H> // includes <FL/fl_config.h>
|
2008-09-25 22:26:33 +04:00
|
|
|
|
2011-01-06 13:24:58 +03:00
|
|
|
#ifdef FLTK_HAVE_CAIRO
|
2022-11-12 22:14:44 +03:00
|
|
|
|
2018-02-01 00:17:17 +03:00
|
|
|
#include <FL/platform.H>
|
2008-09-25 22:26:33 +04:00
|
|
|
#include <FL/Fl_Window.H>
|
|
|
|
|
2016-02-13 21:02:17 +03:00
|
|
|
// Cairo is currently supported for the following platforms:
|
2022-11-12 22:14:44 +03:00
|
|
|
// Windows, macOS (Apple Quartz), X11, Wayland
|
2016-02-13 21:02:17 +03:00
|
|
|
|
2022-11-12 22:14:44 +03:00
|
|
|
#if defined(_WIN32) // Windows
|
2016-02-13 21:02:17 +03:00
|
|
|
# include <cairo-win32.h>
|
2022-11-12 22:14:44 +03:00
|
|
|
#elif defined(__APPLE__) // macOS
|
2016-02-13 21:02:17 +03:00
|
|
|
# include <cairo-quartz.h>
|
2022-11-12 22:14:44 +03:00
|
|
|
#elif defined(FLTK_USE_WAYLAND) // Wayland or hybrid
|
2022-03-04 17:40:29 +03:00
|
|
|
# include "../src/drivers/Wayland/Fl_Wayland_Graphics_Driver.H"
|
|
|
|
# include "../src/drivers/Wayland/Fl_Wayland_Window_Driver.H"
|
2022-11-16 23:10:14 +03:00
|
|
|
# if defined(FLTK_USE_X11)
|
2022-11-15 11:02:03 +03:00
|
|
|
# include <cairo-xlib.h>
|
|
|
|
# else
|
|
|
|
static void *fl_gc = NULL;
|
|
|
|
# endif
|
2022-11-12 22:14:44 +03:00
|
|
|
#elif defined(FLTK_USE_X11) // X11
|
2022-03-15 08:42:06 +03:00
|
|
|
# include <cairo-xlib.h>
|
2016-02-13 21:02:17 +03:00
|
|
|
#else
|
|
|
|
# error Cairo is not supported on this platform.
|
|
|
|
#endif
|
|
|
|
|
2022-11-12 22:14:44 +03:00
|
|
|
// static initialization
|
Cairo increment 2: Finer cairo granularity, less deps, new fltk_cairo lib
+ added new USE_CAIRO config preprocessor def.
to differentiate from HAVE_CAIRO so that we can use the cairo lib
without forcing the full fltk lib to be linked against it.
In that case, cairo autolink context functionality which needs fltk lib
instrumentation is disabled.
+ added new --enable-cairoext, which correspond to previous --enable-cairo.
now, --enable-cairo only adds HAVE_CAIRO def. and keeps fltk lib
from referencing cairo.
In both cases (--enable-cairo & --enable-cairoext), a new fltk_cairo lib is
created. This lib, similarly to local versions of png,jpeg and zlib,
is not generated if cairo is not enabled.
+ added cairo to fltk-config : now new --use-cairo flag is available
+ modified all unix like makefiles to now generate minimum cairo deps and also
new libfltk_cairo lib.
+ added new cairo subdir to permit conditional fltk_cairo lib generation.
+ vc2005 project minimum update to compile without be broken, but still needs
to create a similar fltk_cairo independent lib. For now, it works as before
with a dedicated cairo env. similar to --enable-cairoext context in unix.
+ regression tested ok with cairo disabled on win32, mac osx, mingw.
git-svn-id: file:///fltk/svn/fltk/branches/branch-1.3@6462 ea41ed52-d2ee-0310-a9c1-e6b18d33e121
2008-10-19 05:42:35 +04:00
|
|
|
|
2022-11-12 22:14:44 +03:00
|
|
|
Fl_Cairo_State Fl::cairo_state_; ///< contains all necessary info for current Cairo context mapping
|
2008-09-25 22:26:33 +04:00
|
|
|
|
2022-11-12 22:14:44 +03:00
|
|
|
// Fl_Cairo_State class
|
Cairo increment 2: Finer cairo granularity, less deps, new fltk_cairo lib
+ added new USE_CAIRO config preprocessor def.
to differentiate from HAVE_CAIRO so that we can use the cairo lib
without forcing the full fltk lib to be linked against it.
In that case, cairo autolink context functionality which needs fltk lib
instrumentation is disabled.
+ added new --enable-cairoext, which correspond to previous --enable-cairo.
now, --enable-cairo only adds HAVE_CAIRO def. and keeps fltk lib
from referencing cairo.
In both cases (--enable-cairo & --enable-cairoext), a new fltk_cairo lib is
created. This lib, similarly to local versions of png,jpeg and zlib,
is not generated if cairo is not enabled.
+ added cairo to fltk-config : now new --use-cairo flag is available
+ modified all unix like makefiles to now generate minimum cairo deps and also
new libfltk_cairo lib.
+ added new cairo subdir to permit conditional fltk_cairo lib generation.
+ vc2005 project minimum update to compile without be broken, but still needs
to create a similar fltk_cairo independent lib. For now, it works as before
with a dedicated cairo env. similar to --enable-cairoext context in unix.
+ regression tested ok with cairo disabled on win32, mac osx, mingw.
git-svn-id: file:///fltk/svn/fltk/branches/branch-1.3@6462 ea41ed52-d2ee-0310-a9c1-e6b18d33e121
2008-10-19 05:42:35 +04:00
|
|
|
|
2022-11-12 22:14:44 +03:00
|
|
|
void Fl_Cairo_State::autolink(bool b) {
|
2021-12-19 00:42:30 +03:00
|
|
|
#ifdef FLTK_HAVE_CAIROEXT
|
Cairo increment 2: Finer cairo granularity, less deps, new fltk_cairo lib
+ added new USE_CAIRO config preprocessor def.
to differentiate from HAVE_CAIRO so that we can use the cairo lib
without forcing the full fltk lib to be linked against it.
In that case, cairo autolink context functionality which needs fltk lib
instrumentation is disabled.
+ added new --enable-cairoext, which correspond to previous --enable-cairo.
now, --enable-cairo only adds HAVE_CAIRO def. and keeps fltk lib
from referencing cairo.
In both cases (--enable-cairo & --enable-cairoext), a new fltk_cairo lib is
created. This lib, similarly to local versions of png,jpeg and zlib,
is not generated if cairo is not enabled.
+ added cairo to fltk-config : now new --use-cairo flag is available
+ modified all unix like makefiles to now generate minimum cairo deps and also
new libfltk_cairo lib.
+ added new cairo subdir to permit conditional fltk_cairo lib generation.
+ vc2005 project minimum update to compile without be broken, but still needs
to create a similar fltk_cairo independent lib. For now, it works as before
with a dedicated cairo env. similar to --enable-cairoext context in unix.
+ regression tested ok with cairo disabled on win32, mac osx, mingw.
git-svn-id: file:///fltk/svn/fltk/branches/branch-1.3@6462 ea41ed52-d2ee-0310-a9c1-e6b18d33e121
2008-10-19 05:42:35 +04:00
|
|
|
autolink_ = b;
|
|
|
|
#else
|
|
|
|
Fl::fatal("In Fl::autolink(bool) : Cairo autolink() feature is only "
|
2020-07-01 19:03:10 +03:00
|
|
|
"available with the enable-cairoext configure option, now quitting.");
|
Cairo increment 2: Finer cairo granularity, less deps, new fltk_cairo lib
+ added new USE_CAIRO config preprocessor def.
to differentiate from HAVE_CAIRO so that we can use the cairo lib
without forcing the full fltk lib to be linked against it.
In that case, cairo autolink context functionality which needs fltk lib
instrumentation is disabled.
+ added new --enable-cairoext, which correspond to previous --enable-cairo.
now, --enable-cairo only adds HAVE_CAIRO def. and keeps fltk lib
from referencing cairo.
In both cases (--enable-cairo & --enable-cairoext), a new fltk_cairo lib is
created. This lib, similarly to local versions of png,jpeg and zlib,
is not generated if cairo is not enabled.
+ added cairo to fltk-config : now new --use-cairo flag is available
+ modified all unix like makefiles to now generate minimum cairo deps and also
new libfltk_cairo lib.
+ added new cairo subdir to permit conditional fltk_cairo lib generation.
+ vc2005 project minimum update to compile without be broken, but still needs
to create a similar fltk_cairo independent lib. For now, it works as before
with a dedicated cairo env. similar to --enable-cairoext context in unix.
+ regression tested ok with cairo disabled on win32, mac osx, mingw.
git-svn-id: file:///fltk/svn/fltk/branches/branch-1.3@6462 ea41ed52-d2ee-0310-a9c1-e6b18d33e121
2008-10-19 05:42:35 +04:00
|
|
|
#endif
|
|
|
|
}
|
|
|
|
|
2020-07-01 19:03:10 +03:00
|
|
|
/**
|
2022-11-12 22:14:44 +03:00
|
|
|
Provides a corresponding Cairo context for window \a wi.
|
2022-12-30 21:14:36 +03:00
|
|
|
This is needed in a draw() FL_OVERRIDE if Fl::cairo_autolink_context()
|
2022-11-12 22:14:44 +03:00
|
|
|
returns false, which is the default.
|
|
|
|
The cairo_context() does not need to be freed as it is freed every time
|
|
|
|
a new Cairo context is created. When the program terminates,
|
|
|
|
a call to Fl::cairo_make_current(0) will destroy any residual context.
|
|
|
|
|
|
|
|
\note A new Cairo context is not always re-created when this method
|
2016-02-13 21:02:17 +03:00
|
|
|
is used. In particular, if the current graphical context and the current
|
2008-09-25 22:26:33 +04:00
|
|
|
window didn't change between two calls, the previous gc is internally kept,
|
|
|
|
thus optimizing the drawing performances.
|
2016-02-13 21:02:17 +03:00
|
|
|
Also, after this call, Fl::cairo_cc() is adequately updated with this
|
2022-11-12 22:14:44 +03:00
|
|
|
Cairo context.
|
|
|
|
|
|
|
|
\note Only available when configure has the --enable-cairo option
|
|
|
|
|
|
|
|
\return the valid cairo_t* Cairo context associated to this window.
|
2022-11-15 11:49:19 +03:00
|
|
|
\retval NULL if \a wi is NULL or maybe with GL windows under Wayland
|
2008-09-25 22:26:33 +04:00
|
|
|
*/
|
2022-11-12 22:14:44 +03:00
|
|
|
cairo_t *Fl::cairo_make_current(Fl_Window *wi) {
|
|
|
|
if (!wi)
|
|
|
|
return NULL;
|
|
|
|
cairo_t *cairo_ctxt;
|
|
|
|
|
2022-03-04 17:40:29 +03:00
|
|
|
#if defined(FLTK_USE_WAYLAND)
|
2022-03-15 08:42:06 +03:00
|
|
|
if (fl_wl_display()) { // true means using wayland backend
|
|
|
|
struct wld_window *xid = fl_wl_xid(wi);
|
2022-11-12 22:14:44 +03:00
|
|
|
if (!xid->buffer)
|
|
|
|
return NULL; // this may happen with GL windows
|
2022-03-15 08:42:06 +03:00
|
|
|
cairo_ctxt = xid->buffer->cairo_;
|
|
|
|
cairo_state_.cc(cairo_ctxt, false);
|
|
|
|
return cairo_ctxt;
|
|
|
|
}
|
|
|
|
#endif
|
2008-09-25 22:26:33 +04:00
|
|
|
|
2022-11-12 22:14:44 +03:00
|
|
|
if (fl_gc == 0) { // means remove current cc
|
|
|
|
Fl::cairo_cc(0); // destroy any previous cc
|
|
|
|
cairo_state_.window(0);
|
|
|
|
return 0;
|
|
|
|
}
|
|
|
|
|
|
|
|
// don't re-create a context if it's the same gc/window couple
|
|
|
|
if (fl_gc == Fl::cairo_state_.gc() && fl_xid(wi) == (Window)Fl::cairo_state_.window())
|
|
|
|
return Fl::cairo_cc();
|
2008-09-25 22:26:33 +04:00
|
|
|
|
2022-11-12 22:14:44 +03:00
|
|
|
cairo_state_.window((void *)fl_xid(wi));
|
|
|
|
|
|
|
|
// Scale the Cairo context appropriately. This is platform dependent
|
2008-09-25 22:26:33 +04:00
|
|
|
|
2020-02-09 09:52:20 +03:00
|
|
|
#ifndef __APPLE__
|
|
|
|
float scale = Fl::screen_scale(wi->screen_num()); // get the screen scaling factor
|
|
|
|
#endif
|
2021-12-19 00:42:30 +03:00
|
|
|
#if defined(FLTK_USE_X11)
|
2020-02-09 09:52:20 +03:00
|
|
|
cairo_ctxt = Fl::cairo_make_current(0, wi->w() * scale, wi->h() * scale);
|
2008-09-25 22:26:33 +04:00
|
|
|
#else
|
2020-02-09 09:52:20 +03:00
|
|
|
// on macOS, scaling is done before by Fl_Window::make_current(), on Windows, the size is not used
|
|
|
|
cairo_ctxt = Fl::cairo_make_current(fl_gc, wi->w(), wi->h());
|
|
|
|
#endif
|
|
|
|
#ifndef __APPLE__
|
|
|
|
cairo_scale(cairo_ctxt, scale, scale);
|
2008-09-25 22:26:33 +04:00
|
|
|
#endif
|
2020-02-09 09:52:20 +03:00
|
|
|
return cairo_ctxt;
|
2008-09-25 22:26:33 +04:00
|
|
|
}
|
|
|
|
|
2020-07-01 19:03:10 +03:00
|
|
|
/*
|
2008-09-25 22:26:33 +04:00
|
|
|
Creates transparently a cairo_surface_t object.
|
2018-02-09 17:39:42 +03:00
|
|
|
gc is an HDC context in Windows, a CGContext* in Quartz, and
|
2016-02-13 21:02:17 +03:00
|
|
|
a display on X11 (not used on this platform)
|
2008-09-25 22:26:33 +04:00
|
|
|
*/
|
2013-12-11 10:16:57 +04:00
|
|
|
|
2022-11-12 22:14:44 +03:00
|
|
|
static cairo_surface_t *cairo_create_surface(void *gc, int W, int H) {
|
|
|
|
#if defined(FLTK_USE_X11)
|
|
|
|
return cairo_xlib_surface_create(fl_display, fl_window, fl_visual->visual, W, H);
|
2022-11-15 11:02:03 +03:00
|
|
|
#elif defined(FLTK_USE_WAYLAND)
|
|
|
|
return NULL;
|
2022-11-12 22:14:44 +03:00
|
|
|
#elif defined(_WIN32)
|
|
|
|
return cairo_win32_surface_create((HDC)gc);
|
|
|
|
#elif defined(__APPLE__)
|
|
|
|
return cairo_quartz_surface_create_for_cg_context((CGContextRef)gc, W, H);
|
|
|
|
#else
|
|
|
|
#error Cairo is not supported on this platform.
|
|
|
|
#endif
|
2008-09-25 22:26:33 +04:00
|
|
|
}
|
|
|
|
|
2020-07-01 19:03:10 +03:00
|
|
|
/**
|
2022-11-12 22:14:44 +03:00
|
|
|
Creates a Cairo context from a \a gc only, gets its window size or
|
2016-02-13 21:02:17 +03:00
|
|
|
offscreen size if fl_window is null.
|
|
|
|
\note Only available when configure has the --enable-cairo option
|
2008-09-25 22:26:33 +04:00
|
|
|
*/
|
2022-11-12 22:14:44 +03:00
|
|
|
cairo_t *Fl::cairo_make_current(void *gc) {
|
|
|
|
int W = 0, H = 0;
|
2022-11-15 11:02:03 +03:00
|
|
|
#if defined(FLTK_USE_X11) || defined(FLTK_USE_WAYLAND)
|
2021-02-28 16:56:19 +03:00
|
|
|
// FIXME X11 get W,H
|
|
|
|
// gc will be the window handle here
|
|
|
|
// # warning FIXME get W,H for cairo_make_current(void*)
|
2022-04-08 17:22:22 +03:00
|
|
|
#elif defined(__APPLE__)
|
2022-11-12 22:14:44 +03:00
|
|
|
if (fl_window) {
|
|
|
|
W = Fl_Window::current()->w();
|
|
|
|
H = Fl_Window::current()->h();
|
|
|
|
} else {
|
|
|
|
W = CGBitmapContextGetWidth(fl_gc);
|
|
|
|
H = CGBitmapContextGetHeight(fl_gc);
|
|
|
|
}
|
2018-02-09 17:39:42 +03:00
|
|
|
#elif defined(_WIN32)
|
2022-11-12 22:14:44 +03:00
|
|
|
// we don't need any W,H for Windows
|
2008-09-25 22:26:33 +04:00
|
|
|
#else
|
2022-11-12 22:14:44 +03:00
|
|
|
#error Cairo is not supported on this platform.
|
2008-09-25 22:26:33 +04:00
|
|
|
#endif
|
2022-11-12 22:14:44 +03:00
|
|
|
if (!gc) {
|
|
|
|
Fl::cairo_cc(0);
|
|
|
|
cairo_state_.gc(0); // keep track for next time
|
|
|
|
return 0;
|
|
|
|
}
|
|
|
|
if (gc == Fl::cairo_state_.gc() && fl_window == (Window)Fl::cairo_state_.window() &&
|
|
|
|
cairo_state_.cc() != 0)
|
|
|
|
return Fl::cairo_cc();
|
|
|
|
cairo_state_.gc(fl_gc); // keep track for next time
|
|
|
|
cairo_surface_t *s = cairo_create_surface(gc, W, H);
|
|
|
|
cairo_t *c = cairo_create(s);
|
|
|
|
cairo_surface_destroy(s);
|
|
|
|
cairo_state_.cc(c);
|
|
|
|
return c;
|
2008-09-25 22:26:33 +04:00
|
|
|
}
|
|
|
|
|
2020-07-01 19:03:10 +03:00
|
|
|
/**
|
2022-11-12 22:14:44 +03:00
|
|
|
Creates a Cairo context from a \a gc and its size
|
|
|
|
|
|
|
|
\note Only available if FLTK has been configured with one of the Cairo options
|
2008-09-25 22:26:33 +04:00
|
|
|
*/
|
2022-11-12 22:14:44 +03:00
|
|
|
cairo_t *Fl::cairo_make_current(void *gc, int W, int H) {
|
|
|
|
if (gc == Fl::cairo_state_.gc() && fl_window == (Window)Fl::cairo_state_.window() &&
|
|
|
|
cairo_state_.cc() != 0) // no need to create a cc, just return that one
|
|
|
|
return cairo_state_.cc();
|
|
|
|
|
|
|
|
// we need to (re-)create a fresh cc ...
|
|
|
|
cairo_state_.gc(gc); // keep track for next time
|
|
|
|
cairo_surface_t *s = cairo_create_surface(gc, W, H);
|
2022-04-08 17:22:22 +03:00
|
|
|
#if defined(__APPLE__) && defined(FLTK_HAVE_CAIROEXT)
|
2022-11-12 22:14:44 +03:00
|
|
|
CGAffineTransform at = CGContextGetCTM((CGContextRef)gc);
|
|
|
|
CGContextSaveGState((CGContextRef)gc);
|
|
|
|
CGContextConcatCTM((CGContextRef)gc, CGAffineTransformInvert(at));
|
2022-04-08 17:22:22 +03:00
|
|
|
#endif
|
2022-11-12 22:14:44 +03:00
|
|
|
cairo_t *c = cairo_create(s);
|
2022-04-08 17:22:22 +03:00
|
|
|
#if defined(__APPLE__) && defined(FLTK_HAVE_CAIROEXT)
|
2022-11-12 22:14:44 +03:00
|
|
|
CGContextRestoreGState((CGContextRef)gc);
|
2022-04-08 17:22:22 +03:00
|
|
|
#endif
|
2022-11-12 22:14:44 +03:00
|
|
|
cairo_state_.cc(c); // and purge any previously owned context
|
|
|
|
cairo_surface_destroy(s);
|
|
|
|
return c;
|
2008-09-25 22:26:33 +04:00
|
|
|
}
|
2022-03-04 17:40:29 +03:00
|
|
|
|
2022-11-12 22:14:44 +03:00
|
|
|
// Silence compiler warning if none of the Cairo options has been configured
|
2022-03-04 17:40:29 +03:00
|
|
|
|
Cairo increment 2: Finer cairo granularity, less deps, new fltk_cairo lib
+ added new USE_CAIRO config preprocessor def.
to differentiate from HAVE_CAIRO so that we can use the cairo lib
without forcing the full fltk lib to be linked against it.
In that case, cairo autolink context functionality which needs fltk lib
instrumentation is disabled.
+ added new --enable-cairoext, which correspond to previous --enable-cairo.
now, --enable-cairo only adds HAVE_CAIRO def. and keeps fltk lib
from referencing cairo.
In both cases (--enable-cairo & --enable-cairoext), a new fltk_cairo lib is
created. This lib, similarly to local versions of png,jpeg and zlib,
is not generated if cairo is not enabled.
+ added cairo to fltk-config : now new --use-cairo flag is available
+ modified all unix like makefiles to now generate minimum cairo deps and also
new libfltk_cairo lib.
+ added new cairo subdir to permit conditional fltk_cairo lib generation.
+ vc2005 project minimum update to compile without be broken, but still needs
to create a similar fltk_cairo independent lib. For now, it works as before
with a dedicated cairo env. similar to --enable-cairoext context in unix.
+ regression tested ok with cairo disabled on win32, mac osx, mingw.
git-svn-id: file:///fltk/svn/fltk/branches/branch-1.3@6462 ea41ed52-d2ee-0310-a9c1-e6b18d33e121
2008-10-19 05:42:35 +04:00
|
|
|
#else
|
2022-11-12 22:14:44 +03:00
|
|
|
#warning xxx
|
|
|
|
FL_EXPORT int fltk_cairo_dummy() {
|
|
|
|
return 1;
|
|
|
|
}
|
|
|
|
|
2011-01-06 13:24:58 +03:00
|
|
|
#endif // FLTK_HAVE_CAIRO
|